OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 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_TAB_STRIP_CONTROLLER_H_ | |
6 #define CHROME_BROWSER_UI_COCOA_TAB_STRIP_CONTROLLER_H_ | |
7 #pragma once | |
8 | |
9 #import <Cocoa/Cocoa.h> | |
10 | |
11 #include "base/scoped_nsobject.h" | |
12 #include "base/scoped_ptr.h" | |
13 #import "chrome/browser/ui/cocoa/tab_contents_controller.h" | |
14 #import "chrome/browser/ui/cocoa/tab_controller_target.h" | |
15 #import "chrome/browser/ui/cocoa/url_drop_target.h" | |
16 #import "third_party/GTM/AppKit/GTMWindowSheetController.h" | |
17 | |
18 @class NewTabButton; | |
19 @class TabContentsController; | |
20 @class TabView; | |
21 @class TabStripView; | |
22 | |
23 class Browser; | |
24 class ConstrainedWindowMac; | |
25 class TabStripModelObserverBridge; | |
26 class TabStripModel; | |
27 class TabContents; | |
28 class ToolbarModel; | |
29 | |
30 // The interface for the tab strip controller's delegate. | |
31 // Delegating TabStripModelObserverBridge's events (in lieu of directly | |
32 // subscribing to TabStripModelObserverBridge events, as TabStripController | |
33 // does) is necessary to guarantee a proper order of subviews layout updates, | |
34 // otherwise it might trigger unnesessary content relayout, UI flickering etc. | |
35 @protocol TabStripControllerDelegate | |
36 | |
37 // Stripped down version of TabStripModelObserverBridge:selectTabWithContents. | |
38 - (void)onSelectTabWithContents:(TabContents*)contents; | |
39 | |
40 // Stripped down version of TabStripModelObserverBridge:tabReplacedWithContents. | |
41 - (void)onReplaceTabWithContents:(TabContents*)contents; | |
42 | |
43 // Stripped down version of TabStripModelObserverBridge:tabChangedWithContents. | |
44 - (void)onSelectedTabChange:(TabStripModelObserver::TabChangeType)change; | |
45 | |
46 // Stripped down version of TabStripModelObserverBridge:tabDetachedWithContents. | |
47 - (void)onTabDetachedWithContents:(TabContents*)contents; | |
48 | |
49 @end | |
50 | |
51 // A class that handles managing the tab strip in a browser window. It uses | |
52 // a supporting C++ bridge object to register for notifications from the | |
53 // TabStripModel. The Obj-C part of this class handles drag and drop and all | |
54 // the other Cocoa-y aspects. | |
55 // | |
56 // For a full description of the design, see | |
57 // http://www.chromium.org/developers/design-documents/tab-strip-mac | |
58 @interface TabStripController : | |
59 NSObject<TabControllerTarget, | |
60 URLDropTargetController, | |
61 GTMWindowSheetControllerDelegate, | |
62 TabContentsControllerDelegate> { | |
63 @protected | |
64 // YES if tabs are to be laid out vertically instead of horizontally. | |
65 BOOL verticalLayout_; | |
66 | |
67 @private | |
68 scoped_nsobject<TabStripView> tabStripView_; | |
69 NSView* switchView_; // weak | |
70 scoped_nsobject<NSView> dragBlockingView_; // avoid bad window server drags | |
71 NewTabButton* newTabButton_; // weak, obtained from the nib. | |
72 | |
73 // Tracks the newTabButton_ for rollovers. | |
74 scoped_nsobject<NSTrackingArea> newTabTrackingArea_; | |
75 scoped_ptr<TabStripModelObserverBridge> bridge_; | |
76 Browser* browser_; // weak | |
77 TabStripModel* tabStripModel_; // weak | |
78 // Delegate that is informed about tab state changes. | |
79 id<TabStripControllerDelegate> delegate_; // weak | |
80 | |
81 // YES if the new tab button is currently displaying the hover image (if the | |
82 // mouse is currently over the button). | |
83 BOOL newTabButtonShowingHoverImage_; | |
84 | |
85 // Access to the TabContentsControllers (which own the parent view | |
86 // for the toolbar and associated tab contents) given an index. Call | |
87 // |indexFromModelIndex:| to convert a |tabStripModel_| index to a | |
88 // |tabContentsArray_| index. Do NOT assume that the indices of | |
89 // |tabStripModel_| and this array are identical, this is e.g. not true while | |
90 // tabs are animating closed (closed tabs are removed from |tabStripModel_| | |
91 // immediately, but from |tabContentsArray_| only after their close animation | |
92 // has completed). | |
93 scoped_nsobject<NSMutableArray> tabContentsArray_; | |
94 // An array of TabControllers which manage the actual tab views. See note | |
95 // above |tabContentsArray_|. |tabContentsArray_| and |tabArray_| always | |
96 // contain objects belonging to the same tabs at the same indices. | |
97 scoped_nsobject<NSMutableArray> tabArray_; | |
98 | |
99 // Set of TabControllers that are currently animating closed. | |
100 scoped_nsobject<NSMutableSet> closingControllers_; | |
101 | |
102 // These values are only used during a drag, and override tab positioning. | |
103 TabView* placeholderTab_; // weak. Tab being dragged | |
104 NSRect placeholderFrame_; // Frame to use | |
105 CGFloat placeholderStretchiness_; // Vertical force shown by streching tab. | |
106 NSRect droppedTabFrame_; // Initial frame of a dropped tab, for animation. | |
107 // Frame targets for all the current views. | |
108 // target frames are used because repeated requests to [NSView animator]. | |
109 // aren't coalesced, so we store frames to avoid redundant calls. | |
110 scoped_nsobject<NSMutableDictionary> targetFrames_; | |
111 NSRect newTabTargetFrame_; | |
112 // If YES, do not show the new tab button during layout. | |
113 BOOL forceNewTabButtonHidden_; | |
114 // YES if we've successfully completed the initial layout. When this is | |
115 // NO, we probably don't want to do any animation because we're just coming | |
116 // into being. | |
117 BOOL initialLayoutComplete_; | |
118 | |
119 // Width available for resizing the tabs (doesn't include the new tab | |
120 // button). Used to restrict the available width when closing many tabs at | |
121 // once to prevent them from resizing to fit the full width. If the entire | |
122 // width should be used, this will have a value of |kUseFullAvailableWidth|. | |
123 float availableResizeWidth_; | |
124 // A tracking area that's the size of the tab strip used to be notified | |
125 // when the mouse moves in the tab strip | |
126 scoped_nsobject<NSTrackingArea> trackingArea_; | |
127 TabView* hoveredTab_; // weak. Tab that the mouse is hovering over | |
128 | |
129 // Array of subviews which are permanent (and which should never be removed), | |
130 // such as the new-tab button, but *not* the tabs themselves. | |
131 scoped_nsobject<NSMutableArray> permanentSubviews_; | |
132 | |
133 // The default favicon, so we can use one copy for all buttons. | |
134 scoped_nsobject<NSImage> defaultFavIcon_; | |
135 | |
136 // The amount by which to indent the tabs on the left (to make room for the | |
137 // red/yellow/green buttons). | |
138 CGFloat indentForControls_; | |
139 | |
140 // Manages per-tab sheets. | |
141 scoped_nsobject<GTMWindowSheetController> sheetController_; | |
142 | |
143 // Is the mouse currently inside the strip; | |
144 BOOL mouseInside_; | |
145 } | |
146 | |
147 @property(nonatomic) CGFloat indentForControls; | |
148 | |
149 // Initialize the controller with a view and browser that contains | |
150 // everything else we'll need. |switchView| is the view whose contents get | |
151 // "switched" every time the user switches tabs. The children of this view | |
152 // will be released, so if you want them to stay around, make sure | |
153 // you have retained them. | |
154 // |delegate| is the one listening to filtered TabStripModelObserverBridge's | |
155 // events (see TabStripControllerDelegate for more details). | |
156 - (id)initWithView:(TabStripView*)view | |
157 switchView:(NSView*)switchView | |
158 browser:(Browser*)browser | |
159 delegate:(id<TabStripControllerDelegate>)delegate; | |
160 | |
161 // Return the view for the currently selected tab. | |
162 - (NSView*)selectedTabView; | |
163 | |
164 // Set the frame of the selected tab, also updates the internal frame dict. | |
165 - (void)setFrameOfSelectedTab:(NSRect)frame; | |
166 | |
167 // Move the given tab at index |from| in this window to the location of the | |
168 // current placeholder. | |
169 - (void)moveTabFromIndex:(NSInteger)from; | |
170 | |
171 // Drop a given TabContents at the location of the current placeholder. If there | |
172 // is no placeholder, it will go at the end. Used when dragging from another | |
173 // window when we don't have access to the TabContents as part of our strip. | |
174 // |frame| is in the coordinate system of the tab strip view and represents | |
175 // where the user dropped the new tab so it can be animated into its correct | |
176 // location when the tab is added to the model. If the tab was pinned in its | |
177 // previous window, setting |pinned| to YES will propagate that state to the | |
178 // new window. Mini-tabs are either app or pinned tabs; the app state is stored | |
179 // by the |contents|, but the |pinned| state is the caller's responsibility. | |
180 - (void)dropTabContents:(TabContentsWrapper*)contents | |
181 withFrame:(NSRect)frame | |
182 asPinnedTab:(BOOL)pinned; | |
183 | |
184 // Returns the index of the subview |view|. Returns -1 if not present. Takes | |
185 // closing tabs into account such that this index will correctly match the tab | |
186 // model. If |view| is in the process of closing, returns -1, as closing tabs | |
187 // are no longer in the model. | |
188 - (NSInteger)modelIndexForTabView:(NSView*)view; | |
189 | |
190 // Return the view at a given index. | |
191 - (NSView*)viewAtIndex:(NSUInteger)index; | |
192 | |
193 // Return the number of tab views in the tab strip. It's same as number of tabs | |
194 // in the model, except when a tab is closing, which will be counted in views | |
195 // count, but no longer in the model. | |
196 - (NSUInteger)viewsCount; | |
197 | |
198 // Set the placeholder for a dragged tab, allowing the |frame| and |strechiness| | |
199 // to be specified. This causes this tab to be rendered in an arbitrary position | |
200 - (void)insertPlaceholderForTab:(TabView*)tab | |
201 frame:(NSRect)frame | |
202 yStretchiness:(CGFloat)yStretchiness; | |
203 | |
204 // Returns whether a tab is being dragged within the tab strip. | |
205 - (BOOL)isDragSessionActive; | |
206 | |
207 // Returns whether or not |tab| can still be fully seen in the tab strip or if | |
208 // its current position would cause it be obscured by things such as the edge | |
209 // of the window or the window decorations. Returns YES only if the entire tab | |
210 // is visible. | |
211 - (BOOL)isTabFullyVisible:(TabView*)tab; | |
212 | |
213 // Show or hide the new tab button. The button is hidden immediately, but | |
214 // waits until the next call to |-layoutTabs| to show it again. | |
215 - (void)showNewTabButton:(BOOL)show; | |
216 | |
217 // Force the tabs to rearrange themselves to reflect the current model. | |
218 - (void)layoutTabs; | |
219 | |
220 // Are we in rapid (tab) closure mode? I.e., is a full layout deferred (while | |
221 // the user closes tabs)? Needed to overcome missing clicks during rapid tab | |
222 // closure. | |
223 - (BOOL)inRapidClosureMode; | |
224 | |
225 // Returns YES if the user is allowed to drag tabs on the strip at this moment. | |
226 // For example, this returns NO if there are any pending tab close animtations. | |
227 - (BOOL)tabDraggingAllowed; | |
228 | |
229 // Default height for tabs. | |
230 + (CGFloat)defaultTabHeight; | |
231 | |
232 // Default indentation for tabs (see |indentForControls_|). | |
233 + (CGFloat)defaultIndentForControls; | |
234 | |
235 // Returns the (lazily created) window sheet controller of this window. Used | |
236 // for the per-tab sheets. | |
237 - (GTMWindowSheetController*)sheetController; | |
238 | |
239 // Destroys the window sheet controller of this window, if it exists. The sheet | |
240 // controller can be recreated by a subsequent call to |-sheetController|. Must | |
241 // not be called if any sheets are currently open. | |
242 // TODO(viettrungluu): This is temporary code needed to allow sheets to work | |
243 // (read: not crash) in fullscreen mode. Once GTMWindowSheetController is | |
244 // modified to support moving sheets between windows, this code can go away. | |
245 // http://crbug.com/19093. | |
246 - (void)destroySheetController; | |
247 | |
248 // Returns the currently active TabContentsController. | |
249 - (TabContentsController*)activeTabContentsController; | |
250 | |
251 // See comments in browser_window_controller.h for documentation about these | |
252 // functions. | |
253 - (void)attachConstrainedWindow:(ConstrainedWindowMac*)window; | |
254 - (void)removeConstrainedWindow:(ConstrainedWindowMac*)window; | |
255 | |
256 @end | |
257 | |
258 // Notification sent when the number of tabs changes. The object will be this | |
259 // controller. | |
260 extern NSString* const kTabStripNumberOfTabsChanged; | |
261 | |
262 #endif // CHROME_BROWSER_UI_COCOA_TAB_STRIP_CONTROLLER_H_ | |
OLD | NEW |