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_TABS_TAB_WINDOW_CONTROLLER_H_ 6 #define CHROME_BROWSER_UI_COCOA_TABS_TAB_WINDOW_CONTROLLER_H_ 7 8 // A class acting as the Objective-C window controller for a window that has 9 // tabs which can be dragged around. Tabs can be re-arranged within the same 10 // window or dragged into other TabWindowController windows. This class doesn't 11 // know anything about the actual tab implementation or model, as that is fairly 12 // application-specific. It only provides an API to be overridden by subclasses 13 // to fill in the details. 14 15 #import <Cocoa/Cocoa.h> 16 17 #include "base/mac/scoped_nsobject.h" 18 19 @class FastResizeView; 20 @class FocusTracker; 21 @class TabStripView; 22 @class TabView; 23 24 @interface TabWindowController : NSWindowController<NSWindowDelegate> { 25 @private 26 base::scoped_nsobject<FastResizeView> tabContentArea_; 27 base::scoped_nsobject<TabStripView> tabStripView_; 28 29 // The child window used during dragging to achieve the opacity tricks. 30 NSWindow* overlayWindow_; 31 32 // The contentView of the original window that is moved (for the duration 33 // of the drag) to the |overlayWindow_|. 34 NSView* originalContentView_; // weak 35 36 base::scoped_nsobject<FocusTracker> focusBeforeOverlay_; 37 BOOL closeDeferred_; // If YES, call performClose: in removeOverlay:. 38 } 39 @property(readonly, nonatomic) TabStripView* tabStripView; 40 @property(readonly, nonatomic) FastResizeView* tabContentArea; 41 42 // This is the designated initializer for this class. 43 - (id)initTabWindowControllerWithTabStrip:(BOOL)hasTabStrip; 44 45 // Used during tab dragging to turn on/off the overlay window when a tab 46 // is torn off. If -deferPerformClose (below) is used, -removeOverlay will 47 // cause the controller to be autoreleased before returning. 48 - (void)showOverlay; 49 - (void)removeOverlay; 50 - (NSWindow*)overlayWindow; 51 52 // Returns YES if it is ok to constrain the window's frame to fit the screen. 53 - (BOOL)shouldConstrainFrameRect; 54 55 // A collection of methods, stubbed out in this base class, that provide 56 // the implementation of tab dragging based on whatever model is most 57 // appropriate. 58 59 // Layout the tabs based on the current ordering of the model. 60 - (void)layoutTabs; 61 62 // Creates a new window by pulling the given tabs out and placing it in 63 // the new window. Returns the controller for the new window. The size of the 64 // new window will be the same size as this window. 65 - (TabWindowController*)detachTabsToNewWindow:(NSArray*)tabViews 66 draggedTab:(NSView*)draggedTab; 67 68 // Make room in the tab strip for |tab| at the given x coordinate. Will hide the 69 // new tab button while there's a placeholder. Subclasses need to call the 70 // superclass implementation. 71 - (void)insertPlaceholderForTab:(TabView*)tab frame:(NSRect)frame; 72 73 // Removes the placeholder installed by |-insertPlaceholderForTab:atLocation:| 74 // and restores the new tab button. Subclasses need to call the superclass 75 // implementation. 76 - (void)removePlaceholder; 77 78 // Returns whether one of the window's tabs is being dragged. 79 - (BOOL)isDragSessionActive; 80 81 // The follow return YES if tab dragging/tab tearing (off the tab strip)/window 82 // movement is currently allowed. Any number of things can choose to disable it, 83 // such as pending animations. The default implementations always return YES. 84 // Subclasses should override as appropriate. 85 - (BOOL)tabDraggingAllowed; 86 - (BOOL)tabTearingAllowed; 87 - (BOOL)windowMovementAllowed; 88 89 // Show or hide the new tab button. The button is hidden immediately, but 90 // waits until the next call to |-layoutTabs| to show it again. 91 - (void)showNewTabButton:(BOOL)show; 92 93 // Returns whether or not |tab| can still be fully seen in the tab strip or if 94 // its current position would cause it be obscured by things such as the edge 95 // of the window or the window decorations. Returns YES only if the entire tab 96 // is visible. The default implementation always returns YES. 97 - (BOOL)isTabFullyVisible:(TabView*)tab; 98 99 // Called to check if the receiver can receive dragged tabs from 100 // source. Return YES if so. The default implementation returns NO. 101 - (BOOL)canReceiveFrom:(TabWindowController*)source; 102 103 // Move given tab views to the location of the current placeholder. If there is 104 // no placeholder, it will go at the end. |controller| is the window controller 105 // of a tab being dropped from a different window. It will be nil if the drag is 106 // within the window, otherwise the tab is removed from that window before being 107 // placed into this one. The implementation will call |-removePlaceholder| since 108 // the drag is now complete. This also calls |-layoutTabs| internally so 109 // clients do not need to call it again. 110 - (void)moveTabViews:(NSArray*)views 111 fromController:(TabWindowController*)controller; 112 113 // Number of tabs in the tab strip. Useful, for example, to know if we're 114 // dragging the only tab in the window. This includes pinned tabs (both live 115 // and not). 116 - (NSInteger)numberOfTabs; 117 118 // YES if there are tabs in the tab strip which have content, allowing for 119 // the notion of tabs in the tab strip that are placeholders but currently have 120 // no content. 121 - (BOOL)hasLiveTabs; 122 123 // Returns all tab views. 124 - (NSArray*)tabViews; 125 126 // Return the view of the active tab. 127 - (NSView*)activeTabView; 128 129 // The title of the active tab. 130 - (NSString*)activeTabTitle; 131 132 // Called to check whether or not this controller's window has a tab strip (YES 133 // if it does, NO otherwise). The default implementation returns YES. 134 - (BOOL)hasTabStrip; 135 136 // Gets whether a particular tab is draggable between windows. 137 - (BOOL)isTabDraggable:(NSView*)tabView; 138 139 // Tell the window that it needs to call performClose: as soon as the current 140 // drag is complete. This prevents a window (and its overlay) from going away 141 // during a drag. 142 - (void)deferPerformClose; 143 144 // There are 2 view hierarchy constraints that must be enforced: 145 // - The tab strip must be above the content view. 146 // - The tab strip must be below the traffic lights. 147 // AppKit does not enforce these constraints, because it assumes that Chrome 148 // does not mess with the NSThemeFrame. Chrome must manually enforce these 149 // constraints. 150 // 151 // Immediately after creation of the window, or after the window's content view 152 // is changed, the content view must be moved to the back. 153 - (void)moveContentViewToBack:(NSView*)contentView; 154 155 // The tab strip should always be inserted directly above the content view. 156 - (void)insertTabStripView:(NSView*)tabStripView intoWindow:(NSWindow*)window; 157 158 @end 159 160 @interface TabWindowController(ProtectedMethods) 161 // Tells the tab strip to forget about this tab in preparation for it being 162 // put into a different tab strip, such as during a drop on another window. 163 - (void)detachTabView:(NSView*)view; 164 165 // Called when the size of the window content area has changed. Override to 166 // position specific views. Base class implementation does nothing. 167 - (void)layoutSubviews; 168 @end 169 170 #endif // CHROME_BROWSER_UI_COCOA_TABS_TAB_WINDOW_CONTROLLER_H_ 171