Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm

Issue 7566016: Fullscreen support for Lion. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/cocoa/tabs/tab_strip_controller.h ('k') | chrome/browser/ui/panels/panel.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" 5 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h"
6 6
7 #import <QuartzCore/QuartzCore.h> 7 #import <QuartzCore/QuartzCore.h>
8 8
9 #include <limits> 9 #include <limits>
10 #include <string> 10 #include <string>
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 90
91 // The amount by which tabs overlap. 91 // The amount by which tabs overlap.
92 const CGFloat kTabOverlap = 20.0; 92 const CGFloat kTabOverlap = 20.0;
93 93
94 // The width and height for a tab's icon. 94 // The width and height for a tab's icon.
95 const CGFloat kIconWidthAndHeight = 16.0; 95 const CGFloat kIconWidthAndHeight = 16.0;
96 96
97 // The amount by which the new tab button is offset (from the tabs). 97 // The amount by which the new tab button is offset (from the tabs).
98 const CGFloat kNewTabButtonOffset = 8.0; 98 const CGFloat kNewTabButtonOffset = 8.0;
99 99
100 // The amount by which to shrink the tab strip (on the right) when the
101 // incognito badge is present.
102 const CGFloat kAvatarTabStripShrink = 18;
103
104 // Time (in seconds) in which tabs animate to their final position. 100 // Time (in seconds) in which tabs animate to their final position.
105 const NSTimeInterval kAnimationDuration = 0.125; 101 const NSTimeInterval kAnimationDuration = 0.125;
106 102
107 // The amount by wich the profile menu button is offset (from tab tabs or new 103 // The amount by wich the profile menu button is offset (from tab tabs or new
108 // tab button). 104 // tab button).
109 const CGFloat kProfileMenuButtonOffset = 6.0; 105 const CGFloat kProfileMenuButtonOffset = 6.0;
110 106
111 // Helper class for doing NSAnimationContext calls that takes a bool to disable 107 // Helper class for doing NSAnimationContext calls that takes a bool to disable
112 // all the work. Useful for code that wants to conditionally animate. 108 // all the work. Useful for code that wants to conditionally animate.
113 class ScopedNSAnimationContextGroup { 109 class ScopedNSAnimationContextGroup {
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 // in individual tab positioning (to avoid moving them right back to where they 298 // in individual tab positioning (to avoid moving them right back to where they
303 // were). 299 // were).
304 // 300 //
305 // In order to prevent actions being taken on tabs which are closing, the tab 301 // In order to prevent actions being taken on tabs which are closing, the tab
306 // itself gets marked as such so it no longer will send back its select action 302 // itself gets marked as such so it no longer will send back its select action
307 // or allow itself to be dragged. In addition, drags on the tab strip as a 303 // or allow itself to be dragged. In addition, drags on the tab strip as a
308 // whole are disabled while there are tabs closing. 304 // whole are disabled while there are tabs closing.
309 305
310 @implementation TabStripController 306 @implementation TabStripController
311 307
312 @synthesize indentForControls = indentForControls_; 308 @synthesize leftIndentForControls = leftIndentForControls_;
309 @synthesize rightIndentForControls = rightIndentForControls_;
313 310
314 - (id)initWithView:(TabStripView*)view 311 - (id)initWithView:(TabStripView*)view
315 switchView:(NSView*)switchView 312 switchView:(NSView*)switchView
316 browser:(Browser*)browser 313 browser:(Browser*)browser
317 delegate:(id<TabStripControllerDelegate>)delegate { 314 delegate:(id<TabStripControllerDelegate>)delegate {
318 DCHECK(view && switchView && browser && delegate); 315 DCHECK(view && switchView && browser && delegate);
319 if ((self = [super init])) { 316 if ((self = [super init])) {
320 tabStripView_.reset([view retain]); 317 tabStripView_.reset([view retain]);
321 switchView_ = switchView; 318 switchView_ = switchView;
322 browser_ = browser; 319 browser_ = browser;
323 tabStripModel_ = browser_->tabstrip_model(); 320 tabStripModel_ = browser_->tabstrip_model();
324 hoverTabSelector_.reset(new HoverTabSelector(tabStripModel_)); 321 hoverTabSelector_.reset(new HoverTabSelector(tabStripModel_));
325 delegate_ = delegate; 322 delegate_ = delegate;
326 bridge_.reset(new TabStripModelObserverBridge(tabStripModel_, self)); 323 bridge_.reset(new TabStripModelObserverBridge(tabStripModel_, self));
327 dragController_.reset( 324 dragController_.reset(
328 [[TabStripDragController alloc] initWithTabStripController:self]); 325 [[TabStripDragController alloc] initWithTabStripController:self]);
329 tabContentsArray_.reset([[NSMutableArray alloc] init]); 326 tabContentsArray_.reset([[NSMutableArray alloc] init]);
330 tabArray_.reset([[NSMutableArray alloc] init]); 327 tabArray_.reset([[NSMutableArray alloc] init]);
331 NSWindow* browserWindow = [view window]; 328 NSWindow* browserWindow = [view window];
332 329
333 // Important note: any non-tab subviews not added to |permanentSubviews_| 330 // Important note: any non-tab subviews not added to |permanentSubviews_|
334 // (see |-addSubviewToPermanentList:|) will be wiped out. 331 // (see |-addSubviewToPermanentList:|) will be wiped out.
335 permanentSubviews_.reset([[NSMutableArray alloc] init]); 332 permanentSubviews_.reset([[NSMutableArray alloc] init]);
336 333
337 defaultFavicon_.reset( 334 defaultFavicon_.reset(
338 [gfx::GetCachedImageWithName(@"nav.pdf") retain]); 335 [gfx::GetCachedImageWithName(@"nav.pdf") retain]);
339 336
340 [self setIndentForControls:[[self class] defaultIndentForControls]]; 337 [self setLeftIndentForControls:[[self class] defaultLeftIndentForControls]];
338 [self setRightIndentForControls:0];
341 339
342 // TODO(viettrungluu): WTF? "For some reason, if the view is present in the 340 // TODO(viettrungluu): WTF? "For some reason, if the view is present in the
343 // nib a priori, it draws correctly. If we create it in code and add it to 341 // nib a priori, it draws correctly. If we create it in code and add it to
344 // the tab view, it draws with all sorts of crazy artifacts." 342 // the tab view, it draws with all sorts of crazy artifacts."
345 newTabButton_ = [view getNewTabButton]; 343 newTabButton_ = [view getNewTabButton];
346 [self addSubviewToPermanentList:newTabButton_]; 344 [self addSubviewToPermanentList:newTabButton_];
347 [newTabButton_ setTarget:nil]; 345 [newTabButton_ setTarget:nil];
348 [newTabButton_ setAction:@selector(commandDispatch:)]; 346 [newTabButton_ setAction:@selector(commandDispatch:)];
349 [newTabButton_ setTag:IDC_NEW_TAB]; 347 [newTabButton_ setTag:IDC_NEW_TAB];
350 348
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 [[[view animationForKey:@"frameOrigin"] delegate] invalidate]; 460 [[[view animationForKey:@"frameOrigin"] delegate] invalidate];
463 } 461 }
464 [[NSNotificationCenter defaultCenter] removeObserver:self]; 462 [[NSNotificationCenter defaultCenter] removeObserver:self];
465 [super dealloc]; 463 [super dealloc];
466 } 464 }
467 465
468 + (CGFloat)defaultTabHeight { 466 + (CGFloat)defaultTabHeight {
469 return 25.0; 467 return 25.0;
470 } 468 }
471 469
472 + (CGFloat)defaultIndentForControls { 470 + (CGFloat)defaultLeftIndentForControls {
473 // Default indentation leaves enough room so tabs don't overlap with the 471 // Default indentation leaves enough room so tabs don't overlap with the
474 // window controls. 472 // window controls.
475 return 70.0; 473 return 70.0;
476 } 474 }
477 475
478 // Finds the TabContentsController associated with the given index into the tab 476 // Finds the TabContentsController associated with the given index into the tab
479 // model and swaps out the sole child of the contentArea to display its 477 // model and swaps out the sole child of the contentArea to display its
480 // contents. 478 // contents.
481 - (void)swapInTabAtIndex:(NSInteger)modelIndex { 479 - (void)swapInTabAtIndex:(NSInteger)modelIndex {
482 DCHECK(modelIndex >= 0 && modelIndex < tabStripModel_->count()); 480 DCHECK(modelIndex >= 0 && modelIndex < tabStripModel_->count());
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 placeholderStretchiness_ = yStretchiness; 781 placeholderStretchiness_ = yStretchiness;
784 [self layoutTabsWithAnimation:initialLayoutComplete_ regenerateSubviews:NO]; 782 [self layoutTabsWithAnimation:initialLayoutComplete_ regenerateSubviews:NO];
785 } 783 }
786 784
787 - (BOOL)isDragSessionActive { 785 - (BOOL)isDragSessionActive {
788 return placeholderTab_ != nil; 786 return placeholderTab_ != nil;
789 } 787 }
790 788
791 - (BOOL)isTabFullyVisible:(TabView*)tab { 789 - (BOOL)isTabFullyVisible:(TabView*)tab {
792 NSRect frame = [tab frame]; 790 NSRect frame = [tab frame];
793 return NSMinX(frame) >= [self indentForControls] && 791 return NSMinX(frame) >= [self leftIndentForControls] &&
794 NSMaxX(frame) <= NSMaxX([tabStripView_ frame]); 792 NSMaxX(frame) <= (NSMaxX([tabStripView_ frame]) -
793 [self rightIndentForControls]);
795 } 794 }
796 795
797 - (void)showNewTabButton:(BOOL)show { 796 - (void)showNewTabButton:(BOOL)show {
798 forceNewTabButtonHidden_ = show ? NO : YES; 797 forceNewTabButtonHidden_ = show ? NO : YES;
799 if (forceNewTabButtonHidden_) 798 if (forceNewTabButtonHidden_)
800 [newTabButton_ setHidden:YES]; 799 [newTabButton_ setHidden:YES];
801 } 800 }
802 801
803 // Lay out all tabs in the order of their TabContentsControllers, which matches 802 // Lay out all tabs in the order of their TabContentsControllers, which matches
804 // the ordering in the TabStripModel. This call isn't that expensive, though 803 // the ordering in the TabStripModel. This call isn't that expensive, though
(...skipping 27 matching lines...) Expand all
832 // (taken care of by |MAX()| when calculating tab sizes). 831 // (taken care of by |MAX()| when calculating tab sizes).
833 CGFloat availableSpace = 0; 832 CGFloat availableSpace = 0;
834 if (verticalLayout_) { 833 if (verticalLayout_) {
835 availableSpace = NSHeight([tabStripView_ bounds]); 834 availableSpace = NSHeight([tabStripView_ bounds]);
836 } else { 835 } else {
837 if ([self inRapidClosureMode]) { 836 if ([self inRapidClosureMode]) {
838 availableSpace = availableResizeWidth_; 837 availableSpace = availableResizeWidth_;
839 } else { 838 } else {
840 availableSpace = NSWidth([tabStripView_ frame]); 839 availableSpace = NSWidth([tabStripView_ frame]);
841 840
842 BrowserWindowController* controller = 841 // Account for the width of the new tab button.
843 (BrowserWindowController*)[[tabStripView_ window] windowController];
844
845 // Account for the widths of the new tab button or the avatar, if any/all
846 // are present.
847 availableSpace -= NSWidth([newTabButton_ frame]) + kNewTabButtonOffset; 842 availableSpace -= NSWidth([newTabButton_ frame]) + kNewTabButtonOffset;
848 if ([controller respondsToSelector:@selector(shouldShowAvatar)] &&
849 [controller shouldShowAvatar]) {
850 availableSpace -= kAvatarTabStripShrink;
851 }
852 } 843 }
853 availableSpace -= [self indentForControls]; 844 availableSpace -= [self leftIndentForControls];
845 availableSpace -= [self rightIndentForControls];
854 } 846 }
855 847
856 // This may be negative, but that's okay (taken care of by |MAX()| when 848 // This may be negative, but that's okay (taken care of by |MAX()| when
857 // calculating tab sizes). "mini" tabs in horizontal mode just get a special 849 // calculating tab sizes). "mini" tabs in horizontal mode just get a special
858 // section, they don't change size. 850 // section, they don't change size.
859 CGFloat availableSpaceForNonMini = availableSpace; 851 CGFloat availableSpaceForNonMini = availableSpace;
860 if (!verticalLayout_) { 852 if (!verticalLayout_) {
861 availableSpaceForNonMini -= 853 availableSpaceForNonMini -=
862 [self numberOfOpenMiniTabs] * (kMiniTabWidth - kTabOverlap); 854 [self numberOfOpenMiniTabs] * (kMiniTabWidth - kTabOverlap);
863 } 855 }
864 856
865 // Initialize |nonMiniTabWidth| in case there aren't any non-mini-tabs; this 857 // Initialize |nonMiniTabWidth| in case there aren't any non-mini-tabs; this
866 // value shouldn't actually be used. 858 // value shouldn't actually be used.
867 CGFloat nonMiniTabWidth = kMaxTabWidth; 859 CGFloat nonMiniTabWidth = kMaxTabWidth;
868 const NSInteger numberOfOpenNonMiniTabs = [self numberOfOpenNonMiniTabs]; 860 const NSInteger numberOfOpenNonMiniTabs = [self numberOfOpenNonMiniTabs];
869 if (!verticalLayout_ && numberOfOpenNonMiniTabs) { 861 if (!verticalLayout_ && numberOfOpenNonMiniTabs) {
870 // Find the width of a non-mini-tab. This only applies to horizontal 862 // Find the width of a non-mini-tab. This only applies to horizontal
871 // mode. Add in the amount we "get back" from the tabs overlapping. 863 // mode. Add in the amount we "get back" from the tabs overlapping.
872 availableSpaceForNonMini += (numberOfOpenNonMiniTabs - 1) * kTabOverlap; 864 availableSpaceForNonMini += (numberOfOpenNonMiniTabs - 1) * kTabOverlap;
873 865
874 // Divide up the space between the non-mini-tabs. 866 // Divide up the space between the non-mini-tabs.
875 nonMiniTabWidth = availableSpaceForNonMini / numberOfOpenNonMiniTabs; 867 nonMiniTabWidth = availableSpaceForNonMini / numberOfOpenNonMiniTabs;
876 868
877 // Clamp the width between the max and min. 869 // Clamp the width between the max and min.
878 nonMiniTabWidth = MAX(MIN(nonMiniTabWidth, kMaxTabWidth), kMinTabWidth); 870 nonMiniTabWidth = MAX(MIN(nonMiniTabWidth, kMaxTabWidth), kMinTabWidth);
879 } 871 }
880 872
881 BOOL visible = [[tabStripView_ window] isVisible]; 873 BOOL visible = [[tabStripView_ window] isVisible];
882 874
883 CGFloat offset = [self indentForControls]; 875 CGFloat offset = [self leftIndentForControls];
884 bool hasPlaceholderGap = false; 876 bool hasPlaceholderGap = false;
885 for (TabController* tab in tabArray_.get()) { 877 for (TabController* tab in tabArray_.get()) {
886 // Ignore a tab that is going through a close animation. 878 // Ignore a tab that is going through a close animation.
887 if ([closingControllers_ containsObject:tab]) 879 if ([closingControllers_ containsObject:tab])
888 continue; 880 continue;
889 881
890 BOOL isPlaceholder = [[tab view] isEqual:placeholderTab_]; 882 BOOL isPlaceholder = [[tab view] isEqual:placeholderTab_];
891 NSRect tabFrame = [[tab view] frame]; 883 NSRect tabFrame = [[tab view] frame];
892 tabFrame.size.height = [[self class] defaultTabHeight] + 1; 884 tabFrame.size.height = [[self class] defaultTabHeight] + 1;
893 if (verticalLayout_) { 885 if (verticalLayout_) {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 // Mark that we've successfully completed layout of at least one tab. 1027 // Mark that we've successfully completed layout of at least one tab.
1036 initialLayoutComplete_ = YES; 1028 initialLayoutComplete_ = YES;
1037 } 1029 }
1038 1030
1039 // When we're told to layout from the public API we usually want to animate, 1031 // When we're told to layout from the public API we usually want to animate,
1040 // except when it's the first time. 1032 // except when it's the first time.
1041 - (void)layoutTabs { 1033 - (void)layoutTabs {
1042 [self layoutTabsWithAnimation:initialLayoutComplete_ regenerateSubviews:YES]; 1034 [self layoutTabsWithAnimation:initialLayoutComplete_ regenerateSubviews:YES];
1043 } 1035 }
1044 1036
1037 - (void)layoutTabsWithoutAnimation {
1038 [self layoutTabsWithAnimation:NO regenerateSubviews:YES];
1039 }
1040
1045 // Handles setting the title of the tab based on the given |contents|. Uses 1041 // Handles setting the title of the tab based on the given |contents|. Uses
1046 // a canned string if |contents| is NULL. 1042 // a canned string if |contents| is NULL.
1047 - (void)setTabTitle:(NSViewController*)tab withContents:(TabContents*)contents { 1043 - (void)setTabTitle:(NSViewController*)tab withContents:(TabContents*)contents {
1048 NSString* titleString = nil; 1044 NSString* titleString = nil;
1049 if (contents) 1045 if (contents)
1050 titleString = base::SysUTF16ToNSString(contents->GetTitle()); 1046 titleString = base::SysUTF16ToNSString(contents->GetTitle());
1051 if (![titleString length]) { 1047 if (![titleString length]) {
1052 titleString = l10n_util::GetNSString(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED); 1048 titleString = l10n_util::GetNSString(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED);
1053 } 1049 }
1054 [tab setTitle:titleString]; 1050 [tab setTitle:titleString];
(...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after
2025 NSInteger index = [self indexFromModelIndex:modelIndex]; 2021 NSInteger index = [self indexFromModelIndex:modelIndex];
2026 BrowserWindowController* controller = 2022 BrowserWindowController* controller =
2027 (BrowserWindowController*)[[switchView_ window] windowController]; 2023 (BrowserWindowController*)[[switchView_ window] windowController];
2028 DCHECK(index >= 0); 2024 DCHECK(index >= 0);
2029 if (index >= 0) { 2025 if (index >= 0) {
2030 [controller setTab:[self viewAtIndex:index] isDraggable:YES]; 2026 [controller setTab:[self viewAtIndex:index] isDraggable:YES];
2031 } 2027 }
2032 } 2028 }
2033 2029
2034 @end 2030 @end
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/tabs/tab_strip_controller.h ('k') | chrome/browser/ui/panels/panel.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698