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