| OLD | NEW |
| 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" |
| 11 #include "chrome/browser/browser.h" | 11 #include "chrome/browser/browser.h" |
| 12 #include "chrome/browser/cocoa/nsimage_cache.h" | 12 #include "chrome/browser/cocoa/nsimage_cache.h" |
| 13 #include "chrome/browser/find_bar.h" | 13 #include "chrome/browser/find_bar.h" |
| 14 #include "chrome/browser/find_bar_controller.h" | 14 #include "chrome/browser/find_bar_controller.h" |
| 15 #include "chrome/browser/metrics/user_metrics.h" | 15 #include "chrome/browser/metrics/user_metrics.h" |
| 16 #include "chrome/browser/profile.h" | 16 #include "chrome/browser/profile.h" |
| 17 #import "chrome/browser/cocoa/browser_window_controller.h" |
| 18 #import "chrome/browser/cocoa/constrained_window_mac.h" |
| 17 #import "chrome/browser/cocoa/tab_strip_view.h" | 19 #import "chrome/browser/cocoa/tab_strip_view.h" |
| 18 #import "chrome/browser/cocoa/tab_cell.h" | 20 #import "chrome/browser/cocoa/tab_cell.h" |
| 19 #import "chrome/browser/cocoa/tab_contents_controller.h" | 21 #import "chrome/browser/cocoa/tab_contents_controller.h" |
| 20 #import "chrome/browser/cocoa/tab_controller.h" | 22 #import "chrome/browser/cocoa/tab_controller.h" |
| 21 #import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h" | 23 #import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h" |
| 22 #import "chrome/browser/cocoa/tab_view.h" | 24 #import "chrome/browser/cocoa/tab_view.h" |
| 23 #import "chrome/browser/cocoa/throbber_view.h" | 25 #import "chrome/browser/cocoa/throbber_view.h" |
| 24 #include "chrome/browser/tab_contents/navigation_controller.h" | 26 #include "chrome/browser/tab_contents/navigation_controller.h" |
| 25 #include "chrome/browser/tab_contents/navigation_entry.h" | 27 #include "chrome/browser/tab_contents/navigation_entry.h" |
| 26 #include "chrome/browser/tab_contents/tab_contents.h" | 28 #include "chrome/browser/tab_contents/tab_contents.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 42 @implementation TabStripControllerDragBlockingView | 44 @implementation TabStripControllerDragBlockingView |
| 43 - (BOOL)mouseDownCanMoveWindow {return NO;} | 45 - (BOOL)mouseDownCanMoveWindow {return NO;} |
| 44 - (void)drawRect:(NSRect)rect {} | 46 - (void)drawRect:(NSRect)rect {} |
| 45 @end | 47 @end |
| 46 | 48 |
| 47 @interface TabStripController(Private) | 49 @interface TabStripController(Private) |
| 48 - (void)installTrackingArea; | 50 - (void)installTrackingArea; |
| 49 - (BOOL)useFullWidthForLayout; | 51 - (BOOL)useFullWidthForLayout; |
| 50 - (void)addSubviewToPermanentList:(NSView*)aView; | 52 - (void)addSubviewToPermanentList:(NSView*)aView; |
| 51 - (void)regenerateSubviewList; | 53 - (void)regenerateSubviewList; |
| 54 - (NSInteger)indexForContentsView:(NSView*)view; |
| 52 @end | 55 @end |
| 53 | 56 |
| 54 @implementation TabStripController | 57 @implementation TabStripController |
| 55 | 58 |
| 56 - (id)initWithView:(TabStripView*)view | 59 - (id)initWithView:(TabStripView*)view |
| 57 switchView:(NSView*)switchView | 60 switchView:(NSView*)switchView |
| 58 browser:(Browser*)browser { | 61 browser:(Browser*)browser { |
| 59 DCHECK(view && switchView && browser); | 62 DCHECK(view && switchView && browser); |
| 60 if ((self = [super init])) { | 63 if ((self = [super init])) { |
| 61 tabView_ = view; | 64 tabView_ = view; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 // child of |switchView_| because we're the one who put it there. There | 132 // child of |switchView_| because we're the one who put it there. There |
| 130 // may not be any children in the case of a tab that's been closed, in | 133 // may not be any children in the case of a tab that's been closed, in |
| 131 // which case there's no swapping going on. | 134 // which case there's no swapping going on. |
| 132 NSArray* subviews = [switchView_ subviews]; | 135 NSArray* subviews = [switchView_ subviews]; |
| 133 if ([subviews count]) { | 136 if ([subviews count]) { |
| 134 NSView* oldView = [subviews objectAtIndex:0]; | 137 NSView* oldView = [subviews objectAtIndex:0]; |
| 135 [switchView_ replaceSubview:oldView with:newView]; | 138 [switchView_ replaceSubview:oldView with:newView]; |
| 136 } else { | 139 } else { |
| 137 [switchView_ addSubview:newView]; | 140 [switchView_ addSubview:newView]; |
| 138 } | 141 } |
| 142 |
| 143 // Make sure the new tabs's sheets are visible (necessary when a background |
| 144 // tab opened a sheet while it was in the background and now becomes active). |
| 145 TabContents* newTab = tabModel_->GetTabContentsAt(index); |
| 146 DCHECK(newTab); |
| 147 if (newTab) { |
| 148 TabContents::ConstrainedWindowList::iterator it, end; |
| 149 end = newTab->constrained_window_end(); |
| 150 NSWindowController* controller = [[newView window] windowController]; |
| 151 DCHECK([controller isKindOfClass:[BrowserWindowController class]]); |
| 152 |
| 153 for (it = newTab->constrained_window_begin(); it != end; ++it) { |
| 154 ConstrainedWindow* constrainedWindow = *it; |
| 155 static_cast<ConstrainedWindowMac*>(constrainedWindow)->Realize( |
| 156 static_cast<BrowserWindowController*>(controller)); |
| 157 } |
| 158 } |
| 159 |
| 160 // Tell per-tab sheet manager about currently selected tab. |
| 161 if (sheetController_.get()) { |
| 162 [sheetController_ setActiveView:newView]; |
| 163 } |
| 139 } | 164 } |
| 140 | 165 |
| 141 // Create a new tab view and set its cell correctly so it draws the way we want | 166 // Create a new tab view and set its cell correctly so it draws the way we want |
| 142 // it to. It will be sized and positioned by |-layoutTabs| so there's no need to | 167 // it to. It will be sized and positioned by |-layoutTabs| so there's no need to |
| 143 // set the frame here. This also creates the view as hidden, it will be | 168 // set the frame here. This also creates the view as hidden, it will be |
| 144 // shown during layout. | 169 // shown during layout. |
| 145 - (TabController*)newTab { | 170 - (TabController*)newTab { |
| 146 TabController* controller = [[[TabController alloc] init] autorelease]; | 171 TabController* controller = [[[TabController alloc] init] autorelease]; |
| 147 [controller setTarget:self]; | 172 [controller setTarget:self]; |
| 148 [controller setAction:@selector(selectTab:)]; | 173 [controller setAction:@selector(selectTab:)]; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 162 - (NSInteger)indexForTabView:(NSView*)view { | 187 - (NSInteger)indexForTabView:(NSView*)view { |
| 163 NSInteger index = 0; | 188 NSInteger index = 0; |
| 164 for (TabController* current in tabArray_.get()) { | 189 for (TabController* current in tabArray_.get()) { |
| 165 if ([current view] == view) | 190 if ([current view] == view) |
| 166 return index; | 191 return index; |
| 167 ++index; | 192 ++index; |
| 168 } | 193 } |
| 169 return -1; | 194 return -1; |
| 170 } | 195 } |
| 171 | 196 |
| 197 // Returns the index of the contents subview |view|. Returns -1 if not present. |
| 198 - (NSInteger)indexForContentsView:(NSView*)view { |
| 199 NSInteger index = 0; |
| 200 for (TabContentsController* current in tabContentsArray_.get()) { |
| 201 if ([current view] == view) |
| 202 return index; |
| 203 ++index; |
| 204 } |
| 205 return -1; |
| 206 } |
| 207 |
| 208 |
| 172 // Returns the view at the given index, using the array of TabControllers to | 209 // Returns the view at the given index, using the array of TabControllers to |
| 173 // get the associated view. Returns nil if out of range. | 210 // get the associated view. Returns nil if out of range. |
| 174 - (NSView*)viewAtIndex:(NSUInteger)index { | 211 - (NSView*)viewAtIndex:(NSUInteger)index { |
| 175 if (index >= [tabArray_ count]) | 212 if (index >= [tabArray_ count]) |
| 176 return NULL; | 213 return NULL; |
| 177 return [[tabArray_ objectAtIndex:index] view]; | 214 return [[tabArray_ objectAtIndex:index] view]; |
| 178 } | 215 } |
| 179 | 216 |
| 180 // Called when the user clicks a tab. Tell the model the selection has changed, | 217 // Called when the user clicks a tab. Tell the model the selection has changed, |
| 181 // which feeds back into us via a notification. | 218 // which feeds back into us via a notification. |
| (...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 } else { | 812 } else { |
| 776 [subviews addObject:[tab view]]; | 813 [subviews addObject:[tab view]]; |
| 777 } | 814 } |
| 778 } | 815 } |
| 779 if (selectedTabView) | 816 if (selectedTabView) |
| 780 [subviews addObject:selectedTabView]; | 817 [subviews addObject:selectedTabView]; |
| 781 | 818 |
| 782 [tabView_ setSubviews:subviews]; | 819 [tabView_ setSubviews:subviews]; |
| 783 } | 820 } |
| 784 | 821 |
| 822 - (GTMWindowSheetController*)sheetController { |
| 823 if (!sheetController_.get()) |
| 824 sheetController_.reset([[GTMWindowSheetController alloc] |
| 825 initWithWindow:[switchView_ window] delegate:self]); |
| 826 return sheetController_.get(); |
| 827 } |
| 828 |
| 829 - (void)gtm_systemRequestsVisibilityForView:(NSView*)view { |
| 830 // This implementation is required by GTMWindowSheetController. |
| 831 |
| 832 // Raise window... |
| 833 [[switchView_ window] makeKeyAndOrderFront:self]; |
| 834 |
| 835 // ...and raise a tab with a sheet. |
| 836 NSInteger index = [self indexForContentsView:view]; |
| 837 DCHECK(index >= 0); |
| 838 if (index >= 0) |
| 839 tabModel_->SelectTabContentsAt(index, false /* not a user gesture */); |
| 840 } |
| 841 |
| 842 - (void)attachConstrainedWindow:(ConstrainedWindowMac*)window { |
| 843 // TODO(thakis, avi): Figure out how to make this work when tabs are dragged |
| 844 // out or if fullscreen mode is toggled. |
| 845 |
| 846 // View hierarchy of the contents view: |
| 847 // NSView -- switchView, same for all tabs |
| 848 // +- NSView -- TabContentsController's view |
| 849 // +- NSBox |
| 850 // +- TabContentsViewCocoa |
| 851 // We use the TabContentsController's view in |swapInTabAtIndex|, so we have |
| 852 // to pass it to the sheet controller here. |
| 853 NSView* tabContentsView = |
| 854 [[window->owner()->GetNativeView() superview] superview]; |
| 855 window->delegate()->RunSheet([self sheetController], tabContentsView); |
| 856 |
| 857 // TODO(avi, thakis): GTMWindowSheetController has no api to move tabsheets |
| 858 // between windows. Until then, we have to prevent having to move a tabsheet |
| 859 // between windows, e.g. no tearing off of tabs. |
| 860 NSInteger index = [self indexForContentsView:tabContentsView]; |
| 861 BrowserWindowController* controller = |
| 862 (BrowserWindowController*)[[switchView_ window] windowController]; |
| 863 DCHECK(controller != nil); |
| 864 DCHECK(index >= 0); |
| 865 if (index >= 0) { |
| 866 [controller setTab:[self viewAtIndex:index] isDraggable:NO]; |
| 867 } |
| 868 } |
| 869 |
| 870 - (void)removeConstrainedWindow:(ConstrainedWindowMac*)window { |
| 871 NSView* tabContentsView = |
| 872 [[window->owner()->GetNativeView() superview] superview]; |
| 873 |
| 874 // TODO(avi, thakis): GTMWindowSheetController has no api to move tabsheets |
| 875 // between windows. Until then, we have to prevent having to move a tabsheet |
| 876 // between windows, e.g. no tearing off of tabs. |
| 877 NSInteger index = [self indexForContentsView:tabContentsView]; |
| 878 BrowserWindowController* controller = |
| 879 (BrowserWindowController*)[[switchView_ window] windowController]; |
| 880 DCHECK(index >= 0); |
| 881 if (index >= 0) { |
| 882 [controller setTab:[self viewAtIndex:index] isDraggable:YES]; |
| 883 } |
| 884 } |
| 885 |
| 886 |
| 785 @end | 887 @end |
| OLD | NEW |