• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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