1// Copyright (c) 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_COCOA_PRESENTATION_MODE_CONTROLLER_H_
6#define CHROME_BROWSER_UI_COCOA_PRESENTATION_MODE_CONTROLLER_H_
7
8#include <Carbon/Carbon.h>
9#import <Cocoa/Cocoa.h>
10
11#include "base/mac/mac_util.h"
12#include "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
13
14@class BrowserWindowController;
15@class DropdownAnimation;
16
17namespace fullscreen_mac {
18enum SlidingStyle {
19  OMNIBOX_TABS_PRESENT = 0,  // Tab strip and omnibox both visible.
20  OMNIBOX_TABS_HIDDEN,       // Tab strip and omnibox both hidden.
21};
22}  // namespace fullscreen_mac
23
24// TODO(erikchen): This controller is misnamed. It manages the sliding tab
25// strip and omnibox in all fullscreen modes.
26
27// Provides a controller to manage presentation mode for a single browser
28// window.  This class handles running animations, showing and hiding the
29// floating dropdown bar, and managing the tracking area associated with the
30// dropdown.  This class does not directly manage any views -- the
31// BrowserWindowController is responsible for positioning and z-ordering views.
32//
33// Tracking areas are disabled while animations are running.  If
34// |overlayFrameChanged:| is called while an animation is running, the
35// controller saves the new frame and installs the appropriate tracking area
36// when the animation finishes.  This is largely done for ease of
37// implementation; it is easier to check the mouse location at each animation
38// step than it is to manage a constantly-changing tracking area.
39@interface PresentationModeController : NSObject<NSAnimationDelegate> {
40 @private
41  // Our parent controller.
42  BrowserWindowController* browserController_;  // weak
43
44  // The content view for the window.  This is nil when not in presentation
45  // mode.
46  NSView* contentView_;  // weak
47
48  // YES while this controller is in the process of entering presentation mode.
49  BOOL enteringPresentationMode_;
50
51  // Whether or not we are in presentation mode.
52  BOOL inPresentationMode_;
53
54  // The tracking area associated with the floating dropdown bar.  This tracking
55  // area is attached to |contentView_|, because when the dropdown is completely
56  // hidden, we still need to keep a 1px tall tracking area visible.  Attaching
57  // to the content view allows us to do this.  |trackingArea_| can be nil if
58  // not in presentation mode or during animations.
59  base::scoped_nsobject<NSTrackingArea> trackingArea_;
60
61  // Pointer to the currently running animation.  Is nil if no animation is
62  // running.
63  base::scoped_nsobject<DropdownAnimation> currentAnimation_;
64
65  // Timers for scheduled showing/hiding of the bar (which are always done with
66  // animation).
67  base::scoped_nsobject<NSTimer> showTimer_;
68  base::scoped_nsobject<NSTimer> hideTimer_;
69
70  // Holds the current bounds of |trackingArea_|, even if |trackingArea_| is
71  // currently nil.  Used to restore the tracking area when an animation
72  // completes.
73  NSRect trackingAreaBounds_;
74
75  // Tracks the currently requested system fullscreen mode, used to show or hide
76  // the menubar.  This should be |kFullScreenModeNormal| when the window is not
77  // main or not fullscreen, |kFullScreenModeHideAll| while the overlay is
78  // hidden, and |kFullScreenModeHideDock| while the overlay is shown.  If the
79  // window is not on the primary screen, this should always be
80  // |kFullScreenModeNormal|.  This value can get out of sync with the correct
81  // state if we miss a notification (which can happen when a window is closed).
82  // Used to track the current state and make sure we properly restore the menu
83  // bar when this controller is destroyed.
84  base::mac::FullScreenMode systemFullscreenMode_;
85
86  // Whether the omnibox is hidden in fullscreen.
87  fullscreen_mac::SlidingStyle slidingStyle_;
88
89  // The fraction of the AppKit Menubar that is showing. Ranges from 0 to 1.
90  // Only used in AppKit Fullscreen.
91  CGFloat menubarFraction_;
92
93  // The fraction of the omnibox/tabstrip that is showing. Ranges from 0 to 1.
94  // Used in both AppKit and Immersive Fullscreen.
95  CGFloat toolbarFraction_;
96
97  // A Carbon event handler that tracks the revealed fraction of the menu bar.
98  EventHandlerRef menuBarTrackingHandler_;
99}
100
101@property(readonly, nonatomic) BOOL inPresentationMode;
102@property(nonatomic, assign) fullscreen_mac::SlidingStyle slidingStyle;
103@property(nonatomic, assign) CGFloat toolbarFraction;
104
105// Designated initializer.
106- (id)initWithBrowserController:(BrowserWindowController*)controller
107                          style:(fullscreen_mac::SlidingStyle)style;
108
109// Informs the controller that the browser has entered or exited presentation
110// mode. |-enterPresentationModeForContentView:showDropdown:| should be called
111// after the window is setup, just before it is shown. |-exitPresentationMode|
112// should be called before any views are moved back to the non-fullscreen
113// window.  If |-enterPresentationModeForContentView:showDropdown:| is called,
114// it must be balanced with a call to |-exitPresentationMode| before the
115// controller is released.
116- (void)enterPresentationModeForContentView:(NSView*)contentView
117                               showDropdown:(BOOL)showDropdown;
118- (void)exitPresentationMode;
119
120// Returns the amount by which the floating bar should be offset downwards (to
121// avoid the menu) and by which the overlay view should be enlarged vertically.
122// Generally, this is > 0 when the window is on the primary screen and 0
123// otherwise.
124- (CGFloat)floatingBarVerticalOffset;
125
126// Informs the controller that the overlay's frame has changed.  The controller
127// uses this information to update its tracking areas.
128- (void)overlayFrameChanged:(NSRect)frame;
129
130// Informs the controller that the overlay should be shown/hidden, possibly with
131// animation, possibly after a delay (only applicable for the animated case).
132- (void)ensureOverlayShownWithAnimation:(BOOL)animate delay:(BOOL)delay;
133- (void)ensureOverlayHiddenWithAnimation:(BOOL)animate delay:(BOOL)delay;
134
135// Cancels any running animation and timers.
136- (void)cancelAnimationAndTimers;
137
138// In any fullscreen mode, the y offset to use for the content at the top of
139// the screen (tab strip, omnibox, bookmark bar, etc).
140// Ranges from 0 to -22.
141- (CGFloat)menubarOffset;
142
143@end
144
145// Private methods exposed for testing.
146@interface PresentationModeController (ExposedForTesting)
147// Adjusts the AppKit Fullscreen options of the application.
148- (void)setSystemFullscreenModeTo:(base::mac::FullScreenMode)mode;
149
150// Callback for menu bar animations.
151- (void)setMenuBarRevealProgress:(CGFloat)progress;
152
153// Updates the local state that reflects the fraction of the toolbar area that
154// is showing. This function has the side effect of changing the AppKit
155// Fullscreen option for whether the menu bar is shown.
156- (void)changeToolbarFraction:(CGFloat)fraction;
157@end
158
159// Notification posted when we're about to enter or leave fullscreen.
160extern NSString* const kWillEnterFullscreenNotification;
161extern NSString* const kWillLeaveFullscreenNotification;
162
163#endif  // CHROME_BROWSER_UI_COCOA_PRESENTATION_MODE_CONTROLLER_H_
164