| 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 |