Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 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 CHROME_BROWSER_UI_VIEWS_FRAME_IMMERSIVE_MODE_CONTROLLER_ASH_H_ |
| 6 | #define CHROME_BROWSER_UI_VIEWS_FRAME_IMMERSIVE_MODE_CONTROLLER_ASH_H_ |
| 7 | |
| 8 | #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" |
| 9 | |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 10 | #include "base/timer/timer.h" |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 11 | #include "content/public/browser/notification_observer.h" |
| 12 | #include "content/public/browser/notification_registrar.h" |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 13 | #include "ui/aura/window_observer.h" |
| 14 | #include "ui/base/animation/animation_delegate.h" |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 15 | #include "ui/base/events/event_handler.h" |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 16 | #include "ui/gfx/rect.h" |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 17 | #include "ui/views/focus/focus_manager.h" |
| 18 | #include "ui/views/widget/widget_observer.h" |
| 19 | |
| 20 | class BrowserView; |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 21 | class BookmarkBarView; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 22 | |
| 23 | namespace aura { |
| 24 | class Window; |
| 25 | } |
| 26 | |
| 27 | namespace gfx { |
| 28 | class Transform; |
| 29 | } |
| 30 | |
| 31 | namespace ui { |
| 32 | class Layer; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 33 | class LocatedEvent; |
| 34 | class SlideAnimation; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 35 | } |
| 36 | |
| 37 | namespace views { |
| 38 | class View; |
| 39 | } |
| 40 | |
| 41 | class ImmersiveModeControllerAsh : public ImmersiveModeController, |
| 42 | public content::NotificationObserver, |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 43 | public ui::AnimationDelegate, |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 44 | public ui::EventHandler, |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 45 | public views::FocusChangeListener, |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 46 | public views::WidgetObserver, |
| 47 | public aura::WindowObserver { |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 48 | public: |
| 49 | ImmersiveModeControllerAsh(); |
| 50 | virtual ~ImmersiveModeControllerAsh(); |
| 51 | |
| 52 | // These methods are used to increment and decrement |revealed_lock_count_|. |
| 53 | // If immersive mode is enabled, a transition from 1 to 0 in |
| 54 | // |revealed_lock_count_| closes the top-of-window views and a transition |
| 55 | // from 0 to 1 in |revealed_lock_count_| reveals the top-of-window views. |
| 56 | void LockRevealedState(AnimateReveal animate_reveal); |
| 57 | void UnlockRevealedState(); |
| 58 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 59 | // Exits immersive fullscreen based on |native_window_|'s show state. |
| 60 | void MaybeExitImmersiveFullscreen(); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 61 | |
| 62 | // ImmersiveModeController overrides: |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 63 | virtual void Init(Delegate* delegate, |
| 64 | views::Widget* widget, |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 65 | views::View* top_container) OVERRIDE; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 66 | virtual void SetEnabled(bool enabled) OVERRIDE; |
| 67 | virtual bool IsEnabled() const OVERRIDE; |
| 68 | virtual bool ShouldHideTabIndicators() const OVERRIDE; |
| 69 | virtual bool ShouldHideTopViews() const OVERRIDE; |
| 70 | virtual bool IsRevealed() const OVERRIDE; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 71 | virtual int GetTopContainerVerticalOffset( |
| 72 | const gfx::Size& top_container_size) const OVERRIDE; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 73 | virtual ImmersiveRevealedLock* GetRevealedLock( |
| 74 | AnimateReveal animate_reveal) OVERRIDE WARN_UNUSED_RESULT; |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 75 | virtual void OnFindBarVisibleBoundsChanged( |
| 76 | const gfx::Rect& new_visible_bounds_in_screen) OVERRIDE; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 77 | |
| 78 | // content::NotificationObserver override: |
| 79 | virtual void Observe(int type, |
| 80 | const content::NotificationSource& source, |
| 81 | const content::NotificationDetails& details) OVERRIDE; |
| 82 | |
| 83 | // ui::EventHandler overrides: |
| 84 | virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 85 | virtual void OnTouchEvent(ui::TouchEvent* event) OVERRIDE; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 86 | virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE; |
| 87 | |
| 88 | // views::FocusChangeObserver overrides: |
| 89 | virtual void OnWillChangeFocus(views::View* focused_before, |
| 90 | views::View* focused_now) OVERRIDE; |
| 91 | virtual void OnDidChangeFocus(views::View* focused_before, |
| 92 | views::View* focused_now) OVERRIDE; |
| 93 | |
| 94 | // views::WidgetObserver overrides: |
| 95 | virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE; |
| 96 | virtual void OnWidgetActivationChanged(views::Widget* widget, |
| 97 | bool active) OVERRIDE; |
| 98 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 99 | // ui::AnimationDelegate overrides: |
| 100 | virtual void AnimationEnded(const ui::Animation* animation) OVERRIDE; |
| 101 | virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE; |
| 102 | |
| 103 | // aura::WindowObserver overrides: |
| 104 | virtual void OnWindowPropertyChanged(aura::Window* window, |
| 105 | const void* key, |
| 106 | intptr_t old) OVERRIDE; |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 107 | virtual void OnAddTransientChild(aura::Window* window, |
| 108 | aura::Window* transient) OVERRIDE; |
| 109 | virtual void OnRemoveTransientChild(aura::Window* window, |
| 110 | aura::Window* transient) OVERRIDE; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 111 | |
| 112 | // Testing interface. |
| 113 | void SetForceHideTabIndicatorsForTest(bool force); |
| 114 | void StartRevealForTest(bool hovered); |
| 115 | void SetMouseHoveredForTest(bool hovered); |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 116 | void DisableAnimationsForTest(); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 117 | |
| 118 | private: |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 119 | friend class ImmersiveModeControllerAshTest; |
| 120 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 121 | enum Animate { |
| 122 | ANIMATE_NO, |
| 123 | ANIMATE_SLOW, |
| 124 | ANIMATE_FAST, |
| 125 | }; |
| 126 | enum Layout { |
| 127 | LAYOUT_YES, |
| 128 | LAYOUT_NO |
| 129 | }; |
| 130 | enum RevealState { |
| 131 | CLOSED, // Top container only showing tabstrip, y = 0. |
| 132 | SLIDING_OPEN, // All views showing, y animating from -height to 0. |
| 133 | REVEALED, // All views showing, y = 0. |
| 134 | SLIDING_CLOSED, // All views showing, y animating from 0 to -height. |
| 135 | }; |
| 136 | enum TabIndicatorVisibility { |
| 137 | TAB_INDICATORS_FORCE_HIDE, |
| 138 | TAB_INDICATORS_HIDE, |
| 139 | TAB_INDICATORS_SHOW |
| 140 | }; |
| 141 | enum SwipeType { |
| 142 | SWIPE_OPEN, |
| 143 | SWIPE_CLOSE, |
| 144 | SWIPE_NONE |
| 145 | }; |
| 146 | |
| 147 | // Enables or disables observers for mouse move, focus, and window restore. |
| 148 | void EnableWindowObservers(bool enable); |
| 149 | |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 150 | // Updates |top_edge_hover_timer_| based on a mouse |event|. If the mouse is |
| 151 | // hovered at the top of the screen the timer is started. If the mouse moves |
| 152 | // away from the top edge, or moves too much in the x direction, the timer is |
| 153 | // stopped. |
| 154 | void UpdateTopEdgeHoverTimer(ui::MouseEvent* event); |
| 155 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 156 | // Updates |located_event_revealed_lock_| based on the current mouse state and |
| 157 | // the current touch state. |
| 158 | // |event| is NULL if the source event is not known. |
| 159 | void UpdateLocatedEventRevealedLock(ui::LocatedEvent* event); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 160 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 161 | // Acquires |located_event_revealed_lock_| if it is not already held. |
| 162 | void AcquireLocatedEventRevealedLock(); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 163 | |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 164 | // Updates |focus_revealed_lock_| based on the currently active view and the |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 165 | // currently active widget. |
| 166 | void UpdateFocusRevealedLock(); |
| 167 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 168 | // Update |located_event_revealed_lock_| and |focus_revealed_lock_| as a |
| 169 | // result of a gesture of |swipe_type|. Returns true if any locks were |
| 170 | // acquired or released. |
| 171 | bool UpdateRevealedLocksForSwipe(SwipeType swipe_type); |
| 172 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 173 | // Updates whether fullscreen uses any chrome at all. When using minimal |
| 174 | // chrome, a 'light bar' is permanently visible for the launcher and possibly |
| 175 | // for the tabstrip. |
| 176 | void UpdateUseMinimalChrome(Layout layout); |
| 177 | |
| 178 | // Returns the animation duration given |animate|. |
| 179 | int GetAnimationDuration(Animate animate) const; |
| 180 | |
| 181 | // Temporarily reveals the top-of-window views while in immersive mode, |
| 182 | // hiding them when the cursor exits the area of the top views. If |animate| |
| 183 | // is not ANIMATE_NO, slides in the view, otherwise shows it immediately. |
| 184 | void MaybeStartReveal(Animate animate); |
| 185 | |
| 186 | // Enables or disables layer-based painting to allow smooth animations. |
| 187 | void EnablePaintToLayer(bool enable); |
| 188 | |
| 189 | // Updates the browser root view's layout including window caption controls. |
| 190 | void LayoutBrowserRootView(); |
| 191 | |
| 192 | // Called when the animation to slide open the top-of-window views has |
| 193 | // completed. |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 194 | void OnSlideOpenAnimationCompleted(Layout layout); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 195 | |
| 196 | // Hides the top-of-window views if immersive mode is enabled and nothing is |
| 197 | // keeping them revealed. Optionally animates. |
| 198 | void MaybeEndReveal(Animate animate); |
| 199 | |
| 200 | // Called when the animation to slide out the top-of-window views has |
| 201 | // completed. |
| 202 | void OnSlideClosedAnimationCompleted(); |
| 203 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 204 | // Returns whether immersive fullscreen should be exited based on |
| 205 | // |native_window_|'s show state. This handles cases where the user has |
| 206 | // exited immersive fullscreen without going through |
| 207 | // FullscreenController::ToggleFullscreenMode(). This is the case if the |
| 208 | // user exits fullscreen via the restore button. |
| 209 | bool ShouldExitImmersiveFullscreen() const; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 210 | |
| 211 | // Returns the type of swipe given |event|. |
| 212 | SwipeType GetSwipeType(ui::GestureEvent* event) const; |
| 213 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 214 | // Returns true if a mouse event at |location_in_screen| should be ignored. |
| 215 | // Ignored mouse events should not contribute to revealing or unrevealing the |
| 216 | // top-of-window views. |
| 217 | bool ShouldIgnoreMouseEventAtLocation( |
| 218 | const gfx::Point& location_in_screen) const; |
| 219 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 220 | // True when |location| is "near" to the top container. When the top container |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 221 | // is not closed "near" means within the displayed bounds or above it. When |
| 222 | // the top container is closed "near" means either within the displayed |
| 223 | // bounds, above it, or within a few pixels below it. This allow the container |
| 224 | // to steal enough pixels to detect a swipe in and handles the case that there |
| 225 | // is a bezel sensor above the top container. |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 226 | bool ShouldHandleGestureEvent(const gfx::Point& location) const; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 227 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 228 | // Recreate |bubble_manager_| and start observing any bubbles anchored to a |
| 229 | // child of |top_container_|. |
| 230 | void RecreateBubbleManager(); |
| 231 | |
Ben Murdoch | ca12bfa | 2013-07-23 11:17:05 +0100 | [diff] [blame] | 232 | // Shrinks or expands the touch hit test by updating insets for the render |
| 233 | // window depending on if top_inset is positive or negative respectively. |
| 234 | // Used to ensure that touch events at the top of the screen go to the top |
| 235 | // container so a slide gesture can be generated when the content window is |
| 236 | // consuming all touch events sent to it. |
| 237 | void SetRenderWindowTopInsetsForTouch(int top_inset); |
| 238 | |
Torne (Richard Coles) | 90dce4d | 2013-05-29 14:40:03 +0100 | [diff] [blame] | 239 | // Injected dependencies. Not owned. |
| 240 | Delegate* delegate_; |
| 241 | views::Widget* widget_; |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 242 | views::View* top_container_; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 243 | |
| 244 | // True if the window observers are enabled. |
| 245 | bool observers_enabled_; |
| 246 | |
| 247 | // True when in immersive mode. |
| 248 | bool enabled_; |
| 249 | |
| 250 | // State machine for the revealed/closed animations. |
| 251 | RevealState reveal_state_; |
| 252 | |
| 253 | int revealed_lock_count_; |
| 254 | |
| 255 | // The visibility of the miniature "tab indicators" in the main browser view |
| 256 | // when immersive mode is enabled and the top-of-window views are closed. |
| 257 | TabIndicatorVisibility tab_indicator_visibility_; |
| 258 | |
Torne (Richard Coles) | b2df76e | 2013-05-13 16:52:09 +0100 | [diff] [blame] | 259 | // Timer to track cursor being held at the top edge of the screen. |
| 260 | base::OneShotTimer<ImmersiveModeController> top_edge_hover_timer_; |
| 261 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 262 | // The cursor x position in screen coordinates when the cursor first hit the |
| 263 | // top edge of the screen. |
| 264 | int mouse_x_when_hit_top_in_screen_; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 265 | |
Ben Murdoch | eb525c5 | 2013-07-10 11:40:50 +0100 | [diff] [blame] | 266 | // Tracks if the controller has seen a ET_GESTURE_SCROLL_BEGIN, without the |
| 267 | // following events. |
| 268 | bool gesture_begun_; |
| 269 | |
Torne (Richard Coles) | 7d4cd47 | 2013-06-19 11:58:07 +0100 | [diff] [blame] | 270 | // The current visible bounds of the find bar, in screen coordinates. This is |
| 271 | // an empty rect if the find bar is not visible. |
| 272 | gfx::Rect find_bar_visible_bounds_in_screen_; |
| 273 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 274 | // Lock which keeps the top-of-window views revealed based on the current |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 275 | // mouse state and the current touch state. Acquiring the lock is used to |
| 276 | // trigger a reveal when the user moves the mouse to the top of the screen |
| 277 | // and when the user does a SWIPE_OPEN edge gesture. |
| 278 | scoped_ptr<ImmersiveRevealedLock> located_event_revealed_lock_; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 279 | |
| 280 | // Lock which keeps the top-of-window views revealed based on the focused view |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 281 | // and the active widget. Acquiring the lock never triggers a reveal because |
| 282 | // a view is not focusable till a reveal has made it visible. |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 283 | scoped_ptr<ImmersiveRevealedLock> focus_revealed_lock_; |
| 284 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 285 | // Native window for the browser. |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 286 | aura::Window* native_window_; |
| 287 | |
Torne (Richard Coles) | 868fa2f | 2013-06-11 10:57:03 +0100 | [diff] [blame] | 288 | // The animation which controls sliding the top-of-window views in and out. |
| 289 | scoped_ptr<ui::SlideAnimation> animation_; |
| 290 | |
| 291 | // Whether the animations are disabled for testing. |
| 292 | bool animations_disabled_for_test_; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 293 | |
Ben Murdoch | 7dbb3d5 | 2013-07-17 14:55:54 +0100 | [diff] [blame] | 294 | // Manages bubbles which are anchored to a child of |top_container_|. |
| 295 | class BubbleManager; |
| 296 | scoped_ptr<BubbleManager> bubble_manager_; |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 297 | |
| 298 | content::NotificationRegistrar registrar_; |
| 299 | |
| 300 | base::WeakPtrFactory<ImmersiveModeControllerAsh> weak_ptr_factory_; |
| 301 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 302 | DISALLOW_COPY_AND_ASSIGN(ImmersiveModeControllerAsh); |
| 303 | }; |
| 304 | |
| 305 | #endif // CHROME_BROWSER_UI_VIEWS_FRAME_IMMERSIVE_MODE_CONTROLLER_ASH_H_ |