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

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

Issue 1946993004: [Mac][Material Design] Fix TabStripController test that fails under MD. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix variable name. Created 4 years, 7 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 <cmath> 9 #include <cmath>
10 #include <limits> 10 #include <limits>
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 using content::OpenURLParams; 77 using content::OpenURLParams;
78 using content::Referrer; 78 using content::Referrer;
79 using content::WebContents; 79 using content::WebContents;
80 80
81 namespace { 81 namespace {
82 82
83 // A value to indicate tab layout should use the full available width of the 83 // A value to indicate tab layout should use the full available width of the
84 // view. 84 // view.
85 const CGFloat kUseFullAvailableWidth = -1.0; 85 const CGFloat kUseFullAvailableWidth = -1.0;
86 86
87 // The amount by which tabs overlap.
88 // Needs to be <= the x position of the favicon within a tab. Else, every time
89 // the throbber is painted, the throbber's invalidation will also invalidate
90 // parts of the tab to the left, and two tabs's backgrounds need to be painted
91 // on each throbber frame instead of one.
92 const CGFloat kTabOverlap = 18.0;
93 const CGFloat kTabOverlapNonMD = 19.0;
94
95 // The amount by which pinned tabs are separated from normal tabs. 87 // The amount by which pinned tabs are separated from normal tabs.
96 const CGFloat kLastPinnedTabSpacing = 2.0; 88 const CGFloat kLastPinnedTabSpacing = 2.0;
97 89
98 // The amount by which the new tab button is offset (from the tabs). 90 // The amount by which the new tab button is offset (from the tabs).
99 const CGFloat kNewTabButtonOffset = 10.0; 91 const CGFloat kNewTabButtonOffset = 10.0;
100 const CGFloat kNewTabButtonOffsetNonMD = 8.0; 92 const CGFloat kNewTabButtonOffsetNonMD = 8.0;
101 93
102 // Time (in seconds) in which tabs animate to their final position. 94 // Time (in seconds) in which tabs animate to their final position.
103 const NSTimeInterval kAnimationDuration = 0.125; 95 const NSTimeInterval kAnimationDuration = 0.125;
104 96
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 + (CGFloat)defaultTabHeight { 544 + (CGFloat)defaultTabHeight {
553 return [TabController defaultTabHeight]; 545 return [TabController defaultTabHeight];
554 } 546 }
555 547
556 + (CGFloat)defaultLeftIndentForControls { 548 + (CGFloat)defaultLeftIndentForControls {
557 // Default indentation leaves enough room so tabs don't overlap with the 549 // Default indentation leaves enough room so tabs don't overlap with the
558 // window controls. 550 // window controls.
559 return 70.0; 551 return 70.0;
560 } 552 }
561 553
554 + (CGFloat)tabOverlap {
555 // The overlap value needs to be <= the x position of the favicon within a
556 // tab. Else, every time the throbber is painted, the throbber's invalidation
557 // will also invalidate parts of the tab to the left, and two tabs's
558 // backgrounds need to be painted on each throbber frame instead of one.
559 const CGFloat kTabOverlap = 18.0;
560 const CGFloat kTabOverlapNonMD = 19.0;
561
562 if (!ui::MaterialDesignController::IsModeMaterial()) {
563 return kTabOverlapNonMD;
564 }
565 return kTabOverlap;
566 }
567
562 // Finds the TabContentsController associated with the given index into the tab 568 // Finds the TabContentsController associated with the given index into the tab
563 // model and swaps out the sole child of the contentArea to display its 569 // model and swaps out the sole child of the contentArea to display its
564 // contents. 570 // contents.
565 - (void)swapInTabAtIndex:(NSInteger)modelIndex { 571 - (void)swapInTabAtIndex:(NSInteger)modelIndex {
566 DCHECK(modelIndex >= 0 && modelIndex < tabStripModel_->count()); 572 DCHECK(modelIndex >= 0 && modelIndex < tabStripModel_->count());
567 NSInteger index = [self indexFromModelIndex:modelIndex]; 573 NSInteger index = [self indexFromModelIndex:modelIndex];
568 TabContentsController* controller = [tabContentsArray_ objectAtIndex:index]; 574 TabContentsController* controller = [tabContentsArray_ objectAtIndex:index];
569 575
570 // Make sure we do not draw any transient arrangements of views. 576 // Make sure we do not draw any transient arrangements of views.
571 gfx::ScopedCocoaDisableScreenUpdates cocoa_disabler; 577 gfx::ScopedCocoaDisableScreenUpdates cocoa_disabler;
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 - (void)layoutTabsWithAnimation:(BOOL)animate 911 - (void)layoutTabsWithAnimation:(BOOL)animate
906 regenerateSubviews:(BOOL)doUpdate { 912 regenerateSubviews:(BOOL)doUpdate {
907 DCHECK([NSThread isMainThread]); 913 DCHECK([NSThread isMainThread]);
908 if (![tabArray_ count]) 914 if (![tabArray_ count])
909 return; 915 return;
910 916
911 const CGFloat kMaxTabWidth = [TabController maxTabWidth]; 917 const CGFloat kMaxTabWidth = [TabController maxTabWidth];
912 const CGFloat kMinTabWidth = [TabController minTabWidth]; 918 const CGFloat kMinTabWidth = [TabController minTabWidth];
913 const CGFloat kMinActiveTabWidth = [TabController minActiveTabWidth]; 919 const CGFloat kMinActiveTabWidth = [TabController minActiveTabWidth];
914 const CGFloat kPinnedTabWidth = [TabController pinnedTabWidth]; 920 const CGFloat kPinnedTabWidth = [TabController pinnedTabWidth];
921 const CGFloat kTabOverlap = [TabStripController tabOverlap];
915 922
916 NSRect enclosingRect = NSZeroRect; 923 NSRect enclosingRect = NSZeroRect;
917 ScopedNSAnimationContextGroup mainAnimationGroup(animate); 924 ScopedNSAnimationContextGroup mainAnimationGroup(animate);
918 mainAnimationGroup.SetCurrentContextDuration(kAnimationDuration); 925 mainAnimationGroup.SetCurrentContextDuration(kAnimationDuration);
919 926
920 // Update the current subviews and their z-order if requested. 927 // Update the current subviews and their z-order if requested.
921 if (doUpdate) 928 if (doUpdate)
922 [self regenerateSubviewList]; 929 [self regenerateSubviewList];
923 930
924 // Compute the base width of tabs given how much room we're allowed. Note that 931 // Compute the base width of tabs given how much room we're allowed. Note that
925 // pinned tabs have a fixed width. We may not be able to use the entire width 932 // pinned tabs have a fixed width. We may not be able to use the entire width
926 // if the user is quickly closing tabs. This may be negative, but that's okay 933 // if the user is quickly closing tabs. This may be negative, but that's okay
927 // (taken care of by |MAX()| when calculating tab sizes). 934 // (taken care of by |MAX()| when calculating tab sizes).
928 CGFloat availableSpace = 0; 935 CGFloat availableSpace = 0;
929 if ([self inRapidClosureMode]) { 936 if ([self inRapidClosureMode]) {
930 availableSpace = availableResizeWidth_; 937 availableSpace = availableResizeWidth_;
931 } else { 938 } else {
932 availableSpace = NSWidth([tabStripView_ frame]); 939 availableSpace = NSWidth([tabStripView_ frame]);
933 940
934 // Account for the width of the new tab button. 941 // Account for the width of the new tab button.
935 if (!ui::MaterialDesignController::IsModeMaterial()) { 942 if (!ui::MaterialDesignController::IsModeMaterial()) {
936 availableSpace -= 943 availableSpace -=
937 NSWidth([newTabButton_ frame]) + kNewTabButtonOffsetNonMD - 944 NSWidth([newTabButton_ frame]) + kNewTabButtonOffsetNonMD -
938 kTabOverlapNonMD; 945 kTabOverlap;
939 } else { 946 } else {
940 availableSpace -= 947 availableSpace -=
941 NSWidth([newTabButton_ frame]) + kNewTabButtonOffset - kTabOverlap; 948 NSWidth([newTabButton_ frame]) + kNewTabButtonOffset - kTabOverlap;
942 } 949 }
943 // Account for the right-side controls if not in rapid closure mode. 950 // Account for the right-side controls if not in rapid closure mode.
944 // (In rapid closure mode, the available width is set based on the 951 // (In rapid closure mode, the available width is set based on the
945 // position of the rightmost tab, not based on the width of the tab strip, 952 // position of the rightmost tab, not based on the width of the tab strip,
946 // so the right controls have already been accounted for.) 953 // so the right controls have already been accounted for.)
947 availableSpace -= [self rightIndentForControls]; 954 availableSpace -= [self rightIndentForControls];
948 } 955 }
(...skipping 10 matching lines...) Expand all
959 [self numberOfOpenPinnedTabs] * (kPinnedTabWidth - kTabOverlap); 966 [self numberOfOpenPinnedTabs] * (kPinnedTabWidth - kTabOverlap);
960 availableSpaceForNonPinned -= kLastPinnedTabSpacing; 967 availableSpaceForNonPinned -= kLastPinnedTabSpacing;
961 } 968 }
962 969
963 // Initialize |nonPinnedTabWidth| in case there aren't any non-pinned tabs; 970 // Initialize |nonPinnedTabWidth| in case there aren't any non-pinned tabs;
964 // this value shouldn't actually be used. 971 // this value shouldn't actually be used.
965 CGFloat nonPinnedTabWidth = kMaxTabWidth; 972 CGFloat nonPinnedTabWidth = kMaxTabWidth;
966 CGFloat nonPinnedTabWidthFraction = 0; 973 CGFloat nonPinnedTabWidthFraction = 0;
967 NSInteger numberOfNonPinnedTabs = MIN( 974 NSInteger numberOfNonPinnedTabs = MIN(
968 [self numberOfOpenNonPinnedTabs], 975 [self numberOfOpenNonPinnedTabs],
969 (availableSpaceForNonPinned - kTabOverlap) / (kMinTabWidth - 976 (availableSpaceForNonPinned - kTabOverlap) /
970 kTabOverlap)); 977 (kMinTabWidth - kTabOverlap));
971 978
972 if (numberOfNonPinnedTabs) { 979 if (numberOfNonPinnedTabs) {
973 // Find the width of a non-pinned tab. This only applies to horizontal 980 // Find the width of a non-pinned tab. This only applies to horizontal
974 // mode. Add in the amount we "get back" from the tabs overlapping. 981 // mode. Add in the amount we "get back" from the tabs overlapping.
975 nonPinnedTabWidth = 982 nonPinnedTabWidth =
976 ((availableSpaceForNonPinned - kTabOverlap) / numberOfNonPinnedTabs) + 983 ((availableSpaceForNonPinned - kTabOverlap) / numberOfNonPinnedTabs) +
977 kTabOverlap; 984 kTabOverlap;
978 985
979 // Clamp the width between the max and min. 986 // Clamp the width between the max and min.
980 nonPinnedTabWidth = MAX(MIN(nonPinnedTabWidth, kMaxTabWidth), kMinTabWidth); 987 nonPinnedTabWidth = MAX(MIN(nonPinnedTabWidth, kMaxTabWidth), kMinTabWidth);
981 988
982 // When there are multiple tabs, we'll have one active and some inactive 989 // When there are multiple tabs, we'll have one active and some inactive
983 // tabs. If the desired width was between the minimum sizes of these types, 990 // tabs. If the desired width was between the minimum sizes of these types,
984 // try to shrink the tabs with the smaller minimum. For example, if we have 991 // try to shrink the tabs with the smaller minimum. For example, if we have
985 // a strip of width 10 with 4 tabs, the desired width per tab will be 2.5. 992 // a strip of width 10 with 4 tabs, the desired width per tab will be 2.5.
986 // If selected tabs have a minimum width of 4 and unselected tabs have 993 // If selected tabs have a minimum width of 4 and unselected tabs have
987 // minimum width of 1, the above code would set *unselected_width = 2.5, 994 // minimum width of 1, the above code would set *unselected_width = 2.5,
988 // *selected_width = 4, which results in a total width of 11.5. Instead, we 995 // *selected_width = 4, which results in a total width of 11.5. Instead, we
989 // want to set *unselected_width = 2, *selected_width = 4, for a total width 996 // want to set *unselected_width = 2, *selected_width = 4, for a total width
990 // of 10. 997 // of 10.
991 if (numberOfNonPinnedTabs > 1 && nonPinnedTabWidth < kMinActiveTabWidth) { 998 if (numberOfNonPinnedTabs > 1 && nonPinnedTabWidth < kMinActiveTabWidth) {
992 nonPinnedTabWidth = (availableSpaceForNonPinned - kMinActiveTabWidth) / 999 nonPinnedTabWidth = (availableSpaceForNonPinned - kMinActiveTabWidth) /
993 (numberOfNonPinnedTabs - 1) + 1000 (numberOfNonPinnedTabs - 1) + kTabOverlap;
994 kTabOverlap;
995 if (nonPinnedTabWidth < kMinTabWidth) { 1001 if (nonPinnedTabWidth < kMinTabWidth) {
996 // The above adjustment caused the tabs to not fit, show 1 less tab. 1002 // The above adjustment caused the tabs to not fit, show 1 less tab.
997 --numberOfNonPinnedTabs; 1003 --numberOfNonPinnedTabs;
998 nonPinnedTabWidth = ((availableSpaceForNonPinned - kTabOverlap) / 1004 nonPinnedTabWidth = ((availableSpaceForNonPinned - kTabOverlap) /
999 numberOfNonPinnedTabs) + 1005 numberOfNonPinnedTabs) + kTabOverlap;
1000 kTabOverlap;
1001 } 1006 }
1002 } 1007 }
1003 1008
1004 // Separate integral and fractional parts. 1009 // Separate integral and fractional parts.
1005 CGFloat integralPart = std::floor(nonPinnedTabWidth); 1010 CGFloat integralPart = std::floor(nonPinnedTabWidth);
1006 nonPinnedTabWidthFraction = nonPinnedTabWidth - integralPart; 1011 nonPinnedTabWidthFraction = nonPinnedTabWidth - integralPart;
1007 nonPinnedTabWidth = integralPart; 1012 nonPinnedTabWidth = integralPart;
1008 } 1013 }
1009 1014
1010 BOOL visible = [[tabStripView_ window] isVisible]; 1015 BOOL visible = [[tabStripView_ window] isVisible];
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 // the |TabStripView|'s coordinates). It considers only the x-coordinate of the 1977 // the |TabStripView|'s coordinates). It considers only the x-coordinate of the
1973 // given point. If it's in the "middle" of a tab, it drops on that tab. If it's 1978 // given point. If it's in the "middle" of a tab, it drops on that tab. If it's
1974 // to the left, it inserts to the left, and similarly for the right. 1979 // to the left, it inserts to the left, and similarly for the right.
1975 - (void)droppingURLsAt:(NSPoint)point 1980 - (void)droppingURLsAt:(NSPoint)point
1976 givesIndex:(NSInteger*)index 1981 givesIndex:(NSInteger*)index
1977 disposition:(WindowOpenDisposition*)disposition { 1982 disposition:(WindowOpenDisposition*)disposition {
1978 // Proportion of the tab which is considered the "middle" (and causes things 1983 // Proportion of the tab which is considered the "middle" (and causes things
1979 // to drop on that tab). 1984 // to drop on that tab).
1980 const double kMiddleProportion = 0.5; 1985 const double kMiddleProportion = 0.5;
1981 const double kLRProportion = (1.0 - kMiddleProportion) / 2.0; 1986 const double kLRProportion = (1.0 - kMiddleProportion) / 2.0;
1987 const CGFloat kTabOverlap = [TabStripController tabOverlap];
1982 1988
1983 DCHECK(index && disposition); 1989 DCHECK(index && disposition);
1984 NSInteger i = 0; 1990 NSInteger i = 0;
1985 for (TabController* tab in tabArray_.get()) { 1991 for (TabController* tab in tabArray_.get()) {
1986 NSView* view = [tab view]; 1992 NSView* view = [tab view];
1987 DCHECK([view isKindOfClass:[TabView class]]); 1993 DCHECK([view isKindOfClass:[TabView class]]);
1988 1994
1989 // Recall that |-[NSView frame]| is in its superview's coordinates, so a 1995 // Recall that |-[NSView frame]| is in its superview's coordinates, so a
1990 // |TabView|'s frame is in the coordinates of the |TabStripView| (which 1996 // |TabView|'s frame is in the coordinates of the |TabStripView| (which
1991 // matches the coordinate system of |point|). 1997 // matches the coordinate system of |point|).
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2093 2099
2094 [self openURL:&url inView:view at:point]; 2100 [self openURL:&url inView:view at:point];
2095 } 2101 }
2096 2102
2097 // (URLDropTargetController protocol) 2103 // (URLDropTargetController protocol)
2098 - (void)indicateDropURLsInView:(NSView*)view at:(NSPoint)point { 2104 - (void)indicateDropURLsInView:(NSView*)view at:(NSPoint)point {
2099 DCHECK_EQ(view, tabStripView_.get()); 2105 DCHECK_EQ(view, tabStripView_.get());
2100 2106
2101 // The minimum y-coordinate at which one should consider place the arrow. 2107 // The minimum y-coordinate at which one should consider place the arrow.
2102 const CGFloat arrowBaseY = 25; 2108 const CGFloat arrowBaseY = 25;
2109 const CGFloat kTabOverlap = [TabStripController tabOverlap];
2103 2110
2104 NSInteger index; 2111 NSInteger index;
2105 WindowOpenDisposition disposition; 2112 WindowOpenDisposition disposition;
2106 [self droppingURLsAt:point 2113 [self droppingURLsAt:point
2107 givesIndex:&index 2114 givesIndex:&index
2108 disposition:&disposition]; 2115 disposition:&disposition];
2109 2116
2110 NSPoint arrowPos = NSMakePoint(0, arrowBaseY); 2117 NSPoint arrowPos = NSMakePoint(0, arrowBaseY);
2111 if (index == -1) { 2118 if (index == -1) {
2112 // Append a tab at the end. 2119 // Append a tab at the end.
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
2289 2296
2290 - (TabAlertState)alertStateForContents:(content::WebContents*)contents { 2297 - (TabAlertState)alertStateForContents:(content::WebContents*)contents {
2291 return chrome::GetTabAlertStateForContents(contents); 2298 return chrome::GetTabAlertStateForContents(contents);
2292 } 2299 }
2293 2300
2294 - (void)themeDidChangeNotification:(NSNotification*)notification { 2301 - (void)themeDidChangeNotification:(NSNotification*)notification {
2295 [newTabButton_ setImages]; 2302 [newTabButton_ setImages];
2296 } 2303 }
2297 2304
2298 @end 2305 @end
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/tabs/tab_strip_controller.h ('k') | chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698