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

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

Issue 1119005: [Mac] Re-enable pinned tabs; add support for mini-tabs and phantom tabs. (Closed)
Patch Set: Nits Created 10 years, 9 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) 2010 The Chromium Authors. All rights reserved. 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 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/cocoa/tab_strip_controller.h" 5 #import "chrome/browser/cocoa/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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 - (void)regenerateSubviewList; 116 - (void)regenerateSubviewList;
117 - (NSInteger)indexForContentsView:(NSView*)view; 117 - (NSInteger)indexForContentsView:(NSView*)view;
118 - (void)updateFavIconForContents:(TabContents*)contents 118 - (void)updateFavIconForContents:(TabContents*)contents
119 atIndex:(NSInteger)modelIndex; 119 atIndex:(NSInteger)modelIndex;
120 - (void)layoutTabsWithAnimation:(BOOL)animate 120 - (void)layoutTabsWithAnimation:(BOOL)animate
121 regenerateSubviews:(BOOL)doUpdate; 121 regenerateSubviews:(BOOL)doUpdate;
122 - (void)animationDidStopForController:(TabController*)controller 122 - (void)animationDidStopForController:(TabController*)controller
123 finished:(BOOL)finished; 123 finished:(BOOL)finished;
124 - (NSInteger)indexFromModelIndex:(NSInteger)index; 124 - (NSInteger)indexFromModelIndex:(NSInteger)index;
125 - (NSInteger)numberOfOpenTabs; 125 - (NSInteger)numberOfOpenTabs;
126 - (NSInteger)numberOfOpenPinnedTabs; 126 - (NSInteger)numberOfOpenMiniTabs;
127 - (NSInteger)numberOfOpenUnpinnedTabs; 127 - (NSInteger)numberOfOpenNonMiniTabs;
128 - (void)mouseMoved:(NSEvent*)event; 128 - (void)mouseMoved:(NSEvent*)event;
129 - (void)setTabTrackingAreasEnabled:(BOOL)enabled; 129 - (void)setTabTrackingAreasEnabled:(BOOL)enabled;
130 - (void)droppingURLsAt:(NSPoint)point 130 - (void)droppingURLsAt:(NSPoint)point
131 givesIndex:(NSInteger*)index 131 givesIndex:(NSInteger*)index
132 disposition:(WindowOpenDisposition*)disposition; 132 disposition:(WindowOpenDisposition*)disposition;
133 @end 133 @end
134 134
135 // A simple view class that prevents the Window Server from dragging the area 135 // A simple view class that prevents the Window Server from dragging the area
136 // behind tabs. Sometimes core animation confuses it. Unfortunately, it can also 136 // behind tabs. Sometimes core animation confuses it. Unfortunately, it can also
137 // falsely pick up clicks during rapid tab closure, so we have to account for 137 // falsely pick up clicks during rapid tab closure, so we have to account for
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 return controller; 455 return controller;
456 } 456 }
457 457
458 // (Private) Returns the number of open tabs in the tab strip. This is the 458 // (Private) Returns the number of open tabs in the tab strip. This is the
459 // number of TabControllers we know about (as there's a 1-to-1 mapping from 459 // number of TabControllers we know about (as there's a 1-to-1 mapping from
460 // these controllers to a tab) less the number of closing tabs. 460 // these controllers to a tab) less the number of closing tabs.
461 - (NSInteger)numberOfOpenTabs { 461 - (NSInteger)numberOfOpenTabs {
462 return static_cast<NSInteger>(tabStripModel_->count()); 462 return static_cast<NSInteger>(tabStripModel_->count());
463 } 463 }
464 464
465 // (Private) Returns the number of open, pinned tabs. 465 // (Private) Returns the number of open, mini-tabs.
466 - (NSInteger)numberOfOpenPinnedTabs { 466 - (NSInteger)numberOfOpenMiniTabs {
467 // Ask the model for the number of pinned tabs. Note that tabs which are in 467 // Ask the model for the number of mini tabs. Note that tabs which are in
468 // the process of closing (i.e., whose controllers are in 468 // the process of closing (i.e., whose controllers are in
469 // |closingControllers_|) have already been removed from the model. 469 // |closingControllers_|) have already been removed from the model.
470 // TODO: convert to apps. 470 return tabStripModel_->IndexOfFirstNonMiniTab();
471 return 0;
472 } 471 }
473 472
474 // (Private) Returns the number of open, unpinned tabs. 473 // (Private) Returns the number of open, non-mini tabs.
475 - (NSInteger)numberOfOpenUnpinnedTabs { 474 - (NSInteger)numberOfOpenNonMiniTabs {
476 NSInteger number = [self numberOfOpenTabs] - [self numberOfOpenPinnedTabs]; 475 NSInteger number = [self numberOfOpenTabs] - [self numberOfOpenMiniTabs];
477 DCHECK_GE(number, 0); 476 DCHECK_GE(number, 0);
478 return number; 477 return number;
479 } 478 }
480 479
481 // Given an index into the tab model, returns the index into the tab controller 480 // Given an index into the tab model, returns the index into the tab controller
482 // or tab contents controller array accounting for tabs that are currently 481 // or tab contents controller array accounting for tabs that are currently
483 // closing. For example, if there are two tabs in the process of closing before 482 // closing. For example, if there are two tabs in the process of closing before
484 // |index|, this returns |index| + 2. If there are no closing tabs, this will 483 // |index|, this returns |index| + 2. If there are no closing tabs, this will
485 // return |index|. 484 // return |index|.
486 - (NSInteger)indexFromModelIndex:(NSInteger)index { 485 - (NSInteger)indexFromModelIndex:(NSInteger)index {
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 // tabs would cause an overflow. http://crbug.com/188 646 // tabs would cause an overflow. http://crbug.com/188
648 - (void)layoutTabsWithAnimation:(BOOL)animate 647 - (void)layoutTabsWithAnimation:(BOOL)animate
649 regenerateSubviews:(BOOL)doUpdate { 648 regenerateSubviews:(BOOL)doUpdate {
650 DCHECK([NSThread isMainThread]); 649 DCHECK([NSThread isMainThread]);
651 if (![tabArray_ count]) 650 if (![tabArray_ count])
652 return; 651 return;
653 652
654 const CGFloat kMaxTabWidth = [TabController maxTabWidth]; 653 const CGFloat kMaxTabWidth = [TabController maxTabWidth];
655 const CGFloat kMinTabWidth = [TabController minTabWidth]; 654 const CGFloat kMinTabWidth = [TabController minTabWidth];
656 const CGFloat kMinSelectedTabWidth = [TabController minSelectedTabWidth]; 655 const CGFloat kMinSelectedTabWidth = [TabController minSelectedTabWidth];
657 const CGFloat kPinnedTabWidth = [TabController pinnedTabWidth]; 656 const CGFloat kMiniTabWidth = [TabController miniTabWidth];
658 657
659 NSRect enclosingRect = NSZeroRect; 658 NSRect enclosingRect = NSZeroRect;
660 ScopedNSAnimationContextGroup mainAnimationGroup(animate); 659 ScopedNSAnimationContextGroup mainAnimationGroup(animate);
661 mainAnimationGroup.SetCurrentContextDuration(kAnimationDuration); 660 mainAnimationGroup.SetCurrentContextDuration(kAnimationDuration);
662 661
663 // Update the current subviews and their z-order if requested. 662 // Update the current subviews and their z-order if requested.
664 if (doUpdate) 663 if (doUpdate)
665 [self regenerateSubviewList]; 664 [self regenerateSubviewList];
666 665
667 // Compute the base width of tabs given how much room we're allowed. Note that 666 // Compute the base width of tabs given how much room we're allowed. Note that
668 // pinned tabs have a fixed width. We may not be able to use the entire width 667 // mini-tabs have a fixed width. We may not be able to use the entire width
669 // if the user is quickly closing tabs. This may be negative, but that's okay 668 // if the user is quickly closing tabs. This may be negative, but that's okay
670 // (taken care of by |MAX()| when calculating tab sizes). 669 // (taken care of by |MAX()| when calculating tab sizes).
671 CGFloat availableWidth = 0; 670 CGFloat availableWidth = 0;
672 if ([self inRapidClosureMode]) { 671 if ([self inRapidClosureMode]) {
673 availableWidth = availableResizeWidth_; 672 availableWidth = availableResizeWidth_;
674 } else { 673 } else {
675 availableWidth = NSWidth([tabStripView_ frame]); 674 availableWidth = NSWidth([tabStripView_ frame]);
676 // Account for the new tab button and the incognito badge. 675 // Account for the new tab button and the incognito badge.
677 availableWidth -= NSWidth([newTabButton_ frame]) + kNewTabButtonOffset; 676 availableWidth -= NSWidth([newTabButton_ frame]) + kNewTabButtonOffset;
678 if (browser_->profile()->IsOffTheRecord()) 677 if (browser_->profile()->IsOffTheRecord())
679 availableWidth -= kIncognitoBadgeTabStripShrink; 678 availableWidth -= kIncognitoBadgeTabStripShrink;
680 } 679 }
681 availableWidth -= [self indentForControls]; 680 availableWidth -= [self indentForControls];
682 681
683 // This may be negative, but that's okay (taken care of by |MAX()| when 682 // This may be negative, but that's okay (taken care of by |MAX()| when
684 // calculating tab sizes). 683 // calculating tab sizes).
685 CGFloat availableWidthForUnpinned = availableWidth - 684 CGFloat availableWidthForNonMini = availableWidth -
686 [self numberOfOpenPinnedTabs] * (kPinnedTabWidth - kTabOverlap); 685 [self numberOfOpenMiniTabs] * (kMiniTabWidth - kTabOverlap);
687 686
688 // Initialize |unpinnedTabWidth| in case there aren't any unpinned tabs; this 687 // Initialize |nonMiniTabWidth| in case there aren't any non-mini-tabs; this
689 // value shouldn't actually be used. 688 // value shouldn't actually be used.
690 CGFloat unpinnedTabWidth = kMaxTabWidth; 689 CGFloat nonMiniTabWidth = kMaxTabWidth;
691 const NSInteger numberOfOpenUnpinnedTabs = [self numberOfOpenUnpinnedTabs]; 690 const NSInteger numberOfOpenNonMiniTabs = [self numberOfOpenNonMiniTabs];
692 if (numberOfOpenUnpinnedTabs) { // Find the width of an unpinned tab. 691 if (numberOfOpenNonMiniTabs) { // Find the width of a non-mini-tab.
693 // Add in the amount we "get back" from the tabs overlapping. 692 // Add in the amount we "get back" from the tabs overlapping.
694 availableWidthForUnpinned += (numberOfOpenUnpinnedTabs - 1) * kTabOverlap; 693 availableWidthForNonMini += (numberOfOpenNonMiniTabs - 1) * kTabOverlap;
695 694
696 // Divide up the space between the unpinned tabs. 695 // Divide up the space between the non-mini-tabs.
697 unpinnedTabWidth = availableWidthForUnpinned / numberOfOpenUnpinnedTabs; 696 nonMiniTabWidth = availableWidthForNonMini / numberOfOpenNonMiniTabs;
698 697
699 // Clamp the width between the max and min. 698 // Clamp the width between the max and min.
700 unpinnedTabWidth = MAX(MIN(unpinnedTabWidth, kMaxTabWidth), kMinTabWidth); 699 nonMiniTabWidth = MAX(MIN(nonMiniTabWidth, kMaxTabWidth), kMinTabWidth);
701 } 700 }
702 701
703 const CGFloat minX = NSMinX(placeholderFrame_); 702 const CGFloat minX = NSMinX(placeholderFrame_);
704 BOOL visible = [[tabStripView_ window] isVisible]; 703 BOOL visible = [[tabStripView_ window] isVisible];
705 704
706 CGFloat offset = [self indentForControls]; 705 CGFloat offset = [self indentForControls];
707 NSUInteger i = 0; 706 NSUInteger i = 0;
708 bool hasPlaceholderGap = false; 707 bool hasPlaceholderGap = false;
709 for (TabController* tab in tabArray_.get()) { 708 for (TabController* tab in tabArray_.get()) {
710 // Ignore a tab that is going through a close animation. 709 // Ignore a tab that is going through a close animation.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 // to the right of it we should slide over to make space for it. 745 // to the right of it we should slide over to make space for it.
747 if (placeholderTab_ && !hasPlaceholderGap && NSMidX(tabFrame) > minX) { 746 if (placeholderTab_ && !hasPlaceholderGap && NSMidX(tabFrame) > minX) {
748 hasPlaceholderGap = true; 747 hasPlaceholderGap = true;
749 offset += NSWidth(placeholderFrame_); 748 offset += NSWidth(placeholderFrame_);
750 offset -= kTabOverlap; 749 offset -= kTabOverlap;
751 tabFrame.origin.x = offset; 750 tabFrame.origin.x = offset;
752 } 751 }
753 752
754 // Set the width. Selected tabs are slightly wider when things get really 753 // Set the width. Selected tabs are slightly wider when things get really
755 // small and thus we enforce a different minimum width. 754 // small and thus we enforce a different minimum width.
756 tabFrame.size.width = [tab pinned] ? kPinnedTabWidth : unpinnedTabWidth; 755 tabFrame.size.width = [tab mini] ? kMiniTabWidth : nonMiniTabWidth;
757 if ([tab selected]) 756 if ([tab selected])
758 tabFrame.size.width = MAX(tabFrame.size.width, kMinSelectedTabWidth); 757 tabFrame.size.width = MAX(tabFrame.size.width, kMinSelectedTabWidth);
759 758
760 // Animate a new tab in by putting it below the horizon unless told to put 759 // Animate a new tab in by putting it below the horizon unless told to put
761 // it in a specific location (i.e., from a drop). 760 // it in a specific location (i.e., from a drop).
762 if (newTab && visible && animate) { 761 if (newTab && visible && animate) {
763 if (NSEqualRects(droppedTabFrame_, NSZeroRect)) { 762 if (NSEqualRects(droppedTabFrame_, NSZeroRect)) {
764 [[tab view] setFrame:NSOffsetRect(tabFrame, 0, -NSHeight(tabFrame))]; 763 [[tab view] setFrame:NSOffsetRect(tabFrame, 0, -NSHeight(tabFrame))];
765 } else { 764 } else {
766 [[tab view] setFrame:droppedTabFrame_]; 765 [[tab view] setFrame:droppedTabFrame_];
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 // Make a new tab. Load the contents of this tab from the nib and associate 876 // Make a new tab. Load the contents of this tab from the nib and associate
878 // the new controller with |contents| so it can be looked up later. 877 // the new controller with |contents| so it can be looked up later.
879 TabContentsController* contentsController = 878 TabContentsController* contentsController =
880 [[[TabContentsController alloc] initWithNibName:@"TabContents" 879 [[[TabContentsController alloc] initWithNibName:@"TabContents"
881 contents:contents] 880 contents:contents]
882 autorelease]; 881 autorelease];
883 [tabContentsArray_ insertObject:contentsController atIndex:index]; 882 [tabContentsArray_ insertObject:contentsController atIndex:index];
884 883
885 // Make a new tab and add it to the strip. Keep track of its controller. 884 // Make a new tab and add it to the strip. Keep track of its controller.
886 TabController* newController = [self newTab]; 885 TabController* newController = [self newTab];
886 [newController setMini:tabStripModel_->IsMiniTab(modelIndex)];
887 [tabArray_ insertObject:newController atIndex:index]; 887 [tabArray_ insertObject:newController atIndex:index];
888 NSView* newView = [newController view]; 888 NSView* newView = [newController view];
889 889
890 // Set the originating frame to just below the strip so that it animates 890 // Set the originating frame to just below the strip so that it animates
891 // upwards as it's being initially layed out. Oddly, this works while doing 891 // upwards as it's being initially layed out. Oddly, this works while doing
892 // something similar in |-layoutTabs| confuses the window server. 892 // something similar in |-layoutTabs| confuses the window server.
893 [newView setFrame:NSOffsetRect([newView frame], 893 [newView setFrame:NSOffsetRect([newView frame],
894 0, -[[self class] defaultTabHeight])]; 894 0, -[[self class] defaultTabHeight])];
895 895
896 [self setTabTitle:newController withContents:contents]; 896 [self setTabTitle:newController withContents:contents];
(...skipping 24 matching lines...) Expand all
921 921
922 // Called when a notification is received from the model to select a particular 922 // Called when a notification is received from the model to select a particular
923 // tab. Swaps in the toolbar and content area associated with |newContents|. 923 // tab. Swaps in the toolbar and content area associated with |newContents|.
924 - (void)selectTabWithContents:(TabContents*)newContents 924 - (void)selectTabWithContents:(TabContents*)newContents
925 previousContents:(TabContents*)oldContents 925 previousContents:(TabContents*)oldContents
926 atIndex:(NSInteger)modelIndex 926 atIndex:(NSInteger)modelIndex
927 userGesture:(bool)wasUserGesture { 927 userGesture:(bool)wasUserGesture {
928 // Take closing tabs into account. 928 // Take closing tabs into account.
929 NSInteger index = [self indexFromModelIndex:modelIndex]; 929 NSInteger index = [self indexFromModelIndex:modelIndex];
930 930
931 if (oldContents) {
932 int oldModelIndex =
933 browser_->GetIndexOfController(&(oldContents->controller()));
934 if (oldModelIndex != -1) { // When closing a tab, the old tab may be gone.
935 NSInteger oldIndex = [self indexFromModelIndex:oldModelIndex];
936 TabContentsController* oldController =
937 [tabContentsArray_ objectAtIndex:oldIndex];
938 [oldController willBecomeUnselectedTab];
939 oldContents->view()->StoreFocus();
940 oldContents->WasHidden();
941 // If the selection changed because the tab was made phantom, update the
942 // Cocoa side of the state.
943 TabController* tabController = [tabArray_ objectAtIndex:oldIndex];
944 [tabController setPhantom:tabStripModel_->IsPhantomTab(oldModelIndex)];
945 }
946 }
947
931 // De-select all other tabs and select the new tab. 948 // De-select all other tabs and select the new tab.
932 int i = 0; 949 int i = 0;
933 for (TabController* current in tabArray_.get()) { 950 for (TabController* current in tabArray_.get()) {
934 [current setSelected:(i == index) ? YES : NO]; 951 [current setSelected:(i == index) ? YES : NO];
935 ++i; 952 ++i;
936 } 953 }
937 954
938 // Tell the new tab contents it is about to become the selected tab. Here it 955 // Tell the new tab contents it is about to become the selected tab. Here it
939 // can do things like make sure the toolbar is up to date. 956 // can do things like make sure the toolbar is up to date.
940 TabContentsController* newController = 957 TabContentsController* newController =
941 [tabContentsArray_ objectAtIndex:index]; 958 [tabContentsArray_ objectAtIndex:index];
942 [newController willBecomeSelectedTab]; 959 [newController willBecomeSelectedTab];
943 960
944 // Relayout for new tabs and to let the selected tab grow to be larger in 961 // Relayout for new tabs and to let the selected tab grow to be larger in
945 // size than surrounding tabs if the user has many. This also raises the 962 // size than surrounding tabs if the user has many. This also raises the
946 // selected tab to the top. 963 // selected tab to the top.
947 [self layoutTabs]; 964 [self layoutTabs];
948 965
949 if (oldContents) {
950 int oldModelIndex =
951 browser_->GetIndexOfController(&(oldContents->controller()));
952 if (oldModelIndex != -1) { // When closing a tab, the old tab may be gone.
953 NSInteger oldIndex = [self indexFromModelIndex:oldModelIndex];
954 TabContentsController* oldController =
955 [tabContentsArray_ objectAtIndex:oldIndex];
956 [oldController willBecomeUnselectedTab];
957 oldContents->view()->StoreFocus();
958 oldContents->WasHidden();
959 }
960 }
961
962 // Swap in the contents for the new tab. 966 // Swap in the contents for the new tab.
963 [self swapInTabAtIndex:modelIndex]; 967 [self swapInTabAtIndex:modelIndex];
964 [self updateDevToolsForContents:newContents]; 968 [self updateDevToolsForContents:newContents];
965 969
966 if (newContents) { 970 if (newContents) {
967 newContents->DidBecomeSelected(); 971 newContents->DidBecomeSelected();
968 newContents->view()->RestoreFocus(); 972 newContents->view()->RestoreFocus();
969 973
970 if (newContents->find_ui_active()) 974 if (newContents->find_ui_active())
971 browser_->GetFindBarController()->find_bar()->SetFocusAndSelection(); 975 browser_->GetFindBarController()->find_bar()->SetFocusAndSelection();
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 retain]; 1121 retain];
1118 static NSImage* sadFaviconImage = 1122 static NSImage* sadFaviconImage =
1119 [ResourceBundle::GetSharedInstance().GetNSImageNamed(IDR_SAD_FAVICON) 1123 [ResourceBundle::GetSharedInstance().GetNSImageNamed(IDR_SAD_FAVICON)
1120 retain]; 1124 retain];
1121 1125
1122 // Take closing tabs into account. 1126 // Take closing tabs into account.
1123 NSInteger index = [self indexFromModelIndex:modelIndex]; 1127 NSInteger index = [self indexFromModelIndex:modelIndex];
1124 1128
1125 TabController* tabController = [tabArray_ objectAtIndex:index]; 1129 TabController* tabController = [tabArray_ objectAtIndex:index];
1126 1130
1131 // Since the tab is loading, it cannot be phantom any more.
1132 if ([tabController phantom]) {
1133 [tabController setPhantom:NO];
1134 [[tabController view] setNeedsDisplay:YES];
1135 }
1136
1127 bool oldHasIcon = [tabController iconView] != nil; 1137 bool oldHasIcon = [tabController iconView] != nil;
1128 bool newHasIcon = contents->ShouldDisplayFavIcon() || 1138 bool newHasIcon = contents->ShouldDisplayFavIcon() ||
1129 tabStripModel_->IsTabPinned(modelIndex); // always show icon if pinned 1139 tabStripModel_->IsMiniTab(modelIndex); // Always show icon if mini.
1130 1140
1131 TabLoadingState oldState = [tabController loadingState]; 1141 TabLoadingState oldState = [tabController loadingState];
1132 TabLoadingState newState = kTabDone; 1142 TabLoadingState newState = kTabDone;
1133 NSImage* throbberImage = nil; 1143 NSImage* throbberImage = nil;
1134 if (contents->is_crashed()) { 1144 if (contents->is_crashed()) {
1135 newState = kTabCrashed; 1145 newState = kTabCrashed;
1136 newHasIcon = true; 1146 newHasIcon = true;
1137 } else if (contents->waiting_for_response()) { 1147 } else if (contents->waiting_for_response()) {
1138 newState = kTabWaiting; 1148 newState = kTabWaiting;
1139 throbberImage = throbberWaitingImage; 1149 throbberImage = throbberWaitingImage;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 changeType:(TabStripModelObserver::TabChangeType)change { 1190 changeType:(TabStripModelObserver::TabChangeType)change {
1181 // Take closing tabs into account. 1191 // Take closing tabs into account.
1182 NSInteger index = [self indexFromModelIndex:modelIndex]; 1192 NSInteger index = [self indexFromModelIndex:modelIndex];
1183 1193
1184 if (change == TabStripModelObserver::TITLE_NOT_LOADING) { 1194 if (change == TabStripModelObserver::TITLE_NOT_LOADING) {
1185 // TODO(sky): make this work. 1195 // TODO(sky): make this work.
1186 // We'll receive another notification of the change asynchronously. 1196 // We'll receive another notification of the change asynchronously.
1187 return; 1197 return;
1188 } 1198 }
1189 1199
1200 TabController* tabController = [tabArray_ objectAtIndex:index];
1201
1190 if (change != TabStripModelObserver::LOADING_ONLY) 1202 if (change != TabStripModelObserver::LOADING_ONLY)
1191 [self setTabTitle:[tabArray_ objectAtIndex:index] withContents:contents]; 1203 [self setTabTitle:tabController withContents:contents];
1204
1205 // See if the change was to/from phantom.
1206 bool isPhantom = tabStripModel_->IsPhantomTab(modelIndex);
1207 if (isPhantom != [tabController phantom])
1208 [tabController setPhantom:isPhantom];
1192 1209
1193 [self updateFavIconForContents:contents atIndex:modelIndex]; 1210 [self updateFavIconForContents:contents atIndex:modelIndex];
1194 1211
1195 TabContentsController* updatedController = 1212 TabContentsController* updatedController =
1196 [tabContentsArray_ objectAtIndex:index]; 1213 [tabContentsArray_ objectAtIndex:index];
1197 [updatedController tabDidChange:contents]; 1214 [updatedController tabDidChange:contents];
1198 } 1215 }
1199 1216
1200 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays 1217 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays
1201 // in sync with the tab strip model. It can also be pinned/unpinned 1218 // in sync with the tab strip model. It can also be pinned/unpinned
1202 // simultaneously, so we need to take care of that. 1219 // simultaneously, so we need to take care of that.
1203 - (void)tabMovedWithContents:(TabContents*)contents 1220 - (void)tabMovedWithContents:(TabContents*)contents
1204 fromIndex:(NSInteger)modelFrom 1221 fromIndex:(NSInteger)modelFrom
1205 toIndex:(NSInteger)modelTo 1222 toIndex:(NSInteger)modelTo {
1206 pinnedStateChanged:(BOOL)pinnedChanged {
1207 // Take closing tabs into account. 1223 // Take closing tabs into account.
1208 NSInteger from = [self indexFromModelIndex:modelFrom]; 1224 NSInteger from = [self indexFromModelIndex:modelFrom];
1209 NSInteger to = [self indexFromModelIndex:modelTo]; 1225 NSInteger to = [self indexFromModelIndex:modelTo];
1210 1226
1211 scoped_nsobject<TabContentsController> movedTabContentsController( 1227 scoped_nsobject<TabContentsController> movedTabContentsController(
1212 [[tabContentsArray_ objectAtIndex:from] retain]); 1228 [[tabContentsArray_ objectAtIndex:from] retain]);
1213 [tabContentsArray_ removeObjectAtIndex:from]; 1229 [tabContentsArray_ removeObjectAtIndex:from];
1214 [tabContentsArray_ insertObject:movedTabContentsController.get() 1230 [tabContentsArray_ insertObject:movedTabContentsController.get()
1215 atIndex:to]; 1231 atIndex:to];
1216 scoped_nsobject<TabController> movedTabController( 1232 scoped_nsobject<TabController> movedTabController(
1217 [[tabArray_ objectAtIndex:from] retain]); 1233 [[tabArray_ objectAtIndex:from] retain]);
1218 DCHECK([movedTabController isKindOfClass:[TabController class]]); 1234 DCHECK([movedTabController isKindOfClass:[TabController class]]);
1219 [tabArray_ removeObjectAtIndex:from]; 1235 [tabArray_ removeObjectAtIndex:from];
1220 [tabArray_ insertObject:movedTabController.get() atIndex:to]; 1236 [tabArray_ insertObject:movedTabController.get() atIndex:to];
1221 1237
1222 if (pinnedChanged) { 1238 // The tab moved, which means that the mini-tab state may have changed.
1223 [movedTabController 1239 if (tabStripModel_->IsMiniTab(modelTo) != [movedTabController mini])
1224 setPinned:(tabStripModel_->IsTabPinned(modelTo) ? YES : NO)]; 1240 [self tabMiniStateChangedWithContents:contents atIndex:modelTo];
1225 [self updateFavIconForContents:contents atIndex:modelTo];
1226 }
1227
1228 // TODO(viettrungluu): I don't think this is needed. Investigate. See also
1229 // |-tabPinnedStateChangedWithContents:...|.
1230 [self layoutTabs];
1231 } 1241 }
1232 1242
1233 // Called when a tab is pinned or unpinned without moving. 1243 // Called when a tab is pinned or unpinned without moving.
1234 - (void)tabPinnedStateChangedWithContents:(TabContents*)contents 1244 - (void)tabMiniStateChangedWithContents:(TabContents*)contents
1235 atIndex:(NSInteger)modelIndex { 1245 atIndex:(NSInteger)modelIndex {
1236 // Take closing tabs into account. 1246 // Take closing tabs into account.
1237 NSInteger index = [self indexFromModelIndex:modelIndex]; 1247 NSInteger index = [self indexFromModelIndex:modelIndex];
1238 1248
1239 TabController* tabController = [tabArray_ objectAtIndex:index]; 1249 TabController* tabController = [tabArray_ objectAtIndex:index];
1240 DCHECK([tabController isKindOfClass:[TabController class]]); 1250 DCHECK([tabController isKindOfClass:[TabController class]]);
1241 [tabController setPinned: 1251 [tabController setMini:
1242 (tabStripModel_->IsTabPinned(modelIndex) ? YES : NO)]; 1252 (tabStripModel_->IsMiniTab(modelIndex) ? YES : NO)];
1243 [self updateFavIconForContents:contents atIndex:modelIndex]; 1253 [self updateFavIconForContents:contents atIndex:modelIndex];
1244
1245 // TODO(viettrungluu): I don't think this is needed. Investigate. See also
1246 // |-tabMovedWithContents:...|.
1247 [self layoutTabs];
1248 } 1254 }
1249 1255
1250 - (void)setFrameOfSelectedTab:(NSRect)frame { 1256 - (void)setFrameOfSelectedTab:(NSRect)frame {
1251 NSView* view = [self selectedTabView]; 1257 NSView* view = [self selectedTabView];
1252 NSValue* identifier = [NSValue valueWithPointer:view]; 1258 NSValue* identifier = [NSValue valueWithPointer:view];
1253 [targetFrames_ setObject:[NSValue valueWithRect:frame] 1259 [targetFrames_ setObject:[NSValue valueWithRect:frame]
1254 forKey:identifier]; 1260 forKey:identifier];
1255 [view setFrame:frame]; 1261 [view setFrame:frame];
1256 } 1262 }
1257 1263
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1303 - (void)moveTabFromIndex:(NSInteger)from { 1309 - (void)moveTabFromIndex:(NSInteger)from {
1304 int toIndex = [self indexOfPlaceholder]; 1310 int toIndex = [self indexOfPlaceholder];
1305 tabStripModel_->MoveTabContentsAt(from, toIndex, true); 1311 tabStripModel_->MoveTabContentsAt(from, toIndex, true);
1306 } 1312 }
1307 1313
1308 // Drop a given TabContents at the location of the current placeholder. If there 1314 // Drop a given TabContents at the location of the current placeholder. If there
1309 // is no placeholder, it will go at the end. Used when dragging from another 1315 // is no placeholder, it will go at the end. Used when dragging from another
1310 // window when we don't have access to the TabContents as part of our strip. 1316 // window when we don't have access to the TabContents as part of our strip.
1311 // |frame| is in the coordinate system of the tab strip view and represents 1317 // |frame| is in the coordinate system of the tab strip view and represents
1312 // where the user dropped the new tab so it can be animated into its correct 1318 // where the user dropped the new tab so it can be animated into its correct
1313 // location when the tab is added to the model. 1319 // location when the tab is added to the model. If the tab was pinned in its
1314 - (void)dropTabContents:(TabContents*)contents withFrame:(NSRect)frame { 1320 // previous window, setting |pinned| to YES will propagate that state to the
1321 // new window. Mini-tabs are either app or pinned tabs; the app state is stored
1322 // by the |contents|, but the |pinned| state is the caller's responsibility.
1323 - (void)dropTabContents:(TabContents*)contents
1324 withFrame:(NSRect)frame
1325 asPinnedTab:(BOOL)pinned {
1315 int modelIndex = [self indexOfPlaceholder]; 1326 int modelIndex = [self indexOfPlaceholder];
1316 1327
1317 // Mark that the new tab being created should start at |frame|. It will be 1328 // Mark that the new tab being created should start at |frame|. It will be
1318 // reset as soon as the tab has been positioned. 1329 // reset as soon as the tab has been positioned.
1319 droppedTabFrame_ = frame; 1330 droppedTabFrame_ = frame;
1320 1331
1321 // Insert it into this tab strip. We want it in the foreground and to not 1332 // Insert it into this tab strip. We want it in the foreground and to not
1322 // inherit the current tab's group. 1333 // inherit the current tab's group.
1323 tabStripModel_->InsertTabContentsAt(modelIndex, contents, true, false); 1334 tabStripModel_->InsertTabContentsAt(modelIndex, contents, true, false,
1324 1335 pinned);
1325 // Take closing tabs into account.
1326 NSInteger index = [self indexFromModelIndex:modelIndex];
1327
1328 // The tab's pinned status may have changed.
1329 // TODO(viettrungluu): Improve the behaviour for drops at the dividing point
1330 // between pinned and unpinned tabs.
1331 TabController* tabController = [tabArray_ objectAtIndex:index];
1332 DCHECK([tabController isKindOfClass:[TabController class]]);
1333 [tabController setPinned:
1334 (tabStripModel_->IsTabPinned(modelIndex) ? YES : NO)];
1335 [self updateFavIconForContents:contents atIndex:modelIndex];
1336 } 1336 }
1337 1337
1338 // Called when the tab strip view changes size. As we only registered for 1338 // Called when the tab strip view changes size. As we only registered for
1339 // changes on our view, we know it's only for our view. Layout w/out 1339 // changes on our view, we know it's only for our view. Layout w/out
1340 // animations since they are blocked by the resize nested runloop. We need 1340 // animations since they are blocked by the resize nested runloop. We need
1341 // the views to adjust immediately. Neither the tabs nor their z-order are 1341 // the views to adjust immediately. Neither the tabs nor their z-order are
1342 // changed, so we don't need to update the subviews. 1342 // changed, so we don't need to update the subviews.
1343 - (void)tabViewFrameChanged:(NSNotification*)info { 1343 - (void)tabViewFrameChanged:(NSNotification*)info {
1344 [self layoutTabsWithAnimation:NO regenerateSubviews:NO]; 1344 [self layoutTabsWithAnimation:NO regenerateSubviews:NO];
1345 } 1345 }
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 return; 1730 return;
1731 1731
1732 TabContentsController* tabController = 1732 TabContentsController* tabController =
1733 [tabContentsArray_ objectAtIndex:index]; 1733 [tabContentsArray_ objectAtIndex:index];
1734 TabContents* devtoolsContents = contents ? 1734 TabContents* devtoolsContents = contents ?
1735 DevToolsWindow::GetDevToolsContents(contents) : NULL; 1735 DevToolsWindow::GetDevToolsContents(contents) : NULL;
1736 [tabController showDevToolsContents:devtoolsContents]; 1736 [tabController showDevToolsContents:devtoolsContents];
1737 } 1737 }
1738 1738
1739 @end 1739 @end
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/tab_strip_controller.h ('k') | chrome/browser/cocoa/tab_strip_model_observer_bridge.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698