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 tab 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*)detachTabToNewWindow:(TabView*)tabView;
66
67// Make room in the tab strip for |tab| at the given x coordinate. Will hide the
68// new tab button while there's a placeholder. Subclasses need to call the
69// superclass implementation.
70- (void)insertPlaceholderForTab:(TabView*)tab frame:(NSRect)frame;
71
72// Removes the placeholder installed by |-insertPlaceholderForTab:atLocation:|
73// and restores the new tab button. Subclasses need to call the superclass
74// implementation.
75- (void)removePlaceholder;
76
77// Returns whether one of the window's tabs is being dragged.
78- (BOOL)isDragSessionActive;
79
80// The follow return YES if tab dragging/tab tearing (off the tab strip)/window
81// movement is currently allowed. Any number of things can choose to disable it,
82// such as pending animations. The default implementations always return YES.
83// Subclasses should override as appropriate.
84- (BOOL)tabDraggingAllowed;
85- (BOOL)tabTearingAllowed;
86- (BOOL)windowMovementAllowed;
87
88// Show or hide the new tab button. The button is hidden immediately, but
89// waits until the next call to |-layoutTabs| to show it again.
90- (void)showNewTabButton:(BOOL)show;
91
92// Returns whether or not |tab| can still be fully seen in the tab strip or if
93// its current position would cause it be obscured by things such as the edge
94// of the window or the window decorations. Returns YES only if the entire tab
95// is visible. The default implementation always returns YES.
96- (BOOL)isTabFullyVisible:(TabView*)tab;
97
98// Called to check if the receiver can receive dragged tabs from
99// source.  Return YES if so.  The default implementation returns NO.
100- (BOOL)canReceiveFrom:(TabWindowController*)source;
101
102// Move a given tab view to the location of the current placeholder. If there is
103// no placeholder, it will go at the end. |controller| is the window controller
104// of a tab being dropped from a different window. It will be nil if the drag is
105// within the window, otherwise the tab is removed from that window before being
106// placed into this one. The implementation will call |-removePlaceholder| since
107// the drag is now complete.  This also calls |-layoutTabs| internally so
108// clients do not need to call it again.
109- (void)moveTabView:(NSView*)view
110     fromController:(TabWindowController*)controller;
111
112// Number of tabs in the tab strip. Useful, for example, to know if we're
113// dragging the only tab in the window. This includes pinned tabs (both live
114// and not).
115- (NSInteger)numberOfTabs;
116
117// YES if there are tabs in the tab strip which have content, allowing for
118// the notion of tabs in the tab strip that are placeholders but currently have
119// no content.
120- (BOOL)hasLiveTabs;
121
122// Return the view of the active tab.
123- (NSView*)activeTabView;
124
125// The title of the active tab.
126- (NSString*)activeTabTitle;
127
128// Called to check whether or not this controller's window has a tab strip (YES
129// if it does, NO otherwise). The default implementation returns YES.
130- (BOOL)hasTabStrip;
131
132// Gets whether a particular tab is draggable between windows.
133- (BOOL)isTabDraggable:(NSView*)tabView;
134
135// Tell the window that it needs to call performClose: as soon as the current
136// drag is complete. This prevents a window (and its overlay) from going away
137// during a drag.
138- (void)deferPerformClose;
139
140@end
141
142@interface TabWindowController(ProtectedMethods)
143// Tells the tab strip to forget about this tab in preparation for it being
144// put into a different tab strip, such as during a drop on another window.
145- (void)detachTabView:(NSView*)view;
146
147// Called when the size of the window content area has changed. Override to
148// position specific views. Base class implementation does nothing.
149- (void)layoutSubviews;
150@end
151
152#endif  // CHROME_BROWSER_UI_COCOA_TABS_TAB_WINDOW_CONTROLLER_H_
153