OLD | NEW |
| (Empty) |
1 // Copyright 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 #ifndef ASH_COMMON_SHELF_SHELF_LAYOUT_MANAGER_H_ | |
6 #define ASH_COMMON_SHELF_SHELF_LAYOUT_MANAGER_H_ | |
7 | |
8 #include <memory> | |
9 | |
10 #include "ash/ash_export.h" | |
11 #include "ash/common/session/session_state_observer.h" | |
12 #include "ash/common/shelf/wm_shelf.h" | |
13 #include "ash/common/shell_observer.h" | |
14 #include "ash/common/wm/dock/docked_window_layout_manager_observer.h" | |
15 #include "ash/common/wm/lock_state_observer.h" | |
16 #include "ash/common/wm/wm_snap_to_pixel_layout_manager.h" | |
17 #include "ash/common/wm/workspace/workspace_types.h" | |
18 #include "ash/common/wm_activation_observer.h" | |
19 #include "ash/public/cpp/shelf_types.h" | |
20 #include "base/macros.h" | |
21 #include "base/observer_list.h" | |
22 #include "base/timer/timer.h" | |
23 #include "ui/gfx/geometry/insets.h" | |
24 #include "ui/gfx/geometry/rect.h" | |
25 #include "ui/keyboard/keyboard_controller_observer.h" | |
26 | |
27 namespace ui { | |
28 class ImplicitAnimationObserver; | |
29 class MouseEvent; | |
30 } | |
31 | |
32 namespace ash { | |
33 | |
34 enum class AnimationChangeType; | |
35 class PanelLayoutManagerTest; | |
36 class ShelfLayoutManagerObserver; | |
37 class ShelfLayoutManagerTest; | |
38 class ShelfWidget; | |
39 class WmShelf; | |
40 | |
41 // ShelfLayoutManager is the layout manager responsible for the shelf and | |
42 // status widgets. The shelf is given the total available width and told the | |
43 // width of the status area. This allows the shelf to draw the background and | |
44 // layout to the status area. | |
45 // To respond to bounds changes in the status area StatusAreaLayoutManager works | |
46 // closely with ShelfLayoutManager. | |
47 // On mus, widget bounds management is handled by the window manager. | |
48 class ASH_EXPORT ShelfLayoutManager | |
49 : public ShellObserver, | |
50 public WmActivationObserver, | |
51 public DockedWindowLayoutManagerObserver, | |
52 public keyboard::KeyboardControllerObserver, | |
53 public LockStateObserver, | |
54 public wm::WmSnapToPixelLayoutManager, | |
55 public SessionStateObserver { | |
56 public: | |
57 ShelfLayoutManager(ShelfWidget* shelf_widget, WmShelf* wm_shelf); | |
58 ~ShelfLayoutManager() override; | |
59 | |
60 bool updating_bounds() const { return updating_bounds_; } | |
61 | |
62 // Clears internal data for shutdown process. | |
63 void PrepareForShutdown(); | |
64 | |
65 // Returns whether the shelf and its contents (shelf, status) are visible | |
66 // on the screen. | |
67 bool IsVisible() const; | |
68 | |
69 // Returns the ideal bounds of the shelf assuming it is visible. | |
70 gfx::Rect GetIdealBounds(); | |
71 | |
72 // Returns the preferred size of the shelf for the target visibility state. | |
73 gfx::Size GetPreferredSize(); | |
74 | |
75 // Returns the docked area bounds. | |
76 const gfx::Rect& dock_bounds() const { return dock_bounds_; } | |
77 | |
78 // Returns the bounds within the root window not occupied by the shelf nor the | |
79 // virtual keyboard. | |
80 const gfx::Rect& user_work_area_bounds() const { | |
81 return user_work_area_bounds_; | |
82 } | |
83 | |
84 // Stops any animations and sets the bounds of the shelf and status widgets. | |
85 void LayoutShelfAndUpdateBounds(bool change_work_area); | |
86 | |
87 // Stops any animations, sets the bounds of the shelf and status widgets, and | |
88 // changes the work area | |
89 void LayoutShelf(); | |
90 | |
91 // Returns shelf visibility state based on current value of auto hide | |
92 // behavior setting. | |
93 ShelfVisibilityState CalculateShelfVisibility(); | |
94 | |
95 // Updates the visibility state. | |
96 void UpdateVisibilityState(); | |
97 | |
98 // Invoked by the shelf when the auto-hide state may have changed. | |
99 void UpdateAutoHideState(); | |
100 | |
101 // Updates the auto-hide state for certain events. | |
102 // TODO(mash): Add similar event handling support for mash. | |
103 void UpdateAutoHideForMouseEvent(ui::MouseEvent* event, WmWindow* target); | |
104 void UpdateAutoHideForGestureEvent(ui::GestureEvent* event, WmWindow* target); | |
105 | |
106 ShelfVisibilityState visibility_state() const { | |
107 return state_.visibility_state; | |
108 } | |
109 ShelfAutoHideState auto_hide_state() const { return state_.auto_hide_state; } | |
110 | |
111 ShelfWidget* shelf_widget() { return shelf_widget_; } | |
112 | |
113 // Sets whether any windows overlap the shelf. If a window overlaps the shelf | |
114 // the shelf renders slightly differently. | |
115 void SetWindowOverlapsShelf(bool value); | |
116 bool window_overlaps_shelf() const { return window_overlaps_shelf_; } | |
117 | |
118 void AddObserver(ShelfLayoutManagerObserver* observer); | |
119 void RemoveObserver(ShelfLayoutManagerObserver* observer); | |
120 | |
121 // Processes a gesture event and updates the status of the shelf when | |
122 // appropriate. Returns true if the gesture has been handled and it should not | |
123 // be processed any further, false otherwise. | |
124 bool ProcessGestureEvent(const ui::GestureEvent& event); | |
125 | |
126 // Set an animation duration override for the show / hide animation of the | |
127 // shelf. Specifying 0 leads to use the default. | |
128 void SetAnimationDurationOverride(int duration_override_in_ms); | |
129 | |
130 // Overridden from wm::WmSnapToPixelLayoutManager: | |
131 void OnWindowResized() override; | |
132 void SetChildBounds(WmWindow* child, | |
133 const gfx::Rect& requested_bounds) override; | |
134 | |
135 // Overridden from ShellObserver: | |
136 void OnShelfAutoHideBehaviorChanged(WmWindow* root_window) override; | |
137 void OnPinnedStateChanged(WmWindow* pinned_window) override; | |
138 | |
139 // Overridden from WmActivationObserver: | |
140 void OnWindowActivated(WmWindow* gained_active, | |
141 WmWindow* lost_active) override; | |
142 | |
143 // Overridden from keyboard::KeyboardControllerObserver: | |
144 void OnKeyboardBoundsChanging(const gfx::Rect& new_bounds) override; | |
145 void OnKeyboardClosed() override; | |
146 | |
147 // Overridden from LockStateObserver: | |
148 void OnLockStateEvent(LockStateObserver::EventType event) override; | |
149 | |
150 // Overridden from SessionStateObserver: | |
151 void SessionStateChanged(session_manager::SessionState state) override; | |
152 | |
153 // TODO(harrym|oshima): These templates will be moved to a new Shelf class. | |
154 // A helper function for choosing values specific to a shelf alignment. | |
155 template <typename T> | |
156 T SelectValueForShelfAlignment(T bottom, T left, T right) const { | |
157 switch (wm_shelf_->GetAlignment()) { | |
158 case SHELF_ALIGNMENT_BOTTOM: | |
159 case SHELF_ALIGNMENT_BOTTOM_LOCKED: | |
160 return bottom; | |
161 case SHELF_ALIGNMENT_LEFT: | |
162 return left; | |
163 case SHELF_ALIGNMENT_RIGHT: | |
164 return right; | |
165 } | |
166 NOTREACHED(); | |
167 return right; | |
168 } | |
169 | |
170 template <typename T> | |
171 T PrimaryAxisValue(T horizontal, T vertical) const { | |
172 return wm_shelf_->IsHorizontalAlignment() ? horizontal : vertical; | |
173 } | |
174 | |
175 // Returns how the shelf background should be painted. | |
176 ShelfBackgroundType GetShelfBackgroundType() const; | |
177 | |
178 // Set the height of the ChromeVox panel, which takes away space from the | |
179 // available work area from the top of the screen. | |
180 void SetChromeVoxPanelHeight(int height); | |
181 | |
182 private: | |
183 class UpdateShelfObserver; | |
184 friend class PanelLayoutManagerTest; | |
185 friend class ShelfLayoutManagerTest; | |
186 friend class WebNotificationTrayTest; | |
187 | |
188 struct TargetBounds { | |
189 TargetBounds(); | |
190 ~TargetBounds(); | |
191 | |
192 float opacity; | |
193 float status_opacity; | |
194 gfx::Rect shelf_bounds_in_root; | |
195 gfx::Rect shelf_bounds_in_shelf; | |
196 gfx::Rect status_bounds_in_shelf; | |
197 gfx::Insets work_area_insets; | |
198 }; | |
199 | |
200 struct State { | |
201 State(); | |
202 | |
203 // Returns true when a secondary user is being added to an existing session. | |
204 bool IsAddingSecondaryUser() const; | |
205 | |
206 bool IsScreenLocked() const; | |
207 | |
208 // Returns true if the two states are considered equal. As | |
209 // |auto_hide_state| only matters if |visibility_state| is | |
210 // |SHELF_AUTO_HIDE|, Equals() ignores the |auto_hide_state| as | |
211 // appropriate. | |
212 bool Equals(const State& other) const; | |
213 | |
214 ShelfVisibilityState visibility_state; | |
215 ShelfAutoHideState auto_hide_state; | |
216 wm::WorkspaceWindowState window_state; | |
217 // True when the system is in the cancelable, pre-lock screen animation. | |
218 bool pre_lock_screen_animation_active; | |
219 session_manager::SessionState session_state; | |
220 }; | |
221 | |
222 // Sets the visibility of the shelf to |state|. | |
223 void SetState(ShelfVisibilityState visibility_state); | |
224 | |
225 // Updates the bounds and opacity of the shelf and status widgets. | |
226 // If |observer| is specified, it will be called back when the animations, if | |
227 // any, are complete. |change_work_area| specifies whether or not to update | |
228 // the work area of the screen. | |
229 void UpdateBoundsAndOpacity(const TargetBounds& target_bounds, | |
230 bool animate, | |
231 bool change_work_area, | |
232 ui::ImplicitAnimationObserver* observer); | |
233 | |
234 // Stops any animations and progresses them to the end. | |
235 void StopAnimating(); | |
236 | |
237 // Calculates the target bounds assuming visibility of |visible|. | |
238 void CalculateTargetBounds(const State& state, TargetBounds* target_bounds); | |
239 | |
240 // Updates the target bounds if a gesture-drag is in progress. This is only | |
241 // used by |CalculateTargetBounds()|. | |
242 void UpdateTargetBoundsForGesture(TargetBounds* target_bounds) const; | |
243 | |
244 // Updates the background of the shelf if it has changed. | |
245 void MaybeUpdateShelfBackground(AnimationChangeType change_type); | |
246 | |
247 // Updates the auto hide state immediately. | |
248 void UpdateAutoHideStateNow(); | |
249 | |
250 // Stops the auto hide timer and clears | |
251 // |mouse_over_shelf_when_auto_hide_timer_started_|. | |
252 void StopAutoHideTimer(); | |
253 | |
254 // Returns the bounds of an additional region which can trigger showing the | |
255 // shelf. This region exists to make it easier to trigger showing the shelf | |
256 // when the shelf is auto hidden and the shelf is on the boundary between | |
257 // two displays. | |
258 gfx::Rect GetAutoHideShowShelfRegionInScreen() const; | |
259 | |
260 // Returns the AutoHideState. This value is determined from the shelf and | |
261 // tray. | |
262 ShelfAutoHideState CalculateAutoHideState( | |
263 ShelfVisibilityState visibility_state) const; | |
264 | |
265 // Returns true if |window| is a descendant of the shelf. | |
266 bool IsShelfWindow(WmWindow* window); | |
267 | |
268 int GetWorkAreaInsets(const State& state, int size) const; | |
269 | |
270 // Overridden from DockedWindowLayoutManagerObserver: | |
271 void OnDockBoundsChanging( | |
272 const gfx::Rect& dock_bounds, | |
273 DockedWindowLayoutManagerObserver::Reason reason) override; | |
274 | |
275 // Called when the LoginUI changes from visible to invisible. | |
276 void UpdateShelfVisibilityAfterLoginUIChange(); | |
277 | |
278 // Compute |target_bounds| opacity based on gesture and shelf visibility. | |
279 float ComputeTargetOpacity(const State& state); | |
280 | |
281 // Returns true if there is a fullscreen window open that causes the shelf | |
282 // to be hidden. | |
283 bool IsShelfHiddenForFullscreen() const; | |
284 | |
285 // Gesture related functions: | |
286 void StartGestureDrag(const ui::GestureEvent& gesture); | |
287 void UpdateGestureDrag(const ui::GestureEvent& gesture); | |
288 void CompleteGestureDrag(const ui::GestureEvent& gesture); | |
289 void CancelGestureDrag(); | |
290 | |
291 // True when inside UpdateBoundsAndOpacity() method. Used to prevent calling | |
292 // UpdateBoundsAndOpacity() again from SetChildBounds(). | |
293 bool updating_bounds_; | |
294 | |
295 bool in_shutdown_ = false; | |
296 | |
297 // True if the last mouse event was a mouse drag. | |
298 bool in_mouse_drag_ = false; | |
299 | |
300 // Current state. | |
301 State state_; | |
302 | |
303 ShelfWidget* shelf_widget_; | |
304 WmShelf* wm_shelf_; | |
305 | |
306 // Do any windows overlap the shelf? This is maintained by WorkspaceManager. | |
307 bool window_overlaps_shelf_; | |
308 | |
309 base::OneShotTimer auto_hide_timer_; | |
310 | |
311 // Whether the mouse was over the shelf when the auto hide timer started. | |
312 // False when neither the auto hide timer nor the timer task are running. | |
313 bool mouse_over_shelf_when_auto_hide_timer_started_; | |
314 | |
315 base::ObserverList<ShelfLayoutManagerObserver> observers_; | |
316 | |
317 // The shelf reacts to gesture-drags, and can be set to auto-hide for certain | |
318 // gestures. Some shelf behaviour (e.g. visibility state, background color | |
319 // etc.) are affected by various stages of the drag. The enum keeps track of | |
320 // the present status of the gesture drag. | |
321 enum GestureDragStatus { | |
322 GESTURE_DRAG_NONE, | |
323 GESTURE_DRAG_IN_PROGRESS, | |
324 GESTURE_DRAG_CANCEL_IN_PROGRESS, | |
325 GESTURE_DRAG_COMPLETE_IN_PROGRESS | |
326 }; | |
327 GestureDragStatus gesture_drag_status_; | |
328 | |
329 // Tracks the amount of the drag. The value is only valid when | |
330 // |gesture_drag_status_| is set to GESTURE_DRAG_IN_PROGRESS. | |
331 float gesture_drag_amount_; | |
332 | |
333 // Manage the auto-hide state during the gesture. | |
334 ShelfAutoHideState gesture_drag_auto_hide_state_; | |
335 | |
336 // Used to delay updating shelf background. | |
337 UpdateShelfObserver* update_shelf_observer_; | |
338 | |
339 // The bounds of the keyboard. | |
340 gfx::Rect keyboard_bounds_; | |
341 | |
342 // The bounds of the dock. | |
343 gfx::Rect dock_bounds_; | |
344 | |
345 // The bounds within the root window not occupied by the shelf nor the virtual | |
346 // keyboard. | |
347 gfx::Rect user_work_area_bounds_; | |
348 | |
349 // The height of the ChromeVox panel at the top of the screen, which | |
350 // needs to be removed from the available work area. | |
351 int chromevox_panel_height_; | |
352 | |
353 // The show hide animation duration override or 0 for default. | |
354 int duration_override_in_ms_; | |
355 | |
356 // The current shelf background. Should not be assigned to directly, use | |
357 // MaybeUpdateShelfBackground() instead. | |
358 ShelfBackgroundType shelf_background_type_; | |
359 | |
360 DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManager); | |
361 }; | |
362 | |
363 } // namespace ash | |
364 | |
365 #endif // ASH_COMMON_SHELF_SHELF_LAYOUT_MANAGER_H_ | |
OLD | NEW |