| 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 |