Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(772)

Side by Side Diff: ash/app_list/app_list_shower_delegate.cc

Issue 1872033002: Revert of AppListController refactoring part 2: Ash's AppListShowerDelegate imlementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mus_chrome_delegates_app_list_2
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/app_list/app_list_shower_delegate.h"
6
7 #include "ash/app_list/app_list_view_delegate_factory.h"
8 #include "ash/ash_switches.h"
9 #include "ash/root_window_controller.h"
10 #include "ash/screen_util.h"
11 #include "ash/shelf/shelf.h"
12 #include "ash/shelf/shelf_layout_manager.h"
13 #include "ash/shell.h"
14 #include "ash/shell_delegate.h"
15 #include "ash/shell_window_ids.h"
16 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
17 #include "base/command_line.h"
18 #include "ui/app_list/app_list_constants.h"
19 #include "ui/app_list/app_list_switches.h"
20 #include "ui/app_list/shower/app_list_shower.h"
21 #include "ui/app_list/views/app_list_view.h"
22 #include "ui/aura/window.h"
23 #include "ui/events/event.h"
24 #include "ui/keyboard/keyboard_controller.h"
25 #include "ui/views/widget/widget.h"
26
27 namespace ash {
28 namespace {
29
30 // Offset in pixels to animation away/towards the shelf.
31 const int kAnimationOffset = 8;
32
33 // The minimal anchor position offset to make sure that the bubble is still on
34 // the screen with 8 pixels spacing on the left / right. This constant is a
35 // result of minimal bubble arrow sizes and offsets.
36 const int kMinimalAnchorPositionOffset = 57;
37
38 // The minimal margin (in pixels) around the app list when in centered mode.
39 const int kMinimalCenteredAppListMargin = 10;
40
41 // Gets arrow location based on shelf alignment.
42 views::BubbleBorder::Arrow GetBubbleArrow(aura::Window* window) {
43 DCHECK(Shell::HasInstance());
44 return Shelf::ForWindow(window)->SelectValueForShelfAlignment(
45 views::BubbleBorder::BOTTOM_CENTER, views::BubbleBorder::LEFT_CENTER,
46 views::BubbleBorder::RIGHT_CENTER);
47 }
48
49 // Using |button_bounds|, determine the anchor offset so that the bubble gets
50 // shown above the shelf (used for the alternate shelf theme).
51 gfx::Vector2d GetAnchorPositionOffsetToShelf(
52 const gfx::Rect& button_bounds, views::Widget* widget) {
53 DCHECK(Shell::HasInstance());
54 ShelfAlignment shelf_alignment = Shell::GetInstance()->GetShelfAlignment(
55 widget->GetNativeView()->GetRootWindow());
56 gfx::Point anchor(button_bounds.CenterPoint());
57 switch (shelf_alignment) {
58 case SHELF_ALIGNMENT_BOTTOM:
59 if (base::i18n::IsRTL()) {
60 int screen_width = widget->GetWorkAreaBoundsInScreen().width();
61 return gfx::Vector2d(
62 std::min(screen_width - kMinimalAnchorPositionOffset - anchor.x(),
63 0), 0);
64 }
65 return gfx::Vector2d(
66 std::max(kMinimalAnchorPositionOffset - anchor.x(), 0), 0);
67 case SHELF_ALIGNMENT_LEFT:
68 return gfx::Vector2d(
69 0, std::max(kMinimalAnchorPositionOffset - anchor.y(), 0));
70 case SHELF_ALIGNMENT_RIGHT:
71 return gfx::Vector2d(
72 0, std::max(kMinimalAnchorPositionOffset - anchor.y(), 0));
73 }
74 NOTREACHED();
75 return gfx::Vector2d();
76 }
77
78 // Gets the point at the center of the display that a particular view is on.
79 // This calculation excludes the virtual keyboard area. If the height of the
80 // display area is less than |minimum_height|, its bottom will be extended to
81 // that height (so that the app list never starts above the top of the screen).
82 gfx::Point GetCenterOfDisplayForView(const views::View* view,
83 int minimum_height) {
84 aura::Window* window = view->GetWidget()->GetNativeView();
85 gfx::Rect bounds = ScreenUtil::GetShelfDisplayBoundsInRoot(window);
86 bounds = ScreenUtil::ConvertRectToScreen(window->GetRootWindow(), bounds);
87
88 // If the virtual keyboard is active, subtract it from the display bounds, so
89 // that the app list is centered in the non-keyboard area of the display.
90 // (Note that work_area excludes the keyboard, but it doesn't get updated
91 // until after this function is called.)
92 keyboard::KeyboardController* keyboard_controller =
93 keyboard::KeyboardController::GetInstance();
94 if (keyboard_controller && keyboard_controller->keyboard_visible())
95 bounds.Subtract(keyboard_controller->current_keyboard_bounds());
96
97 // Apply the |minimum_height|.
98 if (bounds.height() < minimum_height)
99 bounds.set_height(minimum_height);
100
101 return bounds.CenterPoint();
102 }
103
104 // Gets the minimum height of the rectangle to center the app list in.
105 int GetMinimumBoundsHeightForAppList(const app_list::AppListView* app_list) {
106 return app_list->bounds().height() + 2 * kMinimalCenteredAppListMargin;
107 }
108
109 bool IsFullscreenAppListEnabled() {
110 #if defined(OS_CHROMEOS)
111 return base::CommandLine::ForCurrentProcess()->HasSwitch(
112 switches::kAshEnableFullscreenAppList) &&
113 app_list::switches::IsExperimentalAppListEnabled();
114 #else
115 return false;
116 #endif
117 }
118
119 } // namespace
120
121 ////////////////////////////////////////////////////////////////////////////////
122 // AppListShowerDelegate, public:
123
124 AppListShowerDelegate::AppListShowerDelegate(
125 app_list::AppListShower* shower,
126 AppListViewDelegateFactory* view_delegate_factory)
127 : shower_(shower), view_delegate_factory_(view_delegate_factory) {
128 Shell::GetInstance()->AddShellObserver(this);
129 }
130
131 AppListShowerDelegate::~AppListShowerDelegate() {
132 DCHECK(view_);
133 keyboard::KeyboardController* keyboard_controller =
134 keyboard::KeyboardController::GetInstance();
135 if (keyboard_controller)
136 keyboard_controller->RemoveObserver(this);
137 views::Widget* widget = view_->GetWidget();
138 Shell::GetInstance()->RemovePreTargetHandler(this);
139 Shelf::ForWindow(widget->GetNativeWindow())->RemoveIconObserver(this);
140 Shell::GetInstance()->RemoveShellObserver(this);
141 }
142
143 app_list::AppListViewDelegate* AppListShowerDelegate::GetViewDelegate() {
144 return view_delegate_factory_->GetDelegate();
145 }
146
147 void AppListShowerDelegate::Init(app_list::AppListView* view,
148 aura::Window* root_window,
149 int current_apps_page) {
150 // App list needs to know the new shelf layout in order to calculate its
151 // UI layout when AppListView visibility changes.
152 ash::Shell::GetPrimaryRootWindowController()
153 ->GetShelfLayoutManager()
154 ->UpdateAutoHideState();
155 view_ = view;
156 aura::Window* container = GetRootWindowController(root_window)
157 ->GetContainer(kShellWindowId_AppListContainer);
158 views::View* applist_button =
159 Shelf::ForWindow(container)->GetAppListButtonView();
160 is_centered_ = view->ShouldCenterWindow();
161 bool is_fullscreen = IsFullscreenAppListEnabled() &&
162 Shell::GetInstance()
163 ->maximize_mode_controller()
164 ->IsMaximizeModeWindowManagerEnabled();
165 if (is_fullscreen) {
166 view->InitAsFramelessWindow(
167 container, current_apps_page,
168 ScreenUtil::GetDisplayWorkAreaBoundsInParent(container));
169 } else if (is_centered_) {
170 // Note: We can't center the app list until we have its dimensions, so we
171 // init at (0, 0) and then reset its anchor point.
172 view->InitAsBubbleAtFixedLocation(container,
173 current_apps_page,
174 gfx::Point(),
175 views::BubbleBorder::FLOAT,
176 true /* border_accepts_events */);
177 // The experimental app list is centered over the display of the app list
178 // button that was pressed (if triggered via keyboard, this is the display
179 // with the currently focused window).
180 view->SetAnchorPoint(GetCenterOfDisplayForView(
181 applist_button, GetMinimumBoundsHeightForAppList(view)));
182 } else {
183 gfx::Rect applist_button_bounds = applist_button->GetBoundsInScreen();
184 // We need the location of the button within the local screen.
185 applist_button_bounds = ScreenUtil::ConvertRectFromScreen(
186 root_window,
187 applist_button_bounds);
188 view->InitAsBubbleAttachedToAnchor(
189 container,
190 current_apps_page,
191 Shelf::ForWindow(container)->GetAppListButtonView(),
192 GetAnchorPositionOffsetToShelf(
193 applist_button_bounds,
194 Shelf::ForWindow(container)->GetAppListButtonView()->GetWidget()),
195 GetBubbleArrow(container),
196 true /* border_accepts_events */);
197 view->SetArrowPaintType(views::BubbleBorder::PAINT_NONE);
198 }
199
200 keyboard::KeyboardController* keyboard_controller =
201 keyboard::KeyboardController::GetInstance();
202 if (keyboard_controller)
203 keyboard_controller->AddObserver(this);
204 Shell::GetInstance()->AddPreTargetHandler(this);
205 views::Widget* widget = view->GetWidget();
206 Shelf::ForWindow(widget->GetNativeWindow())->AddIconObserver(this);
207
208 // By setting us as DnD recipient, the app list knows that we can
209 // handle items.
210 view->SetDragAndDropHostOfCurrentAppList(
211 Shelf::ForWindow(root_window)->GetDragAndDropHostForAppList());
212 }
213
214 void AppListShowerDelegate::OnShown(aura::Window* root_window) {
215 is_visible_ = true;
216 // Update applist button status when app list visibility is changed.
217 Shelf::ForWindow(root_window)->GetAppListButtonView()->SchedulePaint();
218 }
219
220 void AppListShowerDelegate::OnDismissed() {
221 DCHECK(is_visible_);
222 DCHECK(view_);
223
224 is_visible_ = false;
225
226 // App list needs to know the new shelf layout in order to calculate its
227 // UI layout when AppListView visibility changes.
228 Shell::GetPrimaryRootWindowController()
229 ->GetShelfLayoutManager()
230 ->UpdateAutoHideState();
231
232 // Update applist button status when app list visibility is changed.
233 Shelf::ForWindow(view_->GetWidget()->GetNativeView())
234 ->GetAppListButtonView()
235 ->SchedulePaint();
236 }
237
238 void AppListShowerDelegate::UpdateBounds() {
239 if (!view_ || !is_visible_)
240 return;
241
242 view_->UpdateBounds();
243
244 if (is_centered_) {
245 view_->SetAnchorPoint(GetCenterOfDisplayForView(
246 view_, GetMinimumBoundsHeightForAppList(view_)));
247 }
248 }
249
250 gfx::Vector2d AppListShowerDelegate::GetVisibilityAnimationOffset(
251 aura::Window* root_window) {
252 DCHECK(Shell::HasInstance());
253
254 // App list needs to know the new shelf layout in order to calculate its
255 // UI layout when AppListView visibility changes.
256 Shell::GetPrimaryRootWindowController()
257 ->GetShelfLayoutManager()
258 ->UpdateAutoHideState();
259
260 ShelfAlignment shelf_alignment =
261 Shell::GetInstance()->GetShelfAlignment(root_window);
262 switch (shelf_alignment) {
263 case SHELF_ALIGNMENT_BOTTOM:
264 return gfx::Vector2d(0, kAnimationOffset);
265 case SHELF_ALIGNMENT_LEFT:
266 return gfx::Vector2d(-kAnimationOffset, 0);
267 case SHELF_ALIGNMENT_RIGHT:
268 return gfx::Vector2d(kAnimationOffset, 0);
269 }
270 NOTREACHED();
271 return gfx::Vector2d();
272 }
273
274 ////////////////////////////////////////////////////////////////////////////////
275 // AppListShowerDelegate, private:
276
277 void AppListShowerDelegate::ProcessLocatedEvent(ui::LocatedEvent* event) {
278 if (!view_ || !is_visible_)
279 return;
280
281 // If the event happened on a menu, then the event should not close the app
282 // list.
283 aura::Window* target = static_cast<aura::Window*>(event->target());
284 if (target) {
285 RootWindowController* root_controller =
286 GetRootWindowController(target->GetRootWindow());
287 if (root_controller) {
288 aura::Window* menu_container =
289 root_controller->GetContainer(kShellWindowId_MenuContainer);
290 if (menu_container->Contains(target))
291 return;
292 aura::Window* keyboard_container = root_controller->GetContainer(
293 kShellWindowId_VirtualKeyboardContainer);
294 if (keyboard_container->Contains(target))
295 return;
296 }
297 }
298
299 aura::Window* window = view_->GetWidget()->GetNativeView()->parent();
300 if (!window->Contains(target) &&
301 !app_list::switches::ShouldNotDismissOnBlur()) {
302 shower_->Dismiss();
303 }
304 }
305
306 ////////////////////////////////////////////////////////////////////////////////
307 // AppListShowerDelegate, aura::EventFilter implementation:
308
309 void AppListShowerDelegate::OnMouseEvent(ui::MouseEvent* event) {
310 if (event->type() == ui::ET_MOUSE_PRESSED)
311 ProcessLocatedEvent(event);
312 }
313
314 void AppListShowerDelegate::OnGestureEvent(ui::GestureEvent* event) {
315 if (event->type() == ui::ET_GESTURE_TAP_DOWN)
316 ProcessLocatedEvent(event);
317 }
318
319 ////////////////////////////////////////////////////////////////////////////////
320 // AppListShowerDelegate, keyboard::KeyboardControllerObserver implementation:
321
322 void AppListShowerDelegate::OnKeyboardBoundsChanging(
323 const gfx::Rect& new_bounds) {
324 UpdateBounds();
325 }
326
327 ////////////////////////////////////////////////////////////////////////////////
328 // AppListShowerDelegate, ShellObserver implementation:
329 void AppListShowerDelegate::OnShelfAlignmentChanged(aura::Window* root_window) {
330 if (view_)
331 view_->SetBubbleArrow(GetBubbleArrow(view_->GetWidget()->GetNativeView()));
332 }
333
334 void AppListShowerDelegate::OnMaximizeModeStarted() {
335 // The "fullscreen" app-list is initialized as in a different type of window,
336 // therefore we can't switch between the fullscreen status and the normal
337 // app-list bubble. App-list should be dismissed for the transition between
338 // maximize mode (touch-view mode) and non-maximize mode, otherwise the app
339 // list tries to behave as a bubble which leads to a crash. crbug.com/510062
340 if (IsFullscreenAppListEnabled() && is_visible_)
341 shower_->Dismiss();
342 }
343
344 void AppListShowerDelegate::OnMaximizeModeEnded() {
345 // See the comments of OnMaximizeModeStarted().
346 if (IsFullscreenAppListEnabled() && is_visible_)
347 shower_->Dismiss();
348 }
349
350 ////////////////////////////////////////////////////////////////////////////////
351 // AppListShowerDelegate, ShelfIconObserver implementation:
352
353 void AppListShowerDelegate::OnShelfIconPositionsChanged() {
354 UpdateBounds();
355 }
356
357 } // namespace ash
OLDNEW
« no previous file with comments | « ash/app_list/app_list_shower_delegate.h ('k') | ash/app_list/app_list_shower_delegate_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698