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

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

Issue 2489373002: [Mac] (More) RTL support for tab strip (Closed)
Patch Set: Created 4 years, 1 month 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
« no previous file with comments | « chrome/browser/ui/cocoa/tabs/tab_strip_controller.h ('k') | no next file » | 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) 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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 bool animate_; 135 bool animate_;
136 DISALLOW_COPY_AND_ASSIGN(ScopedNSAnimationContextGroup); 136 DISALLOW_COPY_AND_ASSIGN(ScopedNSAnimationContextGroup);
137 }; 137 };
138 138
139 CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) { 139 CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) {
140 if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) 140 if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout())
141 return [view frame].size.width - x - width; 141 return [view frame].size.width - x - width;
142 return x; 142 return x;
143 } 143 }
144 144
145 NSRect FlipRectInView(NSView* view, NSRect rect) {
146 rect.origin.x = FlipXInView(view, NSWidth(rect), NSMinX(rect));
147 return rect;
148 }
149
145 } // namespace 150 } // namespace
146 151
147 @interface NSView (PrivateAPI) 152 @interface NSView (PrivateAPI)
148 // Called by AppKit to check if dragging this view should move the window. 153 // Called by AppKit to check if dragging this view should move the window.
149 // NSButton overrides this method in the same way so dragging window buttons 154 // NSButton overrides this method in the same way so dragging window buttons
150 // has no effect. NSView implementation returns NSZeroRect so the whole view 155 // has no effect. NSView implementation returns NSZeroRect so the whole view
151 // area can be dragged. 156 // area can be dragged.
152 - (NSRect)_opaqueRectForWindowMoveWhenInTitlebar; 157 - (NSRect)_opaqueRectForWindowMoveWhenInTitlebar;
153 @end 158 @end
154 159
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 // in individual tab positioning (to avoid moving them right back to where they 399 // in individual tab positioning (to avoid moving them right back to where they
395 // were). 400 // were).
396 // 401 //
397 // In order to prevent actions being taken on tabs which are closing, the tab 402 // In order to prevent actions being taken on tabs which are closing, the tab
398 // itself gets marked as such so it no longer will send back its select action 403 // itself gets marked as such so it no longer will send back its select action
399 // or allow itself to be dragged. In addition, drags on the tab strip as a 404 // or allow itself to be dragged. In addition, drags on the tab strip as a
400 // whole are disabled while there are tabs closing. 405 // whole are disabled while there are tabs closing.
401 406
402 @implementation TabStripController 407 @implementation TabStripController
403 408
404 @synthesize leftIndentForControls = leftIndentForControls_; 409 @synthesize leadingIndentForControls = leadingIndentForControls_;
405 @synthesize rightIndentForControls = rightIndentForControls_; 410 @synthesize trailingIndentForControls = trailingIndentForControls_;
406 411
407 - (id)initWithView:(TabStripView*)view 412 - (id)initWithView:(TabStripView*)view
408 switchView:(NSView*)switchView 413 switchView:(NSView*)switchView
409 browser:(Browser*)browser 414 browser:(Browser*)browser
410 delegate:(id<TabStripControllerDelegate>)delegate { 415 delegate:(id<TabStripControllerDelegate>)delegate {
411 DCHECK(view && switchView && browser && delegate); 416 DCHECK(view && switchView && browser && delegate);
412 if ((self = [super init])) { 417 if ((self = [super init])) {
413 tabStripView_.reset([view retain]); 418 tabStripView_.reset([view retain]);
414 [tabStripView_ setController:self]; 419 [tabStripView_ setController:self];
415 switchView_ = switchView; 420 switchView_ = switchView;
416 browser_ = browser; 421 browser_ = browser;
417 tabStripModel_ = browser_->tab_strip_model(); 422 tabStripModel_ = browser_->tab_strip_model();
418 hoverTabSelector_.reset(new HoverTabSelector(tabStripModel_)); 423 hoverTabSelector_.reset(new HoverTabSelector(tabStripModel_));
419 delegate_ = delegate; 424 delegate_ = delegate;
420 bridge_.reset(new TabStripModelObserverBridge(tabStripModel_, self)); 425 bridge_.reset(new TabStripModelObserverBridge(tabStripModel_, self));
421 dragController_.reset( 426 dragController_.reset(
422 [[TabStripDragController alloc] initWithTabStripController:self]); 427 [[TabStripDragController alloc] initWithTabStripController:self]);
423 tabContentsArray_.reset([[NSMutableArray alloc] init]); 428 tabContentsArray_.reset([[NSMutableArray alloc] init]);
424 tabArray_.reset([[NSMutableArray alloc] init]); 429 tabArray_.reset([[NSMutableArray alloc] init]);
425 NSWindow* browserWindow = [view window]; 430 NSWindow* browserWindow = [view window];
426 431
427 // Important note: any non-tab subviews not added to |permanentSubviews_| 432 // Important note: any non-tab subviews not added to |permanentSubviews_|
428 // (see |-addSubviewToPermanentList:|) will be wiped out. 433 // (see |-addSubviewToPermanentList:|) will be wiped out.
429 permanentSubviews_.reset([[NSMutableArray alloc] init]); 434 permanentSubviews_.reset([[NSMutableArray alloc] init]);
430 435
431 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 436 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
432 defaultFavicon_.reset( 437 defaultFavicon_.reset(
433 rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON).CopyNSImage()); 438 rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON).CopyNSImage());
434 439
435 [self setLeftIndentForControls:[[self class] defaultLeftIndentForControls]]; 440 [self setLeadingIndentForControls:[[self class]
436 [self setRightIndentForControls:0]; 441 defaultLeadingIndentForControls]];
442 [self setTrailingIndentForControls:0];
437 443
438 // Add this invisible view first so that it is ordered below other views. 444 // Add this invisible view first so that it is ordered below other views.
439 dragBlockingView_.reset( 445 dragBlockingView_.reset(
440 [[TabStripControllerDragBlockingView alloc] initWithFrame:NSZeroRect 446 [[TabStripControllerDragBlockingView alloc] initWithFrame:NSZeroRect
441 controller:self]); 447 controller:self]);
442 [self addSubviewToPermanentList:dragBlockingView_]; 448 [self addSubviewToPermanentList:dragBlockingView_];
443 449
444 newTabButton_ = [view getNewTabButton]; 450 newTabButton_ = [view getNewTabButton];
445 [newTabButton_ setWantsLayer:YES]; 451 [newTabButton_ setWantsLayer:YES];
446 [self addSubviewToPermanentList:newTabButton_]; 452 [self addSubviewToPermanentList:newTabButton_];
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 } 568 }
563 [[NSNotificationCenter defaultCenter] removeObserver:self]; 569 [[NSNotificationCenter defaultCenter] removeObserver:self];
564 570
565 browser_ = nullptr; 571 browser_ = nullptr;
566 } 572 }
567 573
568 + (CGFloat)defaultTabHeight { 574 + (CGFloat)defaultTabHeight {
569 return [TabController defaultTabHeight]; 575 return [TabController defaultTabHeight];
570 } 576 }
571 577
572 + (CGFloat)defaultLeftIndentForControls { 578 + (CGFloat)defaultLeadingIndentForControls {
573 // Default indentation leaves enough room so tabs don't overlap with the 579 // Default indentation leaves enough room so tabs don't overlap with the
574 // window controls. 580 // window controls.
575 return 70.0; 581 return 70.0;
576 } 582 }
577 583
578 + (CGFloat)tabOverlap { 584 + (CGFloat)tabOverlap {
579 // The overlap value needs to be <= the x position of the favicon within a 585 // The overlap value needs to be <= the x position of the favicon within a
580 // tab. Else, every time the throbber is painted, the throbber's invalidation 586 // tab. Else, every time the throbber is painted, the throbber's invalidation
581 // will also invalidate parts of the tab to the left, and two tabs's 587 // will also invalidate parts of the tab to the left, and two tabs's
582 // backgrounds need to be painted on each throbber frame instead of one. 588 // backgrounds need to be painted on each throbber frame instead of one.
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 // resized until a later time (when the mouse leaves the tab strip). 822 // resized until a later time (when the mouse leaves the tab strip).
817 // However, if the tab being closed is a pinned tab, break out of 823 // However, if the tab being closed is a pinned tab, break out of
818 // rapid-closure mode since the mouse is almost guaranteed not to be over 824 // rapid-closure mode since the mouse is almost guaranteed not to be over
819 // the closebox of the adjacent tab (due to the difference in widths). 825 // the closebox of the adjacent tab (due to the difference in widths).
820 // TODO(pinkerton): re-visit when handling tab overflow. 826 // TODO(pinkerton): re-visit when handling tab overflow.
821 // http://crbug.com/188 827 // http://crbug.com/188
822 if (tabStripModel_->IsTabPinned(index)) { 828 if (tabStripModel_->IsTabPinned(index)) {
823 availableResizeWidth_ = kUseFullAvailableWidth; 829 availableResizeWidth_ = kUseFullAvailableWidth;
824 } else { 830 } else {
825 NSView* penultimateTab = [self viewAtIndex:numberOfOpenTabs - 2]; 831 NSView* penultimateTab = [self viewAtIndex:numberOfOpenTabs - 2];
826 availableResizeWidth_ = NSMaxX([penultimateTab frame]); 832 availableResizeWidth_ =
833 cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
834 ? FlipXInView(tabStripView_, 0, NSMinX([penultimateTab frame]))
835 : NSMaxX([penultimateTab frame]);
827 } 836 }
828 } else { 837 } else {
829 // If the rightmost tab is closed, change the available width so that 838 // If the trailing tab is closed, change the available width so that
830 // another tab's close button lands below the cursor (assuming the tabs 839 // another tab's close button lands below the cursor (assuming the tabs
831 // are currently below their maximum width and can grow). 840 // are currently below their maximum width and can grow).
832 NSView* lastTab = [self viewAtIndex:numberOfOpenTabs - 1]; 841 NSView* lastTab = [self viewAtIndex:numberOfOpenTabs - 1];
833 availableResizeWidth_ = NSMaxX([lastTab frame]); 842 availableResizeWidth_ =
843 cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
844 ? FlipXInView(tabStripView_, 0, NSMinX([lastTab frame]))
845 : NSMaxX([lastTab frame]);
834 } 846 }
835 tabStripModel_->CloseWebContentsAt( 847 tabStripModel_->CloseWebContentsAt(
836 index, 848 index,
837 TabStripModel::CLOSE_USER_GESTURE | 849 TabStripModel::CLOSE_USER_GESTURE |
838 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); 850 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB);
839 } else { 851 } else {
840 // Use the standard window close if this is the last tab 852 // Use the standard window close if this is the last tab
841 // this prevents the tab from being removed from the model until after 853 // this prevents the tab from being removed from the model until after
842 // the window dissapears 854 // the window dissapears
843 [[tabStripView_ window] performClose:nil]; 855 [[tabStripView_ window] performClose:nil];
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 placeholderFrame_ = frame; 891 placeholderFrame_ = frame;
880 [self layoutTabsWithAnimation:initialLayoutComplete_ regenerateSubviews:NO]; 892 [self layoutTabsWithAnimation:initialLayoutComplete_ regenerateSubviews:NO];
881 } 893 }
882 894
883 - (BOOL)isDragSessionActive { 895 - (BOOL)isDragSessionActive {
884 return placeholderTab_ != nil; 896 return placeholderTab_ != nil;
885 } 897 }
886 898
887 - (BOOL)isTabFullyVisible:(TabView*)tab { 899 - (BOOL)isTabFullyVisible:(TabView*)tab {
888 NSRect frame = [tab frame]; 900 NSRect frame = [tab frame];
889 return NSMinX(frame) >= [self leftIndentForControls] && 901 if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
890 NSMaxX(frame) <= [self tabAreaRightEdge]; 902 return NSMinX(frame) >= [self trailingIndentForControls] &&
903 NSMaxX(frame) <= [self tabAreaRightEdge];
904 } else {
905 return NSMinX(frame) >= [self leadingIndentForControls] &&
906 NSMaxX(frame) <= [self tabAreaRightEdge];
907 }
891 } 908 }
892 909
893 - (CGFloat)tabAreaRightEdge { 910 - (CGFloat)tabAreaRightEdge {
894 return NSMaxX([tabStripView_ frame]) - [self rightIndentForControls]; 911 CGFloat rightEdge = cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
912 ? [self leadingIndentForControls]
913 : [self trailingIndentForControls];
914 return NSMaxX([tabStripView_ frame]) - rightEdge;
895 } 915 }
896 916
897 - (void)showNewTabButton:(BOOL)show { 917 - (void)showNewTabButton:(BOOL)show {
898 forceNewTabButtonHidden_ = show ? NO : YES; 918 forceNewTabButtonHidden_ = show ? NO : YES;
899 if (forceNewTabButtonHidden_) 919 if (forceNewTabButtonHidden_)
900 [newTabButton_ setHidden:YES]; 920 [newTabButton_ setHidden:YES];
901 } 921 }
902 922
903 // Lay out all tabs in the order of their TabContentsControllers, which matches 923 // Lay out all tabs in the order of their TabContentsControllers, which matches
904 // the ordering in the TabStripModel. This call isn't that expensive, though 924 // the ordering in the TabStripModel. This call isn't that expensive, though
(...skipping 27 matching lines...) Expand all
932 // (taken care of by |MAX()| when calculating tab sizes). 952 // (taken care of by |MAX()| when calculating tab sizes).
933 CGFloat availableSpace = 0; 953 CGFloat availableSpace = 0;
934 if ([self inRapidClosureMode]) { 954 if ([self inRapidClosureMode]) {
935 availableSpace = availableResizeWidth_; 955 availableSpace = availableResizeWidth_;
936 } else { 956 } else {
937 availableSpace = NSWidth([tabStripView_ frame]); 957 availableSpace = NSWidth([tabStripView_ frame]);
938 958
939 // Account for the width of the new tab button. 959 // Account for the width of the new tab button.
940 availableSpace -= 960 availableSpace -=
941 NSWidth([newTabButton_ frame]) + kNewTabButtonOffset - kTabOverlap; 961 NSWidth([newTabButton_ frame]) + kNewTabButtonOffset - kTabOverlap;
942 // Account for the right-side controls if not in rapid closure mode. 962 // Account for the trailing controls if not in rapid closure mode.
943 // (In rapid closure mode, the available width is set based on the 963 // (In rapid closure mode, the available width is set based on the
944 // position of the rightmost tab, not based on the width of the tab strip, 964 // position of the trailing tab, not based on the width of the tab strip,
945 // so the right controls have already been accounted for.) 965 // so the trailing controls have already been accounted for.)
946 availableSpace -= [self rightIndentForControls]; 966 availableSpace -= [self trailingIndentForControls];
947 } 967 }
948 968
949 // Need to leave room for the left-side controls even in rapid closure mode. 969 // Need to leave room for the leading controls even in rapid closure mode.
950 availableSpace -= [self leftIndentForControls]; 970 availableSpace -= [self leadingIndentForControls];
951 971
952 // This may be negative, but that's okay (taken care of by |MAX()| when 972 // This may be negative, but that's okay (taken care of by |MAX()| when
953 // calculating tab sizes). "pinned" tabs in horizontal mode just get a special 973 // calculating tab sizes). "pinned" tabs in horizontal mode just get a special
954 // section, they don't change size. 974 // section, they don't change size.
955 CGFloat availableSpaceForNonPinned = availableSpace; 975 CGFloat availableSpaceForNonPinned = availableSpace;
956 if ([self numberOfOpenPinnedTabs]) { 976 if ([self numberOfOpenPinnedTabs]) {
957 availableSpaceForNonPinned -= 977 availableSpaceForNonPinned -=
958 [self numberOfOpenPinnedTabs] * (kPinnedTabWidth - kTabOverlap); 978 [self numberOfOpenPinnedTabs] * (kPinnedTabWidth - kTabOverlap);
959 availableSpaceForNonPinned -= kLastPinnedTabSpacing; 979 availableSpaceForNonPinned -= kLastPinnedTabSpacing;
960 } 980 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 } 1019 }
1000 1020
1001 // Separate integral and fractional parts. 1021 // Separate integral and fractional parts.
1002 CGFloat integralPart = std::floor(nonPinnedTabWidth); 1022 CGFloat integralPart = std::floor(nonPinnedTabWidth);
1003 nonPinnedTabWidthFraction = nonPinnedTabWidth - integralPart; 1023 nonPinnedTabWidthFraction = nonPinnedTabWidth - integralPart;
1004 nonPinnedTabWidth = integralPart; 1024 nonPinnedTabWidth = integralPart;
1005 } 1025 }
1006 1026
1007 BOOL visible = [[tabStripView_ window] isVisible]; 1027 BOOL visible = [[tabStripView_ window] isVisible];
1008 1028
1009 CGFloat offset = 1029 CGFloat offset = [self leadingIndentForControls];
1010 cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
1011 ? [self rightIndentForControls]
1012 : [self leftIndentForControls];
1013 bool hasPlaceholderGap = false; 1030 bool hasPlaceholderGap = false;
1014 // Whether or not the last tab processed by the loop was a pinned tab. 1031 // Whether or not the last tab processed by the loop was a pinned tab.
1015 BOOL isLastTabPinned = NO; 1032 BOOL isLastTabPinned = NO;
1016 CGFloat tabWidthAccumulatedFraction = 0; 1033 CGFloat tabWidthAccumulatedFraction = 0;
1017 NSInteger laidOutNonPinnedTabs = 0; 1034 NSInteger laidOutNonPinnedTabs = 0;
1018 1035
1036 // Lay everything out as if it was LTR and flip at the end
1037 // for RTL, if necessary.
1019 for (TabController* tab in tabArray_.get()) { 1038 for (TabController* tab in tabArray_.get()) {
1020 // Ignore a tab that is going through a close animation. 1039 // Ignore a tab that is going through a close animation.
1021 if ([closingControllers_ containsObject:tab]) 1040 if ([closingControllers_ containsObject:tab])
1022 continue; 1041 continue;
1023 1042
1024 BOOL isPlaceholder = [[tab view] isEqual:placeholderTab_]; 1043 BOOL isPlaceholder = [[tab view] isEqual:placeholderTab_];
1025 NSRect tabFrame = [[tab view] frame]; 1044 NSRect tabFrame = [[tab view] frame];
1026 tabFrame.size.height = [[self class] defaultTabHeight]; 1045 tabFrame.size.height = [[self class] defaultTabHeight];
1027 tabFrame.origin.y = 0; 1046 tabFrame.origin.y = 0;
1028 tabFrame.origin.x = offset; 1047 tabFrame.origin.x = offset;
(...skipping 14 matching lines...) Expand all
1043 [target setFrame:tabFrame]; 1062 [target setFrame:tabFrame];
1044 1063
1045 // Store the frame by identifier to avoid redundant calls to animator. 1064 // Store the frame by identifier to avoid redundant calls to animator.
1046 NSValue* identifier = [NSValue valueWithPointer:[tab view]]; 1065 NSValue* identifier = [NSValue valueWithPointer:[tab view]];
1047 [targetFrames_ setObject:[NSValue valueWithRect:tabFrame] 1066 [targetFrames_ setObject:[NSValue valueWithRect:tabFrame]
1048 forKey:identifier]; 1067 forKey:identifier];
1049 continue; 1068 continue;
1050 } 1069 }
1051 1070
1052 if (placeholderTab_ && !hasPlaceholderGap) { 1071 if (placeholderTab_ && !hasPlaceholderGap) {
1053 const CGFloat placeholderMin = NSMinX(placeholderFrame_); 1072 // If the back edge is behind the placeholder's back edge, but the
1054 // If the left edge is to the left of the placeholder's left, but the 1073 // mid is in front of it of it, slide over to make space for it.
1055 // mid is to the right of it slide over to make space for it. 1074 bool shouldLeaveGap;
1056 if (NSMidX(tabFrame) > placeholderMin) { 1075 if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
1076 const CGFloat tabMidpoint =
1077 NSMidX(FlipRectInView(tabStripView_, tabFrame));
1078 shouldLeaveGap = tabMidpoint < NSMaxX(placeholderFrame_);
1079 } else {
1080 shouldLeaveGap = NSMidX(tabFrame) > NSMinX(placeholderFrame_);
1081 }
1082 if (shouldLeaveGap) {
1057 hasPlaceholderGap = true; 1083 hasPlaceholderGap = true;
1058 offset += NSWidth(placeholderFrame_); 1084 offset += NSWidth(placeholderFrame_);
1059 offset -= kTabOverlap; 1085 offset -= kTabOverlap;
1060 tabFrame.origin.x = offset; 1086 tabFrame.origin.x = offset;
1061 } 1087 }
1062 } 1088 }
1063 1089
1064 // Set the width. Selected tabs are slightly wider when things get really 1090 // Set the width. Selected tabs are slightly wider when things get really
1065 // small and thus we enforce a different minimum width. 1091 // small and thus we enforce a different minimum width.
1066 BOOL isPinned = [tab pinned]; 1092 BOOL isPinned = [tab pinned];
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after
2012 givesIndex:(NSInteger*)index 2038 givesIndex:(NSInteger*)index
2013 disposition:(WindowOpenDisposition*)disposition { 2039 disposition:(WindowOpenDisposition*)disposition {
2014 // Proportion of the tab which is considered the "middle" (and causes things 2040 // Proportion of the tab which is considered the "middle" (and causes things
2015 // to drop on that tab). 2041 // to drop on that tab).
2016 const double kMiddleProportion = 0.5; 2042 const double kMiddleProportion = 0.5;
2017 const double kLRProportion = (1.0 - kMiddleProportion) / 2.0; 2043 const double kLRProportion = (1.0 - kMiddleProportion) / 2.0;
2018 const CGFloat kTabOverlap = [TabStripController tabOverlap]; 2044 const CGFloat kTabOverlap = [TabStripController tabOverlap];
2019 2045
2020 DCHECK(index && disposition); 2046 DCHECK(index && disposition);
2021 NSInteger i = 0; 2047 NSInteger i = 0;
2048 BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout();
2022 for (TabController* tab in tabArray_.get()) { 2049 for (TabController* tab in tabArray_.get()) {
2023 NSView* view = [tab view]; 2050 NSView* view = [tab view];
2024 DCHECK([view isKindOfClass:[TabView class]]); 2051 DCHECK([view isKindOfClass:[TabView class]]);
2025 2052
2026 // Recall that |-[NSView frame]| is in its superview's coordinates, so a 2053 // Recall that |-[NSView frame]| is in its superview's coordinates, so a
2027 // |TabView|'s frame is in the coordinates of the |TabStripView| (which 2054 // |TabView|'s frame is in the coordinates of the |TabStripView| (which
2028 // matches the coordinate system of |point|). 2055 // matches the coordinate system of |point|).
2029 NSRect frame = [view frame]; 2056 NSRect frame = [view frame];
2030 2057
2031 // Modify the frame to make it "unoverlapped". 2058 // Modify the frame to make it "unoverlapped".
2032 frame.origin.x += kTabOverlap / 2.0; 2059 frame.origin.x += kTabOverlap / 2.0;
2033 frame.size.width -= kTabOverlap; 2060 frame.size.width -= kTabOverlap;
2034 if (frame.size.width < 1.0) 2061 if (frame.size.width < 1.0)
2035 frame.size.width = 1.0; // try to avoid complete failure 2062 frame.size.width = 1.0; // try to avoid complete failure
2036 2063
2037 // Drop in a new tab to the left of tab |i|? 2064 CGFloat rightEdge = NSMaxX(frame) - kLRProportion * frame.size.width;
2038 if (point.x < (frame.origin.x + kLRProportion * frame.size.width)) { 2065 CGFloat leftEdge = frame.origin.x + kLRProportion * frame.size.width;
2066
2067 // Drop in a new tab before tab |i|?
2068 if (isRTL ? point.x > rightEdge : point.x < leftEdge) {
2039 *index = i; 2069 *index = i;
2040 *disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; 2070 *disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
2041 return; 2071 return;
2042 } 2072 }
2043 2073
2044 // Drop on tab |i|? 2074 // Drop on tab |i|?
2045 if (point.x <= (frame.origin.x + 2075 if (isRTL ? point.x >= leftEdge : point.x <= rightEdge) {
2046 (1.0 - kLRProportion) * frame.size.width)) {
2047 *index = i; 2076 *index = i;
2048 *disposition = WindowOpenDisposition::CURRENT_TAB; 2077 *disposition = WindowOpenDisposition::CURRENT_TAB;
2049 return; 2078 return;
2050 } 2079 }
2051 2080
2052 // (Dropping in a new tab to the right of tab |i| will be taken care of in 2081 // (Dropping in a new tab to the right of tab |i| will be taken care of in
2053 // the next iteration.) 2082 // the next iteration.)
2054 i++; 2083 i++;
2055 } 2084 }
2056 2085
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
2213 if (modelIndex < 0) 2242 if (modelIndex < 0)
2214 return nil; 2243 return nil;
2215 NSInteger index = [self indexFromModelIndex:modelIndex]; 2244 NSInteger index = [self indexFromModelIndex:modelIndex];
2216 if (index < 0 || 2245 if (index < 0 ||
2217 index >= (NSInteger)[tabContentsArray_ count]) 2246 index >= (NSInteger)[tabContentsArray_ count])
2218 return nil; 2247 return nil;
2219 return [tabContentsArray_ objectAtIndex:index]; 2248 return [tabContentsArray_ objectAtIndex:index];
2220 } 2249 }
2221 2250
2222 - (void)addCustomWindowControls { 2251 - (void)addCustomWindowControls {
2252 BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout();
2223 if (!customWindowControls_) { 2253 if (!customWindowControls_) {
2224 // Make the container view. 2254 // Make the container view.
2225 CGFloat height = NSHeight([tabStripView_ frame]); 2255 CGFloat height = NSHeight([tabStripView_ frame]);
2226 NSRect frame = NSMakeRect(0, 0, [self leftIndentForControls], height); 2256 CGFloat width = [self leadingIndentForControls];
2257 CGFloat xOrigin = isRTL ? NSWidth([tabStripView_ frame]) - width : 0;
2258 NSRect frame = NSMakeRect(xOrigin, 0, width, height);
2227 customWindowControls_.reset( 2259 customWindowControls_.reset(
2228 [[CustomWindowControlsView alloc] initWithFrame:frame]); 2260 [[CustomWindowControlsView alloc] initWithFrame:frame]);
2229 [customWindowControls_ 2261 [customWindowControls_
2230 setAutoresizingMask:NSViewMaxXMargin | NSViewHeightSizable]; 2262 setAutoresizingMask:isRTL ? NSViewMaxXMargin | NSViewHeightSizable
2263 : NSViewMinXMargin | NSViewHeightSizable];
2231 2264
2232 // Add the traffic light buttons. The horizontal layout was determined by 2265 // Add the traffic light buttons. The horizontal layout was determined by
2233 // manual inspection on Yosemite. 2266 // manual inspection on Yosemite.
2234 CGFloat closeButtonX = 11; 2267 CGFloat closeButtonX = 11;
2235 CGFloat pinnedButtonX = 31; 2268 CGFloat pinnedButtonX = 31;
2236 CGFloat zoomButtonX = 51; 2269 CGFloat zoomButtonX = 51;
2270 if (isRTL)
2271 std::swap(closeButtonX, zoomButtonX);
2237 2272
2238 NSUInteger styleMask = [[tabStripView_ window] styleMask]; 2273 NSUInteger styleMask = [[tabStripView_ window] styleMask];
2239 NSButton* closeButton = [NSWindow standardWindowButton:NSWindowCloseButton 2274 NSButton* closeButton = [NSWindow standardWindowButton:NSWindowCloseButton
2240 forStyleMask:styleMask]; 2275 forStyleMask:styleMask];
2241 2276
2242 // Vertically center the buttons in the tab strip. 2277 // Vertically center the buttons in the tab strip.
2243 CGFloat buttonY = floor((height - NSHeight([closeButton bounds])) / 2); 2278 CGFloat buttonY = floor((height - NSHeight([closeButton bounds])) / 2);
2244 [closeButton setFrameOrigin:NSMakePoint(closeButtonX, buttonY)]; 2279 [closeButton setFrameOrigin:NSMakePoint(closeButtonX, buttonY)];
2245 [customWindowControls_ addSubview:closeButton]; 2280 [customWindowControls_ addSubview:closeButton];
2246 2281
(...skipping 11 matching lines...) Expand all
2258 [zoomButton setFrameOrigin:NSMakePoint(zoomButtonX, buttonY)]; 2293 [zoomButton setFrameOrigin:NSMakePoint(zoomButtonX, buttonY)];
2259 2294
2260 customWindowControlsTrackingArea_.reset([[CrTrackingArea alloc] 2295 customWindowControlsTrackingArea_.reset([[CrTrackingArea alloc]
2261 initWithRect:[customWindowControls_ bounds] 2296 initWithRect:[customWindowControls_ bounds]
2262 options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) 2297 options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways)
2263 owner:self 2298 owner:self
2264 userInfo:nil]); 2299 userInfo:nil]);
2265 [customWindowControls_ 2300 [customWindowControls_
2266 addTrackingArea:customWindowControlsTrackingArea_.get()]; 2301 addTrackingArea:customWindowControlsTrackingArea_.get()];
2267 } 2302 }
2268 2303 if (isRTL &&
2304 NSMaxX([customWindowControls_ frame]) != NSMaxX([tabStripView_ frame])) {
2305 NSRect frame = [customWindowControls_ frame];
2306 frame.origin.x =
2307 NSMaxX([tabStripView_ frame]) - [self leadingIndentForControls];
2308 [customWindowControls_ setFrame:frame];
2309 }
2269 if (![permanentSubviews_ containsObject:customWindowControls_]) { 2310 if (![permanentSubviews_ containsObject:customWindowControls_]) {
2270 [self addSubviewToPermanentList:customWindowControls_]; 2311 [self addSubviewToPermanentList:customWindowControls_];
2271 [self regenerateSubviewList]; 2312 [self regenerateSubviewList];
2272 } 2313 }
2273 } 2314 }
2274 2315
2275 - (void)removeCustomWindowControls { 2316 - (void)removeCustomWindowControls {
2276 if (customWindowControls_) 2317 if (customWindowControls_)
2277 [permanentSubviews_ removeObject:customWindowControls_]; 2318 [permanentSubviews_ removeObject:customWindowControls_];
2278 [self regenerateSubviewList]; 2319 [self regenerateSubviewList];
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2338 for (int i = 0; i < tabStripModel_->count(); i++) { 2379 for (int i = 0; i < tabStripModel_->count(); i++) {
2339 [self updateIconsForContents:tabStripModel_->GetWebContentsAt(i) atIndex:i]; 2380 [self updateIconsForContents:tabStripModel_->GetWebContentsAt(i) atIndex:i];
2340 } 2381 }
2341 } 2382 }
2342 2383
2343 - (void)setVisualEffectsDisabledForFullscreen:(BOOL)fullscreen { 2384 - (void)setVisualEffectsDisabledForFullscreen:(BOOL)fullscreen {
2344 [tabStripView_ setVisualEffectsDisabledForFullscreen:fullscreen]; 2385 [tabStripView_ setVisualEffectsDisabledForFullscreen:fullscreen];
2345 } 2386 }
2346 2387
2347 @end 2388 @end
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/tabs/tab_strip_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698