1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_COCOA_TABS_TAB_STRIP_CONTROLLER_H_
#define CHROME_BROWSER_UI_COCOA_TABS_TAB_STRIP_CONTROLLER_H_
#import <Cocoa/Cocoa.h>
#include "base/mac/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
#import "chrome/browser/ui/cocoa/tabs/tab_controller_target.h"
#import "chrome/browser/ui/cocoa/url_drop_target.h"
#include "chrome/browser/ui/tabs/hover_tab_selector.h"
@class CrTrackingArea;
@class NewTabButton;
@class TabContentsController;
@class TabView;
@class TabStripDragController;
@class TabStripView;
class Browser;
class TabStripModelObserverBridge;
class TabStripModel;
namespace content {
class WebContents;
}
// The interface for the tab strip controller's delegate.
// Delegating TabStripModelObserverBridge's events (in lieu of directly
// subscribing to TabStripModelObserverBridge events, as TabStripController
// does) is necessary to guarantee a proper order of subviews layout updates,
// otherwise it might trigger unnesessary content relayout, UI flickering etc.
@protocol TabStripControllerDelegate
// Stripped down version of TabStripModelObserverBridge:selectTabWithContents.
- (void)onActivateTabWithContents:(content::WebContents*)contents;
// Stripped down version of TabStripModelObserverBridge:tabChangedWithContents.
- (void)onTabChanged:(TabStripModelObserver::TabChangeType)change
withContents:(content::WebContents*)contents;
// Stripped down version of TabStripModelObserverBridge:tabDetachedWithContents.
- (void)onTabDetachedWithContents:(content::WebContents*)contents;
@end
// A class that handles managing the tab strip in a browser window. It uses
// a supporting C++ bridge object to register for notifications from the
// TabStripModel. The Obj-C part of this class handles drag and drop and all
// the other Cocoa-y aspects.
//
// For a full description of the design, see
// http://www.chromium.org/developers/design-documents/tab-strip-mac
@interface TabStripController :
NSObject<TabControllerTarget,
URLDropTargetController> {
@private
base::scoped_nsobject<TabStripView> tabStripView_;
NSView* switchView_; // weak
base::scoped_nsobject<NSView> dragBlockingView_; // avoid bad window server
// drags
NewTabButton* newTabButton_; // weak, obtained from the nib.
// The controller that manages all the interactions of dragging tabs.
base::scoped_nsobject<TabStripDragController> dragController_;
// Tracks the newTabButton_ for rollovers.
base::scoped_nsobject<CrTrackingArea> newTabTrackingArea_;
scoped_ptr<TabStripModelObserverBridge> bridge_;
Browser* browser_; // weak
TabStripModel* tabStripModel_; // weak
// Delegate that is informed about tab state changes.
id<TabStripControllerDelegate> delegate_; // weak
// YES if the new tab button is currently displaying the hover image (if the
// mouse is currently over the button).
BOOL newTabButtonShowingHoverImage_;
// Access to the TabContentsControllers (which own the parent view
// for the toolbar and associated tab contents) given an index. Call
// |indexFromModelIndex:| to convert a |tabStripModel_| index to a
// |tabContentsArray_| index. Do NOT assume that the indices of
// |tabStripModel_| and this array are identical, this is e.g. not true while
// tabs are animating closed (closed tabs are removed from |tabStripModel_|
// immediately, but from |tabContentsArray_| only after their close animation
// has completed).
base::scoped_nsobject<NSMutableArray> tabContentsArray_;
// An array of TabControllers which manage the actual tab views. See note
// above |tabContentsArray_|. |tabContentsArray_| and |tabArray_| always
// contain objects belonging to the same tabs at the same indices.
base::scoped_nsobject<NSMutableArray> tabArray_;
// Set of TabControllers that are currently animating closed.
base::scoped_nsobject<NSMutableSet> closingControllers_;
// These values are only used during a drag, and override tab positioning.
TabView* placeholderTab_; // weak. Tab being dragged
NSRect placeholderFrame_; // Frame to use
NSRect droppedTabFrame_; // Initial frame of a dropped tab, for animation.
// Frame targets for all the current views.
// target frames are used because repeated requests to [NSView animator].
// aren't coalesced, so we store frames to avoid redundant calls.
base::scoped_nsobject<NSMutableDictionary> targetFrames_;
NSRect newTabTargetFrame_;
// If YES, do not show the new tab button during layout.
BOOL forceNewTabButtonHidden_;
// YES if we've successfully completed the initial layout. When this is
// NO, we probably don't want to do any animation because we're just coming
// into being.
BOOL initialLayoutComplete_;
// Width available for resizing the tabs (doesn't include the new tab
// button). Used to restrict the available width when closing many tabs at
// once to prevent them from resizing to fit the full width. If the entire
// width should be used, this will have a value of |kUseFullAvailableWidth|.
float availableResizeWidth_;
// A tracking area that's the size of the tab strip used to be notified
// when the mouse moves in the tab strip
base::scoped_nsobject<CrTrackingArea> trackingArea_;
TabView* hoveredTab_; // weak. Tab that the mouse is hovering over
// Array of subviews which are permanent (and which should never be removed),
// such as the new-tab button, but *not* the tabs themselves.
base::scoped_nsobject<NSMutableArray> permanentSubviews_;
// The default favicon, so we can use one copy for all buttons.
base::scoped_nsobject<NSImage> defaultFavicon_;
// The amount by which to indent the tabs on the sides (to make room for the
// red/yellow/green and incognito/fullscreen buttons).
CGFloat leftIndentForControls_;
CGFloat rightIndentForControls_;
// Is the mouse currently inside the strip;
BOOL mouseInside_;
// Helper for performing tab selection as a result of dragging over a tab.
scoped_ptr<HoverTabSelector> hoverTabSelector_;
// A container view for custom traffic light buttons, which must be manually
// added in fullscreen in 10.10+.
base::scoped_nsobject<NSView> customWindowControls_;
}
@property(nonatomic) CGFloat leftIndentForControls;
@property(nonatomic) CGFloat rightIndentForControls;
// Initialize the controller with a view and browser that contains
// everything else we'll need. |switchView| is the view whose contents get
// "switched" every time the user switches tabs. The children of this view
// will be released, so if you want them to stay around, make sure
// you have retained them.
// |delegate| is the one listening to filtered TabStripModelObserverBridge's
// events (see TabStripControllerDelegate for more details).
- (id)initWithView:(TabStripView*)view
switchView:(NSView*)switchView
browser:(Browser*)browser
delegate:(id<TabStripControllerDelegate>)delegate;
// Returns the model behind this controller.
- (TabStripModel*)tabStripModel;
// Returns all tab views.
- (NSArray*)tabViews;
// Return the view for the currently active tab.
- (NSView*)activeTabView;
// Find the model index based on the x coordinate of the placeholder. If there
// is no placeholder, this returns the end of the tab strip. Closing tabs are
// not considered in computing the index.
- (int)indexOfPlaceholder;
// Set the frame of |tabView|, also updates the internal frame dict.
- (void)setFrame:(NSRect)frame ofTabView:(NSView*)tabView;
// Move the given tab at index |from| in this window to the location of the
// current placeholder.
- (void)moveTabFromIndex:(NSInteger)from;
// Drop a given WebContents at |modelIndex|. Used when dragging from
// another window when we don't have access to the WebContents as part of our
// strip. |frame| is in the coordinate system of the tab strip view and
// represents where the user dropped the new tab so it can be animated into its
// correct location when the tab is added to the model. If the tab was pinned in
// its previous window, setting |pinned| to YES will propagate that state to the
// new window. Mini-tabs are either app or pinned tabs; the app state is stored
// by the |contents|, but the |pinned| state is the caller's responsibility.
// Setting |activate| to YES will make the new tab active.
- (void)dropWebContents:(content::WebContents*)contents
atIndex:(int)modelIndex
withFrame:(NSRect)frame
asPinnedTab:(BOOL)pinned
activate:(BOOL)activate;
// Returns the index of the subview |view|. Returns -1 if not present. Takes
// closing tabs into account such that this index will correctly match the tab
// model. If |view| is in the process of closing, returns -1, as closing tabs
// are no longer in the model.
- (NSInteger)modelIndexForTabView:(NSView*)view;
// Returns all selected tab views.
- (NSArray*)selectedViews;
// Return the view at a given index.
- (NSView*)viewAtIndex:(NSUInteger)index;
// Return the number of tab views in the tab strip. It's same as number of tabs
// in the model, except when a tab is closing, which will be counted in views
// count, but no longer in the model.
- (NSUInteger)viewsCount;
// Set the placeholder for a dragged tab, allowing the |frame| to be specified.
// This causes this tab to be rendered in an arbitrary position.
- (void)insertPlaceholderForTab:(TabView*)tab frame:(NSRect)frame;
// Returns whether a tab is being dragged within the tab strip.
- (BOOL)isDragSessionActive;
// Returns whether or not |tab| can still be fully seen in the tab strip or if
// its current position would cause it be obscured by things such as the edge
// of the window or the window decorations. Returns YES only if the entire tab
// is visible.
- (BOOL)isTabFullyVisible:(TabView*)tab;
// Show or hide the new tab button. The button is hidden immediately, but
// waits until the next call to |-layoutTabs| to show it again.
- (void)showNewTabButton:(BOOL)show;
// Force the tabs to rearrange themselves to reflect the current model.
- (void)layoutTabs;
- (void)layoutTabsWithoutAnimation;
// Are we in rapid (tab) closure mode? I.e., is a full layout deferred (while
// the user closes tabs)? Needed to overcome missing clicks during rapid tab
// closure.
- (BOOL)inRapidClosureMode;
// Returns YES if the user is allowed to drag tabs on the strip at this moment.
// For example, this returns NO if there are any pending tab close animtations.
- (BOOL)tabDraggingAllowed;
// Default height for tabs.
+ (CGFloat)defaultTabHeight;
// Default indentation for tabs (see |leftIndentForControls_|).
+ (CGFloat)defaultLeftIndentForControls;
// Returns the currently active TabContentsController.
- (TabContentsController*)activeTabContentsController;
// Adds custom traffic light buttons to the tab strip. Idempotent.
- (void)addCustomWindowControls;
// Removes custom traffic light buttons from the tab strip. Idempotent.
- (void)removeCustomWindowControls;
@end
@interface TabStripController(TestingAPI)
- (void)setTabTitle:(TabController*)tab
withContents:(content::WebContents*)contents;
@end
// Returns the parent view to use when showing a sheet for a given web contents.
NSView* GetSheetParentViewForWebContents(content::WebContents* web_contents);
// Returns the bounds to use when showing a sheet for a given parent view. This
// returns a rect in window coordinates.
NSRect GetSheetParentBoundsForParentView(NSView* view);
#endif // CHROME_BROWSER_UI_COCOA_TABS_TAB_STRIP_CONTROLLER_H_
|