1 // Copyright (c) 2011 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 #pragma once 8 9 // A class acting as the Objective-C window controller for a window that has 10 // tabs which can be dragged around. Tabs can be re-arranged within the same 11 // window or dragged into other TabWindowController windows. This class doesn't 12 // know anything about the actual tab implementation or model, as that is fairly 13 // application-specific. It only provides an API to be overridden by subclasses 14 // to fill in the details. 15 // 16 // This assumes that there will be a view in the nib, connected to 17 // |tabContentArea_|, that indicates the content that it switched when switching 18 // between tabs. It needs to be a regular NSView, not something like an NSBox 19 // because the TabStripController makes certain assumptions about how it can 20 // swap out subviews. 21 // 22 // The tab strip can exist in different orientations and window locations, 23 // depending on the return value of -usesVerticalTabs. If NO (the default), 24 // the tab strip is placed outside the window's content area, overlapping the 25 // title area and window controls and will be stretched to fill the width 26 // of the window. If YES, the tab strip is vertical and lives within the 27 // window's content area. It will be stretched to fill the window's height. 28 29 #import <Cocoa/Cocoa.h> 30 31 #import "base/mac/cocoa_protocols.h" 32 #include "base/memory/scoped_nsobject.h" 33 34 @class FastResizeView; 35 @class FocusTracker; 36 @class TabStripView; 37 @class TabView; 38 39 @interface TabWindowController : NSWindowController<NSWindowDelegate> { 40 @private 41 IBOutlet FastResizeView* tabContentArea_; 42 // TODO(pinkerton): Figure out a better way to initialize one or the other 43 // w/out needing both to be in the nib. 44 IBOutlet TabStripView* topTabStripView_; 45 IBOutlet TabStripView* sideTabStripView_; 46 NSWindow* overlayWindow_; // Used during dragging for window opacity tricks 47 NSView* cachedContentView_; // Used during dragging for identifying which 48 // view is the proper content area in the overlay 49 // (weak) 50 scoped_nsobject<FocusTracker> focusBeforeOverlay_; 51 scoped_nsobject<NSMutableSet> lockedTabs_; 52 BOOL closeDeferred_; // If YES, call performClose: in removeOverlay:. 53 // Difference between height of window content area and height of the 54 // |tabContentArea_|. Calculated when the window is loaded from the nib and 55 // cached in order to restore the delta when switching tab modes. 56 CGFloat contentAreaHeightDelta_; 57 } 58 @property(readonly, nonatomic) TabStripView* tabStripView; 59 @property(readonly, nonatomic) FastResizeView* tabContentArea; 60 61 // Used during tab dragging to turn on/off the overlay window when a tab 62 // is torn off. If -deferPerformClose (below) is used, -removeOverlay will 63 // cause the controller to be autoreleased before returning. 64 - (void)showOverlay; 65 - (void)removeOverlay; 66 - (NSWindow*)overlayWindow; 67 68 // Returns YES if it is ok to constrain the window's frame to fit the screen. 69 - (BOOL)shouldConstrainFrameRect; 70 71 // A collection of methods, stubbed out in this base class, that provide 72 // the implementation of tab dragging based on whatever model is most 73 // appropriate. 74 75 // Layout the tabs based on the current ordering of the model. 76 - (void)layoutTabs; 77 78 // Creates a new window by pulling the given tab out and placing it in 79 // the new window. Returns the controller for the new window. The size of the 80 // new window will be the same size as this window. 81 - (TabWindowController*)detachTabToNewWindow:(TabView*)tabView; 82 83 // Make room in the tab strip for |tab| at the given x coordinate. Will hide the 84 // new tab button while there's a placeholder. Subclasses need to call the 85 // superclass implementation. 86 - (void)insertPlaceholderForTab:(TabView*)tab 87 frame:(NSRect)frame 88 yStretchiness:(CGFloat)yStretchiness; 89 90 // Removes the placeholder installed by |-insertPlaceholderForTab:atLocation:| 91 // and restores the new tab button. Subclasses need to call the superclass 92 // implementation. 93 - (void)removePlaceholder; 94 95 // Returns whether one of the window's tabs is being dragged. 96 - (BOOL)isDragSessionActive; 97 98 // The follow return YES if tab dragging/tab tearing (off the tab strip)/window 99 // movement is currently allowed. Any number of things can choose to disable it, 100 // such as pending animations. The default implementations always return YES. 101 // Subclasses should override as appropriate. 102 - (BOOL)tabDraggingAllowed; 103 - (BOOL)tabTearingAllowed; 104 - (BOOL)windowMovementAllowed; 105 106 // Show or hide the new tab button. The button is hidden immediately, but 107 // waits until the next call to |-layoutTabs| to show it again. 108 - (void)showNewTabButton:(BOOL)show; 109 110 // Returns whether or not |tab| can still be fully seen in the tab strip or if 111 // its current position would cause it be obscured by things such as the edge 112 // of the window or the window decorations. Returns YES only if the entire tab 113 // is visible. The default implementation always returns YES. 114 - (BOOL)isTabFullyVisible:(TabView*)tab; 115 116 // Called to check if the receiver can receive dragged tabs from 117 // source. Return YES if so. The default implementation returns NO. 118 - (BOOL)canReceiveFrom:(TabWindowController*)source; 119 120 // Move a given tab view to the location of the current placeholder. If there is 121 // no placeholder, it will go at the end. |controller| is the window controller 122 // of a tab being dropped from a different window. It will be nil if the drag is 123 // within the window, otherwise the tab is removed from that window before being 124 // placed into this one. The implementation will call |-removePlaceholder| since 125 // the drag is now complete. This also calls |-layoutTabs| internally so 126 // clients do not need to call it again. 127 - (void)moveTabView:(NSView*)view 128 fromController:(TabWindowController*)controller; 129 130 // Number of tabs in the tab strip. Useful, for example, to know if we're 131 // dragging the only tab in the window. This includes pinned tabs (both live 132 // and not). 133 - (NSInteger)numberOfTabs; 134 135 // YES if there are tabs in the tab strip which have content, allowing for 136 // the notion of tabs in the tab strip that are placeholders but currently have 137 // no content. 138 - (BOOL)hasLiveTabs; 139 140 // Return the view of the selected tab. 141 - (NSView *)selectedTabView; 142 143 // The title of the selected tab. 144 - (NSString*)selectedTabTitle; 145 146 // Called to check whether or not this controller's window has a tab strip (YES 147 // if it does, NO otherwise). The default implementation returns YES. 148 - (BOOL)hasTabStrip; 149 150 // Returns YES if the tab strip lives in the window content area alongside the 151 // tab contents. Returns NO if the tab strip is outside the window content 152 // area, along the top of the window. 153 - (BOOL)useVerticalTabs; 154 155 // Get/set whether a particular tab is draggable between windows. 156 - (BOOL)isTabDraggable:(NSView*)tabView; 157 - (void)setTab:(NSView*)tabView isDraggable:(BOOL)draggable; 158 159 // Tell the window that it needs to call performClose: as soon as the current 160 // drag is complete. This prevents a window (and its overlay) from going away 161 // during a drag. 162 - (void)deferPerformClose; 163 164 @end 165 166 @interface TabWindowController(ProtectedMethods) 167 // Tells the tab strip to forget about this tab in preparation for it being 168 // put into a different tab strip, such as during a drop on another window. 169 - (void)detachTabView:(NSView*)view; 170 171 // Toggles from one display mode of the tab strip to another. Will automatically 172 // call -layoutSubviews to reposition other content. 173 - (void)toggleTabStripDisplayMode; 174 175 // Called when the size of the window content area has changed. Override to 176 // position specific views. Base class implementation does nothing. 177 - (void)layoutSubviews; 178 @end 179 180 #endif // CHROME_BROWSER_UI_COCOA_TABS_TAB_WINDOW_CONTROLLER_H_ 181