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

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

Issue 181002: Reverting 24700. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 3 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/cocoa/tab_strip_controller.h ('k') | chrome/browser/cocoa/tab_strip_view.mm » ('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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "base/mac_util.h" 8 #include "base/mac_util.h"
9 #include "base/sys_string_conversions.h" 9 #include "base/sys_string_conversions.h"
10 #include "chrome/app/chrome_dll_resource.h" 10 #include "chrome/app/chrome_dll_resource.h"
(...skipping 29 matching lines...) Expand all
40 // A simple view class that prevents the windowserver from dragging the 40 // A simple view class that prevents the windowserver from dragging the
41 // area behind tabs. Sometimes core animation confuses it. 41 // area behind tabs. Sometimes core animation confuses it.
42 @interface TabStripControllerDragBlockingView : NSView 42 @interface TabStripControllerDragBlockingView : NSView
43 @end 43 @end
44 @implementation TabStripControllerDragBlockingView 44 @implementation TabStripControllerDragBlockingView
45 - (BOOL)mouseDownCanMoveWindow {return NO;} 45 - (BOOL)mouseDownCanMoveWindow {return NO;}
46 - (void)drawRect:(NSRect)rect {} 46 - (void)drawRect:(NSRect)rect {}
47 @end 47 @end
48 48
49 @interface TabStripController(Private) 49 @interface TabStripController(Private)
50 - (void)installTrackingArea;
50 - (BOOL)useFullWidthForLayout; 51 - (BOOL)useFullWidthForLayout;
51 - (void)addSubviewToPermanentList:(NSView*)aView; 52 - (void)addSubviewToPermanentList:(NSView*)aView;
52 - (void)regenerateSubviewList; 53 - (void)regenerateSubviewList;
53 - (NSInteger)indexForContentsView:(NSView*)view; 54 - (NSInteger)indexForContentsView:(NSView*)view;
54 - (void)updateFavIconForContents:(TabContents*)contents 55 - (void)updateFavIconForContents:(TabContents*)contents
55 atIndex:(NSInteger)index; 56 atIndex:(NSInteger)index;
56 @end 57 @end
57 58
58 @implementation TabStripController 59 @implementation TabStripController
59 60
(...skipping 15 matching lines...) Expand all
75 // some reason, if the view is present in the nib apriori, it draws 76 // some reason, if the view is present in the nib apriori, it draws
76 // correctly. If we create it in code and add it to the tab view, it draws 77 // correctly. If we create it in code and add it to the tab view, it draws
77 // with all sorts of crazy artifacts. 78 // with all sorts of crazy artifacts.
78 newTabButton_ = [[tabView_ subviews] objectAtIndex:0]; 79 newTabButton_ = [[tabView_ subviews] objectAtIndex:0];
79 DCHECK([newTabButton_ isKindOfClass:[NSButton class]]); 80 DCHECK([newTabButton_ isKindOfClass:[NSButton class]]);
80 [self addSubviewToPermanentList:newTabButton_]; 81 [self addSubviewToPermanentList:newTabButton_];
81 [newTabButton_ setTarget:nil]; 82 [newTabButton_ setTarget:nil];
82 [newTabButton_ setAction:@selector(commandDispatch:)]; 83 [newTabButton_ setAction:@selector(commandDispatch:)];
83 [newTabButton_ setTag:IDC_NEW_TAB]; 84 [newTabButton_ setTag:IDC_NEW_TAB];
84 targetFrames_.reset([[NSMutableDictionary alloc] init]); 85 targetFrames_.reset([[NSMutableDictionary alloc] init]);
86 [tabView_ setWantsLayer:YES];
85 dragBlockingView_.reset([[TabStripControllerDragBlockingView alloc] 87 dragBlockingView_.reset([[TabStripControllerDragBlockingView alloc]
86 initWithFrame:NSZeroRect]); 88 initWithFrame:NSZeroRect]);
87 [self addSubviewToPermanentList:dragBlockingView_]; 89 [self addSubviewToPermanentList:dragBlockingView_];
88 newTabTargetFrame_ = NSMakeRect(0, 0, 0, 0); 90 newTabTargetFrame_ = NSMakeRect(0, 0, 0, 0);
89 availableResizeWidth_ = kUseFullAvailableWidth; 91 availableResizeWidth_ = kUseFullAvailableWidth;
90 92
91 // Install the permanent subviews. 93 // Install the permanent subviews.
92 [self regenerateSubviewList]; 94 [self regenerateSubviewList];
93 95
94 // Watch for notifications that the tab strip view has changed size so 96 // Watch for notifications that the tab strip view has changed size so
95 // we can tell it to layout for the new size. 97 // we can tell it to layout for the new size.
96 [[NSNotificationCenter defaultCenter] 98 [[NSNotificationCenter defaultCenter]
97 addObserver:self 99 addObserver:self
98 selector:@selector(tabViewFrameChanged:) 100 selector:@selector(tabViewFrameChanged:)
99 name:NSViewFrameDidChangeNotification 101 name:NSViewFrameDidChangeNotification
100 object:tabView_]; 102 object:tabView_];
101
102 trackingArea_.reset([[NSTrackingArea alloc]
103 initWithRect:NSZeroRect // Ignored by NSTrackingInVisibleRect
104 options:NSTrackingMouseEnteredAndExited |
105 NSTrackingMouseMoved |
106 NSTrackingActiveAlways |
107 NSTrackingInVisibleRect
108 owner:self
109 userInfo:nil]);
110 [tabView_ addTrackingArea:trackingArea_.get()];
111 } 103 }
112 return self; 104 return self;
113 } 105 }
114 106
115 - (void)dealloc { 107 - (void)dealloc {
116 if (trackingArea_.get()) 108 if (closeTabTrackingArea_.get())
117 [tabView_ removeTrackingArea:trackingArea_.get()]; 109 [tabView_ removeTrackingArea:closeTabTrackingArea_.get()];
118 [[NSNotificationCenter defaultCenter] removeObserver:self]; 110 [[NSNotificationCenter defaultCenter] removeObserver:self];
119 [super dealloc]; 111 [super dealloc];
120 } 112 }
121 113
122 + (CGFloat)defaultTabHeight { 114 + (CGFloat)defaultTabHeight {
123 return 24.0; 115 return 24.0;
124 } 116 }
125 117
126 // Finds the associated TabContentsController at the given |index| and swaps 118 // Finds the associated TabContentsController at the given |index| and swaps
127 // out the sole child of the contentArea to display its contents. 119 // out the sole child of the contentArea to display its contents.
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 DCHECK([sender isKindOfClass:[NSView class]]); 222 DCHECK([sender isKindOfClass:[NSView class]]);
231 int index = [self indexForTabView:sender]; 223 int index = [self indexForTabView:sender];
232 if (index >= 0 && tabModel_->ContainsIndex(index)) 224 if (index >= 0 && tabModel_->ContainsIndex(index))
233 tabModel_->SelectTabContentsAt(index, true); 225 tabModel_->SelectTabContentsAt(index, true);
234 } 226 }
235 227
236 // Called when the user closes a tab. Asks the model to close the tab. |sender| 228 // Called when the user closes a tab. Asks the model to close the tab. |sender|
237 // is the TabView that is potentially going away. 229 // is the TabView that is potentially going away.
238 - (void)closeTab:(id)sender { 230 - (void)closeTab:(id)sender {
239 DCHECK([sender isKindOfClass:[NSView class]]); 231 DCHECK([sender isKindOfClass:[NSView class]]);
240 if ([hoveredTab_ isEqual:sender]) {
241 hoveredTab_ = nil;
242 }
243 int index = [self indexForTabView:sender]; 232 int index = [self indexForTabView:sender];
244 if (tabModel_->ContainsIndex(index)) { 233 if (tabModel_->ContainsIndex(index)) {
245 TabContents* contents = tabModel_->GetTabContentsAt(index); 234 TabContents* contents = tabModel_->GetTabContentsAt(index);
246 if (contents) 235 if (contents)
247 UserMetrics::RecordAction(L"CloseTab_Mouse", contents->profile()); 236 UserMetrics::RecordAction(L"CloseTab_Mouse", contents->profile());
248 if ([self numberOfTabViews] > 1) { 237 if ([self numberOfTabViews] > 1) {
249 // Limit the width available for laying out tabs so that tabs are not 238 // Limit the width available for laying out tabs so that tabs are not
250 // resized until a later time (when the mouse leaves the tab strip). 239 // resized until a later time (when the mouse leaves the tab strip).
251 // TODO(pinkerton): re-visit when handling tab overflow. 240 // TODO(pinkerton): re-visit when handling tab overflow.
252 NSView* penultimateTab = [self viewAtIndex:[tabArray_ count] - 2]; 241 NSView* penultimateTab = [self viewAtIndex:[tabArray_ count] - 2];
253 availableResizeWidth_ = NSMaxX([penultimateTab frame]); 242 availableResizeWidth_ = NSMaxX([penultimateTab frame]);
243 [self installTrackingArea];
254 tabModel_->CloseTabContentsAt(index); 244 tabModel_->CloseTabContentsAt(index);
255 } else { 245 } else {
256 // Use the standard window close if this is the last tab 246 // Use the standard window close if this is the last tab
257 // this prevents the tab from being removed from the model until after 247 // this prevents the tab from being removed from the model until after
258 // the window dissapears 248 // the window dissapears
259 [[tabView_ window] performClose:nil]; 249 [[tabView_ window] performClose:nil];
260 } 250 }
261 } 251 }
262 } 252 }
263 253
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 328
339 CGFloat minX = NSMinX(placeholderFrame_); 329 CGFloat minX = NSMinX(placeholderFrame_);
340 BOOL visible = [[tabView_ window] isVisible]; 330 BOOL visible = [[tabView_ window] isVisible];
341 331
342 float offset = kIndentLeavingSpaceForControls; 332 float offset = kIndentLeavingSpaceForControls;
343 NSUInteger i = 0; 333 NSUInteger i = 0;
344 NSInteger gap = -1; 334 NSInteger gap = -1;
345 for (TabController* tab in tabArray_.get()) { 335 for (TabController* tab in tabArray_.get()) {
346 BOOL isPlaceholder = [[tab view] isEqual:placeholderTab_]; 336 BOOL isPlaceholder = [[tab view] isEqual:placeholderTab_];
347 NSRect tabFrame = [[tab view] frame]; 337 NSRect tabFrame = [[tab view] frame];
348 tabFrame.size.height = [[self class] defaultTabHeight] + 1; 338 tabFrame.size.height = [[self class] defaultTabHeight];
349 tabFrame.origin.y = 0; 339 tabFrame.origin.y = 0;
350 tabFrame.origin.x = offset; 340 tabFrame.origin.x = offset;
351 341
352 // If the tab is hidden, we consider it a new tab. We make it visible 342 // If the tab is hidden, we consider it a new tab. We make it visible
353 // and animate it in. 343 // and animate it in.
354 BOOL newTab = [[tab view] isHidden]; 344 BOOL newTab = [[tab view] isHidden];
355 if (newTab) { 345 if (newTab) {
356 [[tab view] setHidden:NO]; 346 [[tab view] setHidden:NO];
357 } 347 }
358 348
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 // Release the tab contents controller so those views get destroyed. This 556 // Release the tab contents controller so those views get destroyed. This
567 // will remove all the tab content Cocoa views from the hierarchy. A 557 // will remove all the tab content Cocoa views from the hierarchy. A
568 // subsequent "select tab" notification will follow from the model. To 558 // subsequent "select tab" notification will follow from the model. To
569 // tell us what to swap in in its absence. 559 // tell us what to swap in in its absence.
570 [tabContentsArray_ removeObjectAtIndex:index]; 560 [tabContentsArray_ removeObjectAtIndex:index];
571 561
572 // Remove the |index|th view from the tab strip 562 // Remove the |index|th view from the tab strip
573 NSView* tab = [self viewAtIndex:index]; 563 NSView* tab = [self viewAtIndex:index];
574 [tab removeFromSuperview]; 564 [tab removeFromSuperview];
575 565
576 if ([hoveredTab_ isEqual:tab]) {
577 hoveredTab_ = nil;
578 }
579
580 NSValue *identifier = [NSValue valueWithPointer:tab]; 566 NSValue *identifier = [NSValue valueWithPointer:tab];
581 [targetFrames_ removeObjectForKey:identifier]; 567 [targetFrames_ removeObjectForKey:identifier];
582 568
583 // Once we're totally done with the tab, delete its controller 569 // Once we're totally done with the tab, delete its controller
584 [tabArray_ removeObjectAtIndex:index]; 570 [tabArray_ removeObjectAtIndex:index];
585 571
586 // Send a broadcast that the number of tabs have changed. 572 // Send a broadcast that the number of tabs have changed.
587 [[NSNotificationCenter defaultCenter] 573 [[NSNotificationCenter defaultCenter]
588 postNotificationName:kTabStripNumberOfTabsChanged 574 postNotificationName:kTabStripNumberOfTabsChanged
589 object:self]; 575 object:self];
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 // is no placeholder, it will go at the end. Used when dragging from another 740 // is no placeholder, it will go at the end. Used when dragging from another
755 // window when we don't have access to the TabContents as part of our strip. 741 // window when we don't have access to the TabContents as part of our strip.
756 - (void)dropTabContents:(TabContents*)contents { 742 - (void)dropTabContents:(TabContents*)contents {
757 int index = [self indexOfPlaceholder]; 743 int index = [self indexOfPlaceholder];
758 744
759 // Insert it into this tab strip. We want it in the foreground and to not 745 // Insert it into this tab strip. We want it in the foreground and to not
760 // inherit the current tab's group. 746 // inherit the current tab's group.
761 tabModel_->InsertTabContentsAt(index, contents, true, false); 747 tabModel_->InsertTabContentsAt(index, contents, true, false);
762 } 748 }
763 749
764 - (void)applyTheme { 750 - (void)userChangedTheme {
765 for (TabController* tab in tabArray_.get()) { 751 for (TabController* tab in tabArray_.get()) {
766 [tab applyTheme]; 752 [[tab view] setNeedsDisplay:YES];
767 } 753 }
768 } 754 }
769 755
770 // Called when the tab strip view changes size. As we only registered for 756 // Called when the tab strip view changes size. As we only registered for
771 // changes on our view, we know it's only for our view. Layout w/out 757 // changes on our view, we know it's only for our view. Layout w/out
772 // animations since they are blocked by the resize nested runloop. We need 758 // animations since they are blocked by the resize nested runloop. We need
773 // the views to adjust immediately. Neither the tabs nor their z-order are 759 // the views to adjust immediately. Neither the tabs nor their z-order are
774 // changed, so we don't need to update the subviews. 760 // changed, so we don't need to update the subviews.
775 - (void)tabViewFrameChanged:(NSNotification*)info { 761 - (void)tabViewFrameChanged:(NSNotification*)info {
776 [self layoutTabsWithAnimation:NO regenerateSubviews:NO]; 762 [self layoutTabsWithAnimation:NO regenerateSubviews:NO];
777 } 763 }
778 764
779 - (BOOL)useFullWidthForLayout { 765 - (BOOL)useFullWidthForLayout {
780 return availableResizeWidth_ == kUseFullAvailableWidth; 766 return availableResizeWidth_ == kUseFullAvailableWidth;
781 } 767 }
782 768
783 - (void)mouseMoved:(NSEvent *)event { 769 // Call to install a tracking area that reports mouseEnter/Exit messages so
784 // Use hit test to figure out what view we are hovering over. 770 // we can track when the mouse leaves the tab view after closing a tab with
785 TabView* targetView = (TabView*)[tabView_ hitTest:[event locationInWindow]]; 771 // the mouse. Don't install another tracking rect if one is already there.
786 if (![targetView isKindOfClass:[TabView class]]) { 772 - (void)installTrackingArea {
787 if ([[targetView superview] isKindOfClass:[TabView class]]) { 773 if (closeTabTrackingArea_.get())
788 targetView = (TabView*)[targetView superview]; 774 return;
789 } else { 775 // Note that we pass |NSTrackingInVisibleRect| so the rect is actually
790 targetView = nil; 776 // ignored.
791 } 777 closeTabTrackingArea_.reset([[NSTrackingArea alloc]
792 } 778 initWithRect:[tabView_ bounds]
793 779 options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways |
794 if (hoveredTab_ != targetView) { 780 NSTrackingInVisibleRect
795 [hoveredTab_ mouseExited:nil]; // We don't pass event because moved events 781 owner:self
796 [targetView mouseEntered:nil]; // don't have valid tracking areas 782 userInfo:nil]);
797 hoveredTab_ = targetView; 783 [tabView_ addTrackingArea:closeTabTrackingArea_.get()];
798 } else {
799 [hoveredTab_ mouseMoved:event];
800 }
801 } 784 }
802 785
803 - (void)mouseEntered:(NSEvent*)event { 786 - (void)mouseEntered:(NSEvent*)event {
804 [self mouseMoved:event]; 787 // Do nothing.
805 } 788 }
806 789
807 // Called when the tracking area is in effect which means we're tracking to 790 // Called when the tracking area is in effect which means we're tracking to
808 // see if the user leaves the tab strip with their mouse. When they do, 791 // see if the user leaves the tab strip with their mouse. When they do,
809 // reset layout to use all available width. 792 // reset layout to use all available width.
810 - (void)mouseExited:(NSEvent*)event { 793 - (void)mouseExited:(NSEvent*)event {
794 [tabView_ removeTrackingArea:closeTabTrackingArea_.get()];
795 closeTabTrackingArea_.reset(nil);
811 availableResizeWidth_ = kUseFullAvailableWidth; 796 availableResizeWidth_ = kUseFullAvailableWidth;
812
813 [hoveredTab_ mouseExited:event];
814 hoveredTab_ = nil;
815 [self layoutTabs]; 797 [self layoutTabs];
816 } 798 }
817 799
818 // Adds the given subview to (the end of) the list of permanent subviews 800 // Adds the given subview to (the end of) the list of permanent subviews
819 // (specified from bottom up). These subviews will always be below the 801 // (specified from bottom up). These subviews will always be below the
820 // transitory subviews (tabs). |-regenerateSubviewList| must be called to 802 // transitory subviews (tabs). |-regenerateSubviewList| must be called to
821 // effectuate the addition. 803 // effectuate the addition.
822 - (void)addSubviewToPermanentList:(NSView*)aView { 804 - (void)addSubviewToPermanentList:(NSView*)aView {
823 [permanentSubviews_ addObject:aView]; 805 [permanentSubviews_ addObject:aView];
824 } 806 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 BrowserWindowController* controller = 891 BrowserWindowController* controller =
910 (BrowserWindowController*)[[switchView_ window] windowController]; 892 (BrowserWindowController*)[[switchView_ window] windowController];
911 DCHECK(index >= 0); 893 DCHECK(index >= 0);
912 if (index >= 0) { 894 if (index >= 0) {
913 [controller setTab:[self viewAtIndex:index] isDraggable:YES]; 895 [controller setTab:[self viewAtIndex:index] isDraggable:YES];
914 } 896 }
915 } 897 }
916 898
917 899
918 @end 900 @end
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/tab_strip_controller.h ('k') | chrome/browser/cocoa/tab_strip_view.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698