123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- // Copyright (c) 2010 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE-chromium file.
- #import "CTTabWindowController.h"
- #import "CTTabStripView.h"
- #import "common.h"
- #if VERSION_DMG
- #import <PDF_Master-Swift.h>
- #else
- #import <PDF_Master-Swift.h>
- #endif
- @interface CTTabWindowController(PRIVATE)
- - (void)setUseOverlay:(BOOL)useOverlay;
- @end
- @interface TabWindowOverlayWindow : NSWindow
- @end
- @implementation TabWindowOverlayWindow
- - (NSPoint)themePatternPhase {
- return NSZeroPoint;
- }
- @end
- @implementation CTTabWindowController {
- @private
- IBOutlet NSView* tabContentArea_;
- // TODO(pinkerton): Figure out a better way to initialize one or the other
- // w/out needing both to be in the nib.
- IBOutlet CTTabStripView* topTabStripView_;
- IBOutlet CTTabStripView* sideTabStripView_;
- NSWindow* overlayWindow_; // Used during dragging for window opacity tricks
- __weak NSView* cachedContentView_; // Used during dragging for identifying which
- // view is the proper content area in the overlay
- // (weak)
- NSMutableSet *lockedTabs_;
- BOOL closeDeferred_; // If YES, call performClose: in removeOverlay:.
- // Difference between height of window content area and height of the
- // |tabContentArea_|. Calculated when the window is loaded from the nib and
- // cached in order to restore the delta when switching tab modes.
- CGFloat contentAreaHeightDelta_;
- BOOL enableTransparentContent_;
- }
- @synthesize tabContentArea = tabContentArea_;
- - (id)initWithWindow:(NSWindow*)window {
- if ((self = [super initWithWindow:window]) != nil) {
- lockedTabs_ = [[NSMutableSet alloc] initWithCapacity:10];
- }
- return self;
- }
- - (void)dealloc {
- if (overlayWindow_) {
- [self setUseOverlay:NO];
- }
- }
- // Add the top tab strop to the window, above the content box and add it to the
- // view hierarchy as a sibling of the content view so it can overlap with the
- // window frame.
- - (void)addTopTabStripToWindow {
- CGFloat rightOffst = NSWidth(self.rightStripView.frame);
- NSRect contentFrame = [tabContentArea_ frame];
- NSRect rightFrame =
- NSMakeRect(NSWidth(contentFrame) - rightOffst, NSMaxY(contentFrame),
- rightOffst,
- NSHeight([topTabStripView_ frame]));
- NSRect tabFrame =
- NSMakeRect(topTabStripView_.frame.origin.x, NSMaxY(contentFrame),
- NSWidth(contentFrame)-rightOffst,
- NSHeight([topTabStripView_ frame]));
- [topTabStripView_ setFrame:tabFrame];
- [self.rightStripView setFrame:rightFrame];
- NSView* contentParent = [[[self window] contentView] superview];
- [contentParent addSubview:topTabStripView_ positioned:NSWindowBelow relativeTo:nil];
- [contentParent addSubview:self.rightStripView positioned:NSWindowAbove relativeTo:nil];
- }
- - (void)windowDidLoad {
- // Cache the difference in height between the window content area and the
- // tab content area.
- NSRect tabFrame = [tabContentArea_ frame];
- NSRect contentFrame = [[[self window] contentView] frame];
- contentAreaHeightDelta_ = NSHeight(contentFrame) - NSHeight(tabFrame);
-
- if ([self hasTabStrip]) {
- [self addTopTabStripToWindow];
- } else {
- // No top tabstrip so remove the tabContentArea offset.
- tabFrame.size.height = contentFrame.size.height;
- [tabContentArea_ setFrame:tabFrame];
- }
- }
- // Return the appropriate tab strip based on whether or not side tabs are
- // enabled.
- - (CTTabStripView*)tabStripView {
- return topTabStripView_;
- }
- - (void)removeOverlay {
- [self setUseOverlay:NO];
- if (closeDeferred_) {
- // See comment in BrowserWindowCocoa::Close() about orderOut:.
- [[self window] orderOut:self];
- [[self window] performClose:self]; // Autoreleases the controller.
- }
- }
- - (void)showOverlay {
- [self setUseOverlay:YES];
- }
- // if |useOverlay| is true, we're moving views into the overlay's content
- // area. If false, we're moving out of the overlay back into the window's
- // content.
- - (void)moveViewsBetweenWindowAndOverlay:(BOOL)useOverlay {
- if (useOverlay) {
- [[self tabStripView] setAllowGradient:NO];
- [[[overlayWindow_ contentView] superview] addSubview:[self tabStripView]];
- // Add the original window's content view as a subview of the overlay
- // window's content view. We cannot simply use setContentView: here because
- // the overlay window has a different content size (due to it being
- // borderless).
- [[overlayWindow_ contentView] addSubview:cachedContentView_];
- } else {
- [[self window] setContentView:cachedContentView_];
- // The CTTabStripView always needs to be in front of the window's content
- // view and therefore it should always be added after the content view is
- // set.
- [[self tabStripView] setAllowGradient:enableTransparentContent_];
- [[[[self window] contentView] superview] addSubview:[self tabStripView]
- positioned:NSWindowBelow
- relativeTo:nil];
- [[[[self window] contentView] superview] updateTrackingAreas];
- }
- }
- -(void)willStartTearingTab {
- }
- -(void)willEndTearingTab {
- }
- -(void)didEndTearingTab {
- }
- // If |useOverlay| is YES, creates a new overlay window and puts the tab strip
- // and the content area inside of it. This allows it to have a different opacity
- // from the title bar. If NO, returns everything to the previous state and
- // destroys the overlay window until it's needed again. The tab strip and window
- // contents are returned to the original window.
- - (void)setUseOverlay:(BOOL)useOverlay {
- [NSObject cancelPreviousPerformRequestsWithTarget:self
- selector:@selector(removeOverlay)
- object:nil];
- NSWindow* window = [self window];
- if (useOverlay && !overlayWindow_) {
- DCHECK(!cachedContentView_);
- overlayWindow_ = [[TabWindowOverlayWindow alloc] initWithContentRect:[window frame]
- styleMask:NSBorderlessWindowMask
- backing:NSBackingStoreBuffered
- defer:YES];
- [overlayWindow_ setTitle:@"overlay"];
- [overlayWindow_ setBackgroundColor:[NSColor clearColor]];
- [overlayWindow_ setOpaque:NO];
- [overlayWindow_ setDelegate:self];
- cachedContentView_ = [window contentView];
- [window addChildWindow:overlayWindow_ ordered:NSWindowAbove];
- [window makeFirstResponder:nil];
- [self moveViewsBetweenWindowAndOverlay:useOverlay];
- [overlayWindow_ orderFront:nil];
- } else if (!useOverlay && overlayWindow_) {
- DCHECK(cachedContentView_);
- [window setContentView:cachedContentView_];
- [self moveViewsBetweenWindowAndOverlay:useOverlay];
- [window makeFirstResponder:cachedContentView_];
- [window display];
- [window removeChildWindow:overlayWindow_];
- [overlayWindow_ orderOut:nil];
- overlayWindow_ = nil;
- cachedContentView_ = nil;
- } else {
- NOTREACHED();
- }
- }
- - (NSWindow*)overlayWindow {
- return overlayWindow_;
- }
- - (BOOL)shouldConstrainFrameRect {
- // If we currently have an overlay window, do not attempt to change the
- // window's size, as our overlay window doesn't know how to resize properly.
- return overlayWindow_ == nil;
- }
- - (BOOL)canReceiveFrom:(CTTabWindowController*)source {
- // subclass must implement
- NOTIMPLEMENTED();
- return NO;
- }
- - (void)moveTabView:(NSView*)view
- fromController:(CTTabWindowController*)dragController {
- NOTIMPLEMENTED();
- }
- - (NSView*)activeTabView {
- NOTIMPLEMENTED();
- return nil;
- }
- - (void)layoutTabs {
- // subclass must implement
- NOTIMPLEMENTED();
- }
- - (CTTabWindowController*)detachTabToNewWindow:(CTTabView*)tabView {
- // subclass must implement
- NOTIMPLEMENTED();
- return NULL;
- }
- - (void)insertPlaceholderForTab:(CTTabView*)tab
- frame:(NSRect)frame {
- self.showsNewTabButton = NO;
- }
- - (void)removePlaceholder {
- self.showsNewTabButton = YES;
- }
- - (BOOL)tabDraggingAllowed {
- return YES;
- }
- - (BOOL)tabTearingAllowed {
- return YES;
- }
- - (BOOL)windowMovementAllowed {
- return YES;
- }
- - (BOOL)isTabFullyVisible:(CTTabView*)tab {
- // Subclasses should implement this, but it's not necessary.
- return YES;
- }
- - (void)setShowsNewTabButton:(BOOL)show {
- // subclass must implement
- NOTIMPLEMENTED();
- }
- - (BOOL)showsNewTabButton {
- // subclass must implement
- NOTIMPLEMENTED();
- }
- - (void)setEnableTransparentContent:(BOOL)enable {
- enableTransparentContent_ = enable;
- if (enableTransparentContent_) {
- [self.window setOpaque:NO];
- } else {
- [self.window setOpaque:YES];
- }
- if (!overlayWindow_) {
- [topTabStripView_ setAllowGradient:enable];
- }
- }
- - (BOOL)enableTransparentContent {
- return enableTransparentContent_;
- }
- - (void)detachTabView:(NSView*)view {
- // subclass must implement
- NOTIMPLEMENTED();
- }
- - (NSInteger)numberOfTabs {
- // subclass must implement
- NOTIMPLEMENTED();
- return 0;
- }
- - (BOOL)hasLiveTabs {
- // subclass must implement
- NOTIMPLEMENTED();
- return NO;
- }
- - (NSString*)activeTabTitle {
- // subclass must implement
- NOTIMPLEMENTED();
- return @"";
- }
- - (BOOL)hasTabStrip {
- // Subclasses should implement this.
- NOTIMPLEMENTED();
- return YES;
- }
- - (BOOL)isTabDraggable:(NSView*)tabView {
- return ![lockedTabs_ containsObject:tabView];
- }
- - (void)setTab:(NSView*)tabView isDraggable:(BOOL)draggable {
- if (draggable)
- [lockedTabs_ removeObject:tabView];
- else
- [lockedTabs_ addObject:tabView];
- }
- // Tell the window that it needs to call performClose: as soon as the current
- // drag is complete. This prevents a window (and its overlay) from going away
- // during a drag.
- - (void)deferPerformClose {
- closeDeferred_ = YES;
- }
- // Called when the size of the window content area has changed. Override to
- // position specific views. Base class implementation does nothing.
- - (void)layoutSubviews {
- NOTIMPLEMENTED();
- }
- @end
|