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