CTTabWindowController.m 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. // Copyright (c) 2010 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-chromium file.
  4. #import "CTTabWindowController.h"
  5. #import "CTTabStripView.h"
  6. #import "common.h"
  7. #import <PDF_Reader_Pro-Swift.h>
  8. @interface CTTabWindowController(PRIVATE)
  9. - (void)setUseOverlay:(BOOL)useOverlay;
  10. @end
  11. @interface TabWindowOverlayWindow : NSWindow
  12. @end
  13. @implementation TabWindowOverlayWindow
  14. - (NSPoint)themePatternPhase {
  15. return NSZeroPoint;
  16. }
  17. @end
  18. @implementation CTTabWindowController {
  19. @private
  20. IBOutlet NSView* tabContentArea_;
  21. // TODO(pinkerton): Figure out a better way to initialize one or the other
  22. // w/out needing both to be in the nib.
  23. IBOutlet CTTabStripView* topTabStripView_;
  24. IBOutlet CTTabStripView* sideTabStripView_;
  25. NSWindow* overlayWindow_; // Used during dragging for window opacity tricks
  26. __weak NSView* cachedContentView_; // Used during dragging for identifying which
  27. // view is the proper content area in the overlay
  28. // (weak)
  29. NSMutableSet *lockedTabs_;
  30. BOOL closeDeferred_; // If YES, call performClose: in removeOverlay:.
  31. // Difference between height of window content area and height of the
  32. // |tabContentArea_|. Calculated when the window is loaded from the nib and
  33. // cached in order to restore the delta when switching tab modes.
  34. CGFloat contentAreaHeightDelta_;
  35. BOOL enableTransparentContent_;
  36. }
  37. @synthesize tabContentArea = tabContentArea_;
  38. - (id)initWithWindow:(NSWindow*)window {
  39. if ((self = [super initWithWindow:window]) != nil) {
  40. lockedTabs_ = [[NSMutableSet alloc] initWithCapacity:10];
  41. }
  42. return self;
  43. }
  44. - (void)dealloc {
  45. if (overlayWindow_) {
  46. [self setUseOverlay:NO];
  47. }
  48. }
  49. // Add the top tab strop to the window, above the content box and add it to the
  50. // view hierarchy as a sibling of the content view so it can overlap with the
  51. // window frame.
  52. - (void)addTopTabStripToWindow {
  53. CGFloat rightOffst = NSWidth(self.rightStripView.frame);
  54. NSRect contentFrame = [tabContentArea_ frame];
  55. NSRect rightFrame =
  56. NSMakeRect(NSWidth(contentFrame) - rightOffst, NSMaxY(contentFrame),
  57. rightOffst,
  58. NSHeight([topTabStripView_ frame]));
  59. NSRect tabFrame =
  60. NSMakeRect(topTabStripView_.frame.origin.x, NSMaxY(contentFrame),
  61. NSWidth(contentFrame)-rightOffst,
  62. NSHeight([topTabStripView_ frame]));
  63. [topTabStripView_ setFrame:tabFrame];
  64. [self.rightStripView setFrame:rightFrame];
  65. NSView* contentParent = [[[self window] contentView] superview];
  66. // NSView* contentParent = [[self window] contentView];
  67. [contentParent addSubview:topTabStripView_ positioned:NSWindowBelow relativeTo:nil];
  68. [contentParent addSubview:self.rightStripView positioned:NSWindowAbove relativeTo:nil];
  69. }
  70. - (void)windowDidLoad {
  71. // Cache the difference in height between the window content area and the
  72. // tab content area.
  73. NSRect tabFrame = [tabContentArea_ frame];
  74. NSRect contentFrame = [[[self window] contentView] frame];
  75. contentAreaHeightDelta_ = NSHeight(contentFrame) - NSHeight(tabFrame);
  76. // self.window.styleMask |= NSWindowStyleMaskFullSizeContentView;
  77. // self.window.titlebarAppearsTransparent = YES;
  78. if ([self hasTabStrip]) {
  79. [self addTopTabStripToWindow];
  80. } else {
  81. // No top tabstrip so remove the tabContentArea offset.
  82. tabFrame.size.height = contentFrame.size.height;
  83. [tabContentArea_ setFrame:tabFrame];
  84. }
  85. }
  86. // Return the appropriate tab strip based on whether or not side tabs are
  87. // enabled.
  88. - (CTTabStripView*)tabStripView {
  89. return topTabStripView_;
  90. }
  91. - (void)removeOverlay {
  92. [self setUseOverlay:NO];
  93. if (closeDeferred_) {
  94. // See comment in BrowserWindowCocoa::Close() about orderOut:.
  95. [[self window] orderOut:self];
  96. [[self window] performClose:self]; // Autoreleases the controller.
  97. }
  98. }
  99. - (void)showOverlay {
  100. [self setUseOverlay:YES];
  101. }
  102. // if |useOverlay| is true, we're moving views into the overlay's content
  103. // area. If false, we're moving out of the overlay back into the window's
  104. // content.
  105. - (void)moveViewsBetweenWindowAndOverlay:(BOOL)useOverlay {
  106. if (useOverlay) {
  107. [[self tabStripView] setAllowGradient:NO];
  108. [[[overlayWindow_ contentView] superview] addSubview:[self tabStripView]];
  109. // Add the original window's content view as a subview of the overlay
  110. // window's content view. We cannot simply use setContentView: here because
  111. // the overlay window has a different content size (due to it being
  112. // borderless).
  113. [[overlayWindow_ contentView] addSubview:cachedContentView_];
  114. } else {
  115. [[self window] setContentView:cachedContentView_];
  116. // The CTTabStripView always needs to be in front of the window's content
  117. // view and therefore it should always be added after the content view is
  118. // set.
  119. [[self tabStripView] setAllowGradient:enableTransparentContent_];
  120. [[[[self window] contentView] superview] addSubview:[self tabStripView]
  121. positioned:NSWindowBelow
  122. relativeTo:nil];
  123. [[[[self window] contentView] superview] updateTrackingAreas];
  124. }
  125. }
  126. -(void)willStartTearingTab {
  127. }
  128. -(void)willEndTearingTab {
  129. }
  130. -(void)didEndTearingTab {
  131. }
  132. // If |useOverlay| is YES, creates a new overlay window and puts the tab strip
  133. // and the content area inside of it. This allows it to have a different opacity
  134. // from the title bar. If NO, returns everything to the previous state and
  135. // destroys the overlay window until it's needed again. The tab strip and window
  136. // contents are returned to the original window.
  137. - (void)setUseOverlay:(BOOL)useOverlay {
  138. [NSObject cancelPreviousPerformRequestsWithTarget:self
  139. selector:@selector(removeOverlay)
  140. object:nil];
  141. NSWindow* window = [self window];
  142. if (useOverlay && !overlayWindow_) {
  143. DCHECK(!cachedContentView_);
  144. overlayWindow_ = [[TabWindowOverlayWindow alloc] initWithContentRect:[window frame]
  145. styleMask:NSBorderlessWindowMask
  146. backing:NSBackingStoreBuffered
  147. defer:YES];
  148. [overlayWindow_ setTitle:@"overlay"];
  149. [overlayWindow_ setBackgroundColor:[NSColor clearColor]];
  150. [overlayWindow_ setOpaque:NO];
  151. [overlayWindow_ setDelegate:self];
  152. cachedContentView_ = [window contentView];
  153. [window addChildWindow:overlayWindow_ ordered:NSWindowAbove];
  154. [window makeFirstResponder:nil];
  155. [self moveViewsBetweenWindowAndOverlay:useOverlay];
  156. [overlayWindow_ orderFront:nil];
  157. } else if (!useOverlay && overlayWindow_) {
  158. DCHECK(cachedContentView_);
  159. [window setContentView:cachedContentView_];
  160. [self moveViewsBetweenWindowAndOverlay:useOverlay];
  161. [window makeFirstResponder:cachedContentView_];
  162. [window display];
  163. [window removeChildWindow:overlayWindow_];
  164. [overlayWindow_ orderOut:nil];
  165. overlayWindow_ = nil;
  166. cachedContentView_ = nil;
  167. } else {
  168. NOTREACHED();
  169. }
  170. }
  171. - (NSWindow*)overlayWindow {
  172. return overlayWindow_;
  173. }
  174. - (BOOL)shouldConstrainFrameRect {
  175. // If we currently have an overlay window, do not attempt to change the
  176. // window's size, as our overlay window doesn't know how to resize properly.
  177. return overlayWindow_ == nil;
  178. }
  179. - (BOOL)canReceiveFrom:(CTTabWindowController*)source {
  180. // subclass must implement
  181. NOTIMPLEMENTED();
  182. return NO;
  183. }
  184. - (void)moveTabView:(NSView*)view
  185. fromController:(CTTabWindowController*)dragController {
  186. NOTIMPLEMENTED();
  187. }
  188. - (NSView*)activeTabView {
  189. NOTIMPLEMENTED();
  190. return nil;
  191. }
  192. - (void)layoutTabs {
  193. // subclass must implement
  194. NOTIMPLEMENTED();
  195. }
  196. - (CTTabWindowController*)detachTabToNewWindow:(CTTabView*)tabView {
  197. // subclass must implement
  198. NOTIMPLEMENTED();
  199. return NULL;
  200. }
  201. - (void)insertPlaceholderForTab:(CTTabView*)tab
  202. frame:(NSRect)frame {
  203. self.showsNewTabButton = NO;
  204. }
  205. - (void)removePlaceholder {
  206. self.showsNewTabButton = YES;
  207. }
  208. - (BOOL)tabDraggingAllowed {
  209. return YES;
  210. }
  211. - (BOOL)tabTearingAllowed {
  212. return YES;
  213. }
  214. - (BOOL)windowMovementAllowed {
  215. return YES;
  216. }
  217. - (BOOL)isTabFullyVisible:(CTTabView*)tab {
  218. // Subclasses should implement this, but it's not necessary.
  219. return YES;
  220. }
  221. - (void)setShowsNewTabButton:(BOOL)show {
  222. // subclass must implement
  223. NOTIMPLEMENTED();
  224. }
  225. - (BOOL)showsNewTabButton {
  226. // subclass must implement
  227. NOTIMPLEMENTED();
  228. }
  229. - (void)setEnableTransparentContent:(BOOL)enable {
  230. enableTransparentContent_ = enable;
  231. if (enableTransparentContent_) {
  232. [self.window setOpaque:NO];
  233. } else {
  234. [self.window setOpaque:YES];
  235. }
  236. if (!overlayWindow_) {
  237. [topTabStripView_ setAllowGradient:enable];
  238. }
  239. }
  240. - (BOOL)enableTransparentContent {
  241. return enableTransparentContent_;
  242. }
  243. - (void)detachTabView:(NSView*)view {
  244. // subclass must implement
  245. NOTIMPLEMENTED();
  246. }
  247. - (NSInteger)numberOfTabs {
  248. // subclass must implement
  249. NOTIMPLEMENTED();
  250. return 0;
  251. }
  252. - (BOOL)hasLiveTabs {
  253. // subclass must implement
  254. NOTIMPLEMENTED();
  255. return NO;
  256. }
  257. - (NSString*)activeTabTitle {
  258. // subclass must implement
  259. NOTIMPLEMENTED();
  260. return @"";
  261. }
  262. - (BOOL)hasTabStrip {
  263. // Subclasses should implement this.
  264. NOTIMPLEMENTED();
  265. return YES;
  266. }
  267. - (BOOL)isTabDraggable:(NSView*)tabView {
  268. return ![lockedTabs_ containsObject:tabView];
  269. }
  270. - (void)setTab:(NSView*)tabView isDraggable:(BOOL)draggable {
  271. if (draggable)
  272. [lockedTabs_ removeObject:tabView];
  273. else
  274. [lockedTabs_ addObject:tabView];
  275. }
  276. // Tell the window that it needs to call performClose: as soon as the current
  277. // drag is complete. This prevents a window (and its overlay) from going away
  278. // during a drag.
  279. - (void)deferPerformClose {
  280. closeDeferred_ = YES;
  281. }
  282. // Called when the size of the window content area has changed. Override to
  283. // position specific views. Base class implementation does nothing.
  284. - (void)layoutSubviews {
  285. NOTIMPLEMENTED();
  286. }
  287. @end