Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / cocoa / tabs / tab_window_controller.mm
blobc3cc590b7d67b83b2fd86084d601d824f4ca187d
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.
5 #import "chrome/browser/ui/cocoa/tabs/tab_window_controller.h"
7 #include "base/logging.h"
8 #import "chrome/browser/ui/cocoa/fast_resize_view.h"
9 #import "chrome/browser/ui/cocoa/framed_browser_window.h"
10 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h"
11 #import "chrome/browser/ui/cocoa/themed_window.h"
12 #import "ui/base/cocoa/focus_tracker.h"
13 #include "ui/base/theme_provider.h"
15 @interface TabWindowController(PRIVATE)
16 - (void)setUseOverlay:(BOOL)useOverlay;
17 @end
19 @interface TabWindowOverlayWindow : NSWindow
20 @end
22 @implementation TabWindowOverlayWindow
24 - (ui::ThemeProvider*)themeProvider {
25   if ([self parentWindow])
26     return [[[self parentWindow] windowController] themeProvider];
27   return NULL;
30 - (ThemedWindowStyle)themedWindowStyle {
31   if ([self parentWindow])
32     return [[[self parentWindow] windowController] themedWindowStyle];
33   return NO;
36 - (NSPoint)themeImagePositionForAlignment:(ThemeImageAlignment)alignment {
37   if ([self parentWindow]) {
38     return [[[self parentWindow] windowController]
39         themeImagePositionForAlignment:alignment];
40   }
41   return NSZeroPoint;
44 @end
46 @implementation TabWindowController
48 - (id)initTabWindowControllerWithTabStrip:(BOOL)hasTabStrip {
49   NSRect contentRect = NSMakeRect(60, 229, 750, 600);
50   base::scoped_nsobject<FramedBrowserWindow> window(
51       [[FramedBrowserWindow alloc] initWithContentRect:contentRect
52                                            hasTabStrip:hasTabStrip]);
53   [window setReleasedWhenClosed:YES];
54   [window setAutorecalculatesKeyViewLoop:YES];
56   if ((self = [super initWithWindow:window])) {
57     [[self window] setDelegate:self];
59     tabContentArea_.reset([[FastResizeView alloc] initWithFrame:
60         NSMakeRect(0, 0, 750, 600)]);
61     [tabContentArea_ setAutoresizingMask:NSViewWidthSizable |
62                                          NSViewHeightSizable];
63     [[[self window] contentView] addSubview:tabContentArea_];
65     tabStripView_.reset([[TabStripView alloc] initWithFrame:
66         NSMakeRect(0, 0, 750, 37)]);
67     [tabStripView_ setAutoresizingMask:NSViewWidthSizable |
68                                        NSViewMinYMargin];
69     if (hasTabStrip)
70       [self addTabStripToWindow];
71   }
72   return self;
75 - (TabStripView*)tabStripView {
76   return tabStripView_;
79 - (FastResizeView*)tabContentArea {
80   return tabContentArea_;
83 // Add the top tab strop to the window, above the content box and add it to the
84 // view hierarchy as a sibling of the content view so it can overlap with the
85 // window frame.
86 - (void)addTabStripToWindow {
87   // The frame doesn't matter. This class relies on subclasses to do tab strip
88   // layout.
89   NSView* contentParent = [[[self window] contentView] superview];
90   [contentParent addSubview:tabStripView_];
93 - (void)removeOverlay {
94   [self setUseOverlay:NO];
95   if (closeDeferred_) {
96     // See comment in BrowserWindowCocoa::Close() about orderOut:.
97     [[self window] orderOut:self];
98     [[self window] performClose:self];  // Autoreleases the controller.
99   }
102 - (void)showOverlay {
103   [self setUseOverlay:YES];
106 // If |useOverlay| is YES, creates a new overlay window and puts the tab strip
107 // and the content area inside of it. This allows it to have a different opacity
108 // from the title bar. If NO, returns everything to the previous state and
109 // destroys the overlay window until it's needed again. The tab strip and window
110 // contents are returned to the original window.
111 - (void)setUseOverlay:(BOOL)useOverlay {
112   [NSObject cancelPreviousPerformRequestsWithTarget:self
113                                            selector:@selector(removeOverlay)
114                                              object:nil];
115   NSWindow* window = [self window];
116   if (useOverlay && !overlayWindow_) {
117     DCHECK(!originalContentView_);
119     overlayWindow_ = [[TabWindowOverlayWindow alloc]
120                          initWithContentRect:[window frame]
121                                    styleMask:NSBorderlessWindowMask
122                                      backing:NSBackingStoreBuffered
123                                        defer:YES];
124     [overlayWindow_ setTitle:@"overlay"];
125     [overlayWindow_ setBackgroundColor:[NSColor clearColor]];
126     [overlayWindow_ setOpaque:NO];
127     [overlayWindow_ setDelegate:self];
129     originalContentView_ = [window contentView];
130     [window addChildWindow:overlayWindow_ ordered:NSWindowAbove];
132     // Explicitly set the responder to be nil here (for restoring later).
133     // If the first responder were to be left non-nil here then
134     // [RenderWidgethostViewCocoa resignFirstResponder] would be called,
135     // followed by RenderWidgetHost::Blur(), which would result in an unexpected
136     // loss of focus.
137     focusBeforeOverlay_.reset([[FocusTracker alloc] initWithWindow:window]);
138     [window makeFirstResponder:nil];
140     // Move the original window's tab strip view and content view to the overlay
141     // window. The content view is added as a subview of the overlay window's
142     // content view (rather than using setContentView:) because the overlay
143     // window has a different content size (due to it being borderless).
144     [[[overlayWindow_ contentView] superview] addSubview:[self tabStripView]];
145     [[overlayWindow_ contentView] addSubview:originalContentView_];
147     [overlayWindow_ orderFront:nil];
148   } else if (!useOverlay && overlayWindow_) {
149     DCHECK(originalContentView_);
151     // Return the original window's tab strip view and content view to their
152     // places. The TabStripView always needs to be in front of the window's
153     // content view and therefore it should always be added after the content
154     // view is set.
155     [window setContentView:originalContentView_];
156     [[[window contentView] superview] addSubview:[self tabStripView]];
157     [[[window contentView] superview] updateTrackingAreas];
159     [focusBeforeOverlay_ restoreFocusInWindow:window];
160     focusBeforeOverlay_.reset();
162     [window display];
163     [window removeChildWindow:overlayWindow_];
165     [overlayWindow_ orderOut:nil];
166     [overlayWindow_ release];
167     overlayWindow_ = nil;
168     originalContentView_ = nil;
169   } else {
170     NOTREACHED();
171   }
174 - (NSWindow*)overlayWindow {
175   return overlayWindow_;
178 - (BOOL)shouldConstrainFrameRect {
179   // If we currently have an overlay window, do not attempt to change the
180   // window's size, as our overlay window doesn't know how to resize properly.
181   return overlayWindow_ == nil;
184 - (BOOL)canReceiveFrom:(TabWindowController*)source {
185   // subclass must implement
186   NOTIMPLEMENTED();
187   return NO;
190 - (void)moveTabView:(NSView*)view
191      fromController:(TabWindowController*)dragController {
192   NOTIMPLEMENTED();
195 - (NSView*)activeTabView {
196   NOTIMPLEMENTED();
197   return nil;
200 - (void)layoutTabs {
201   // subclass must implement
202   NOTIMPLEMENTED();
205 - (TabWindowController*)detachTabToNewWindow:(TabView*)tabView {
206   // subclass must implement
207   NOTIMPLEMENTED();
208   return NULL;
211 - (void)insertPlaceholderForTab:(TabView*)tab frame:(NSRect)frame {
212   [self showNewTabButton:NO];
215 - (void)removePlaceholder {
216   [self showNewTabButton:YES];
219 - (BOOL)isDragSessionActive {
220   NOTIMPLEMENTED();
221   return NO;
224 - (BOOL)tabDraggingAllowed {
225   return YES;
228 - (BOOL)tabTearingAllowed {
229   return YES;
232 - (BOOL)windowMovementAllowed {
233   return YES;
236 - (BOOL)isTabFullyVisible:(TabView*)tab {
237   // Subclasses should implement this, but it's not necessary.
238   return YES;
241 - (void)showNewTabButton:(BOOL)show {
242   // subclass must implement
243   NOTIMPLEMENTED();
246 - (void)detachTabView:(NSView*)view {
247   // subclass must implement
248   NOTIMPLEMENTED();
251 - (NSInteger)numberOfTabs {
252   // subclass must implement
253   NOTIMPLEMENTED();
254   return 0;
257 - (BOOL)hasLiveTabs {
258   // subclass must implement
259   NOTIMPLEMENTED();
260   return NO;
263 - (NSString*)activeTabTitle {
264   // subclass must implement
265   NOTIMPLEMENTED();
266   return @"";
269 - (BOOL)hasTabStrip {
270   // Subclasses should implement this.
271   NOTIMPLEMENTED();
272   return YES;
275 - (BOOL)isTabDraggable:(NSView*)tabView {
276   // Subclasses should implement this.
277   NOTIMPLEMENTED();
278   return YES;
281 // Tell the window that it needs to call performClose: as soon as the current
282 // drag is complete. This prevents a window (and its overlay) from going away
283 // during a drag.
284 - (void)deferPerformClose {
285   closeDeferred_ = YES;
288 // Called when the size of the window content area has changed. Override to
289 // position specific views. Base class implementation does nothing.
290 - (void)layoutSubviews {
291   NOTIMPLEMENTED();
294 @end