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