immersive_mode_controller_ash.h revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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/base/events/event_handler.h"
14#include "ui/compositor/layer_animation_observer.h"
15#include "ui/views/focus/focus_manager.h"
16#include "ui/views/widget/widget_observer.h"
17
18class BrowserView;
19class BookmarkBarView;
20class TopContainerView;
21
22namespace aura {
23class Window;
24}
25
26namespace gfx {
27class Transform;
28}
29
30namespace ui {
31class Layer;
32}
33
34namespace views {
35class View;
36}
37
38class ImmersiveModeControllerAsh : public ImmersiveModeController,
39                                   public content::NotificationObserver,
40                                   public ui::EventHandler,
41                                   public ui::ImplicitAnimationObserver,
42                                   public views::FocusChangeListener,
43                                   public views::WidgetObserver {
44 public:
45  ImmersiveModeControllerAsh();
46  virtual ~ImmersiveModeControllerAsh();
47
48  // These methods are used to increment and decrement |revealed_lock_count_|.
49  // If immersive mode is enabled, a transition from 1 to 0 in
50  // |revealed_lock_count_| closes the top-of-window views and a transition
51  // from 0 to 1 in |revealed_lock_count_| reveals the top-of-window views.
52  void LockRevealedState(AnimateReveal animate_reveal);
53  void UnlockRevealedState();
54
55  // Shows the reveal view without any animations if immersive mode is enabled.
56  void MaybeRevealWithoutAnimation();
57
58  // ImmersiveModeController overrides:
59  virtual void Init(Delegate* delegate,
60                    views::Widget* widget,
61                    TopContainerView* top_container) OVERRIDE;
62  virtual void SetEnabled(bool enabled) OVERRIDE;
63  virtual bool IsEnabled() const OVERRIDE;
64  virtual bool ShouldHideTabIndicators() const OVERRIDE;
65  virtual bool ShouldHideTopViews() const OVERRIDE;
66  virtual bool IsRevealed() const OVERRIDE;
67  virtual void MaybeStackViewAtTop() OVERRIDE;
68  virtual ImmersiveRevealedLock* GetRevealedLock(
69      AnimateReveal animate_reveal) OVERRIDE WARN_UNUSED_RESULT;
70  virtual void AnchorWidgetToTopContainer(views::Widget* widget,
71                                          int y_offset) OVERRIDE;
72  virtual void UnanchorWidgetFromTopContainer(views::Widget* widget) OVERRIDE;
73  virtual void OnTopContainerBoundsChanged() OVERRIDE;
74
75  // content::NotificationObserver override:
76  virtual void Observe(int type,
77                       const content::NotificationSource& source,
78                       const content::NotificationDetails& details) OVERRIDE;
79
80  // ui::EventHandler overrides:
81  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
82  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
83
84  // views::FocusChangeObserver overrides:
85  virtual void OnWillChangeFocus(views::View* focused_before,
86                                 views::View* focused_now) OVERRIDE;
87  virtual void OnDidChangeFocus(views::View* focused_before,
88                                views::View* focused_now) OVERRIDE;
89
90  // views::WidgetObserver overrides:
91  virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;
92  virtual void OnWidgetActivationChanged(views::Widget* widget,
93                                         bool active) OVERRIDE;
94
95  // ui::ImplicitAnimationObserver override:
96  virtual void OnImplicitAnimationsCompleted() OVERRIDE;
97
98  // Testing interface.
99  void SetForceHideTabIndicatorsForTest(bool force);
100  void StartRevealForTest(bool hovered);
101  void SetMouseHoveredForTest(bool hovered);
102
103 private:
104  friend class ImmersiveModeControllerAshTest;
105
106  enum Animate {
107    ANIMATE_NO,
108    ANIMATE_SLOW,
109    ANIMATE_FAST,
110  };
111  enum Layout {
112    LAYOUT_YES,
113    LAYOUT_NO
114  };
115  enum RevealState {
116    CLOSED,          // Top container only showing tabstrip, y = 0.
117    SLIDING_OPEN,    // All views showing, y animating from -height to 0.
118    REVEALED,        // All views showing, y = 0.
119    SLIDING_CLOSED,  // All views showing, y animating from 0 to -height.
120  };
121  enum TabIndicatorVisibility {
122    TAB_INDICATORS_FORCE_HIDE,
123    TAB_INDICATORS_HIDE,
124    TAB_INDICATORS_SHOW
125  };
126  enum SwipeType {
127    SWIPE_OPEN,
128    SWIPE_CLOSE,
129    SWIPE_NONE
130  };
131
132  // Enables or disables observers for mouse move, focus, and window restore.
133  void EnableWindowObservers(bool enable);
134
135  // Updates |top_edge_hover_timer_| based on a mouse |event|. If the mouse is
136  // hovered at the top of the screen the timer is started. If the mouse moves
137  // away from the top edge, or moves too much in the x direction, the timer is
138  // stopped.
139  void UpdateTopEdgeHoverTimer(ui::MouseEvent* event);
140
141  // Updates |mouse_revealed_lock_| based on the current mouse state and the
142  // currently active widget.
143  // |maybe_drag| is true if the user may be in the middle of a drag.
144  // |event_type| is the type of event that triggered the update or
145  // ui::ET_UNKNOWN if the source event isn't known.
146  void UpdateMouseRevealedLock(bool maybe_drag, ui::EventType event_type);
147
148  // Acquires the mouse revealed lock if it is not already held.
149  void AcquireMouseRevealedLock();
150
151  // Updates |focus_revealed_lock_| based on the currently active view and the
152  // currently active widget.
153  void UpdateFocusRevealedLock();
154
155  // Updates whether fullscreen uses any chrome at all. When using minimal
156  // chrome, a 'light bar' is permanently visible for the launcher and possibly
157  // for the tabstrip.
158  void UpdateUseMinimalChrome(Layout layout);
159
160  // Returns the animation duration given |animate|.
161  int GetAnimationDuration(Animate animate) const;
162
163  // Temporarily reveals the top-of-window views while in immersive mode,
164  // hiding them when the cursor exits the area of the top views. If |animate|
165  // is not ANIMATE_NO, slides in the view, otherwise shows it immediately.
166  void MaybeStartReveal(Animate animate);
167
168  // Enables or disables layer-based painting to allow smooth animations.
169  void EnablePaintToLayer(bool enable);
170
171  // Updates the browser root view's layout including window caption controls.
172  void LayoutBrowserRootView();
173
174  // Called when the animation to slide open the top-of-window views has
175  // completed.
176  void OnSlideOpenAnimationCompleted();
177
178  // Hides the top-of-window views if immersive mode is enabled and nothing is
179  // keeping them revealed. Optionally animates.
180  void MaybeEndReveal(Animate animate);
181
182  // Called when the animation to slide out the top-of-window views has
183  // completed.
184  void OnSlideClosedAnimationCompleted();
185
186  // Starts an animation for the top-of-window views and any anchored widgets
187  // of |duration_ms| to |target_transform|.
188  void DoAnimation(const gfx::Transform& target_transform, int duration_ms);
189
190  // Starts an animation for |layer| of |duration_ms| to |target_transform|.
191  // If non-NULL, sets |observer| to be notified when the animation completes.
192  void DoLayerAnimation(ui::Layer* layer,
193                        const gfx::Transform& target_transform,
194                        int duration_ms,
195                        ui::ImplicitAnimationObserver* observer);
196
197  // Returns the type of swipe given |event|.
198  SwipeType GetSwipeType(ui::GestureEvent* event) const;
199
200  // True when |location| is "near" to the top container. When the top container
201  // is not closed "near" means within the displayed bounds. When the top
202  // container is closed "near" means either within the displayed bounds or
203  // within a few pixels of it. This allow the container to steal enough pixels
204  // to detect a swipe in.
205  bool IsNearTopContainer(gfx::Point location) const;
206
207  // Injected dependencies. Not owned.
208  Delegate* delegate_;
209  views::Widget* widget_;
210  TopContainerView* top_container_;
211
212  // True if the window observers are enabled.
213  bool observers_enabled_;
214
215  // True when in immersive mode.
216  bool enabled_;
217
218  // State machine for the revealed/closed animations.
219  RevealState reveal_state_;
220
221  int revealed_lock_count_;
222
223  // The visibility of the miniature "tab indicators" in the main browser view
224  // when immersive mode is enabled and the top-of-window views are closed.
225  TabIndicatorVisibility tab_indicator_visibility_;
226
227  // Timer to track cursor being held at the top edge of the screen.
228  base::OneShotTimer<ImmersiveModeController> top_edge_hover_timer_;
229
230  // The cursor x position in root coordinates when the cursor first hit
231  // the top edge of the screen.
232  int mouse_x_when_hit_top_;
233
234  // Lock which keeps the top-of-window views revealed based on the current
235  // mouse state.
236  scoped_ptr<ImmersiveRevealedLock> mouse_revealed_lock_;
237
238  // Lock which keeps the top-of-window views revealed based on the focused view
239  // and the active widget.
240  scoped_ptr<ImmersiveRevealedLock> focus_revealed_lock_;
241
242  // Native window for the browser, needed to clean up observers.
243  aura::Window* native_window_;
244
245  // Observer to disable immersive mode when window leaves the maximized state.
246  class WindowObserver;
247  scoped_ptr<WindowObserver> window_observer_;
248
249  // Manages widgets which are anchored to the top-of-window views.
250  class AnchoredWidgetManager;
251  scoped_ptr<AnchoredWidgetManager> anchored_widget_manager_;
252
253  content::NotificationRegistrar registrar_;
254
255  base::WeakPtrFactory<ImmersiveModeControllerAsh> weak_ptr_factory_;
256
257  // Tracks if the controller has seen a ET_GESTURE_SCROLL_BEGIN, without the
258  // following events.
259  bool gesture_begun_;
260
261  DISALLOW_COPY_AND_ASSIGN(ImmersiveModeControllerAsh);
262};
263
264#endif  // CHROME_BROWSER_UI_VIEWS_FRAME_IMMERSIVE_MODE_CONTROLLER_ASH_H_
265