| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <limits> | 9 #include <limits> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 #include "chrome/browser/sidebar/sidebar_container.h" | 25 #include "chrome/browser/sidebar/sidebar_container.h" |
| 26 #include "chrome/browser/sidebar/sidebar_manager.h" | 26 #include "chrome/browser/sidebar/sidebar_manager.h" |
| 27 #include "chrome/browser/tabs/tab_strip_model.h" | 27 #include "chrome/browser/tabs/tab_strip_model.h" |
| 28 #include "chrome/browser/tabs/tab_strip_selection_model.h" | 28 #include "chrome/browser/tabs/tab_strip_selection_model.h" |
| 29 #include "chrome/browser/ui/browser.h" | 29 #include "chrome/browser/ui/browser.h" |
| 30 #include "chrome/browser/ui/browser_navigator.h" | 30 #include "chrome/browser/ui/browser_navigator.h" |
| 31 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | 31 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| 32 #import "chrome/browser/ui/cocoa/constrained_window_mac.h" | 32 #import "chrome/browser/ui/cocoa/constrained_window_mac.h" |
| 33 #import "chrome/browser/ui/cocoa/image_button_cell.h" | 33 #import "chrome/browser/ui/cocoa/image_button_cell.h" |
| 34 #import "chrome/browser/ui/cocoa/new_tab_button.h" | 34 #import "chrome/browser/ui/cocoa/new_tab_button.h" |
| 35 #import "chrome/browser/ui/cocoa/profile_menu_button.h" | |
| 36 #import "chrome/browser/ui/cocoa/tab_contents/favicon_util.h" | 35 #import "chrome/browser/ui/cocoa/tab_contents/favicon_util.h" |
| 37 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" | 36 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" |
| 38 #import "chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.h" | 37 #import "chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.h" |
| 39 #import "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h" | 38 #import "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h" |
| 40 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" | 39 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" |
| 41 #import "chrome/browser/ui/cocoa/tabs/tab_view.h" | 40 #import "chrome/browser/ui/cocoa/tabs/tab_view.h" |
| 42 #import "chrome/browser/ui/cocoa/tabs/throbber_view.h" | 41 #import "chrome/browser/ui/cocoa/tabs/throbber_view.h" |
| 43 #import "chrome/browser/ui/cocoa/tracking_area.h" | 42 #import "chrome/browser/ui/cocoa/tracking_area.h" |
| 44 #include "chrome/browser/ui/find_bar/find_bar.h" | 43 #include "chrome/browser/ui/find_bar/find_bar.h" |
| 45 #include "chrome/browser/ui/find_bar/find_bar_controller.h" | 44 #include "chrome/browser/ui/find_bar/find_bar_controller.h" |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 strip_ = nil; | 264 strip_ = nil; |
| 266 controller_ = nil; | 265 controller_ = nil; |
| 267 } | 266 } |
| 268 | 267 |
| 269 - (void)animationDidStop:(CAAnimation*)animation finished:(BOOL)finished { | 268 - (void)animationDidStop:(CAAnimation*)animation finished:(BOOL)finished { |
| 270 [strip_ animationDidStopForController:controller_ finished:finished]; | 269 [strip_ animationDidStopForController:controller_ finished:finished]; |
| 271 } | 270 } |
| 272 | 271 |
| 273 @end | 272 @end |
| 274 | 273 |
| 275 namespace TabStripControllerInternal { | |
| 276 | |
| 277 // Bridges C++ notifications back to the TabStripController. | |
| 278 class NotificationBridge : public NotificationObserver { | |
| 279 public: | |
| 280 explicit NotificationBridge(TabStripController* controller, | |
| 281 PrefService* prefService) | |
| 282 : controller_(controller) { | |
| 283 DCHECK(prefService); | |
| 284 usernamePref_.Init(prefs::kGoogleServicesUsername, prefService, this); | |
| 285 } | |
| 286 | |
| 287 // Overridden from NotificationObserver: | |
| 288 virtual void Observe(NotificationType type, | |
| 289 const NotificationSource& source, | |
| 290 const NotificationDetails& details) { | |
| 291 DCHECK_EQ(NotificationType::PREF_CHANGED, type.value); | |
| 292 std::string* name = Details<std::string>(details).ptr(); | |
| 293 if (prefs::kGoogleServicesUsername == *name) { | |
| 294 [controller_ updateProfileMenuButton]; | |
| 295 [controller_ layoutTabsWithAnimation:NO regenerateSubviews:NO]; | |
| 296 } | |
| 297 } | |
| 298 | |
| 299 private: | |
| 300 TabStripController* controller_; // weak, owns us | |
| 301 | |
| 302 // The Google services user name associated with this BrowserView's profile. | |
| 303 StringPrefMember usernamePref_; | |
| 304 }; | |
| 305 | |
| 306 } // namespace TabStripControllerInternal | |
| 307 | |
| 308 #pragma mark - | 274 #pragma mark - |
| 309 | 275 |
| 310 // In general, there is a one-to-one correspondence between TabControllers, | 276 // In general, there is a one-to-one correspondence between TabControllers, |
| 311 // TabViews, TabContentsControllers, and the TabContents in the TabStripModel. | 277 // TabViews, TabContentsControllers, and the TabContents in the TabStripModel. |
| 312 // In the steady-state, the indices line up so an index coming from the model | 278 // In the steady-state, the indices line up so an index coming from the model |
| 313 // is directly mapped to the same index in the parallel arrays holding our | 279 // is directly mapped to the same index in the parallel arrays holding our |
| 314 // views and controllers. This is also true when new tabs are created (even | 280 // views and controllers. This is also true when new tabs are created (even |
| 315 // though there is a small period of animation) because the tab is present | 281 // though there is a small period of animation) because the tab is present |
| 316 // in the model while the TabView is animating into place. As a result, nothing | 282 // in the model while the TabView is animating into place. As a result, nothing |
| 317 // special need be done to handle "new tab" animation. | 283 // special need be done to handle "new tab" animation. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 | 343 |
| 378 // TODO(viettrungluu): WTF? "For some reason, if the view is present in the | 344 // TODO(viettrungluu): WTF? "For some reason, if the view is present in the |
| 379 // nib a priori, it draws correctly. If we create it in code and add it to | 345 // nib a priori, it draws correctly. If we create it in code and add it to |
| 380 // the tab view, it draws with all sorts of crazy artifacts." | 346 // the tab view, it draws with all sorts of crazy artifacts." |
| 381 newTabButton_ = [view getNewTabButton]; | 347 newTabButton_ = [view getNewTabButton]; |
| 382 [self addSubviewToPermanentList:newTabButton_]; | 348 [self addSubviewToPermanentList:newTabButton_]; |
| 383 [newTabButton_ setTarget:nil]; | 349 [newTabButton_ setTarget:nil]; |
| 384 [newTabButton_ setAction:@selector(commandDispatch:)]; | 350 [newTabButton_ setAction:@selector(commandDispatch:)]; |
| 385 [newTabButton_ setTag:IDC_NEW_TAB]; | 351 [newTabButton_ setTag:IDC_NEW_TAB]; |
| 386 | 352 |
| 387 profileMenuButton_ = [view profileMenuButton]; | |
| 388 [self addSubviewToPermanentList:profileMenuButton_]; | |
| 389 [self updateProfileMenuButton]; | |
| 390 // Register pref observers for profile name. | |
| 391 notificationBridge_.reset( | |
| 392 new TabStripControllerInternal::NotificationBridge( | |
| 393 self, browser_->profile()->GetPrefs())); | |
| 394 | |
| 395 // Set the images from code because Cocoa fails to find them in our sub | 353 // Set the images from code because Cocoa fails to find them in our sub |
| 396 // bundle during tests. | 354 // bundle during tests. |
| 397 [[newTabButton_ cell] setImageID:IDR_NEWTAB_BUTTON | 355 [[newTabButton_ cell] setImageID:IDR_NEWTAB_BUTTON |
| 398 forButtonState:image_button_cell::kDefaultState]; | 356 forButtonState:image_button_cell::kDefaultState]; |
| 399 [[newTabButton_ cell] setImageID:IDR_NEWTAB_BUTTON_H | 357 [[newTabButton_ cell] setImageID:IDR_NEWTAB_BUTTON_H |
| 400 forButtonState:image_button_cell::kHoverState]; | 358 forButtonState:image_button_cell::kHoverState]; |
| 401 [[newTabButton_ cell] setImageID:IDR_NEWTAB_BUTTON_P | 359 [[newTabButton_ cell] setImageID:IDR_NEWTAB_BUTTON_P |
| 402 forButtonState:image_button_cell::kPressedState]; | 360 forButtonState:image_button_cell::kPressedState]; |
| 403 newTabButtonShowingHoverImage_ = NO; | 361 newTabButtonShowingHoverImage_ = NO; |
| 404 newTabTrackingArea_.reset( | 362 newTabTrackingArea_.reset( |
| (...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1074 } | 1032 } |
| 1075 [[newTabButton_ animator] setFrame:newTabNewFrame]; | 1033 [[newTabButton_ animator] setFrame:newTabNewFrame]; |
| 1076 newTabTargetFrame_ = newTabNewFrame; | 1034 newTabTargetFrame_ = newTabNewFrame; |
| 1077 } else { | 1035 } else { |
| 1078 [newTabButton_ setFrame:newTabNewFrame]; | 1036 [newTabButton_ setFrame:newTabNewFrame]; |
| 1079 newTabTargetFrame_ = newTabNewFrame; | 1037 newTabTargetFrame_ = newTabNewFrame; |
| 1080 } | 1038 } |
| 1081 } | 1039 } |
| 1082 } | 1040 } |
| 1083 | 1041 |
| 1084 if (profileMenuButton_ && ![profileMenuButton_ isHidden]) { | |
| 1085 CGFloat maxX; | |
| 1086 if ([newTabButton_ isHidden]) { | |
| 1087 maxX = std::max(offset, NSMaxX(placeholderFrame_) - kTabOverlap); | |
| 1088 } else { | |
| 1089 maxX = NSMaxX(newTabTargetFrame_); | |
| 1090 } | |
| 1091 NSRect profileMenuButtonFrame = [profileMenuButton_ frame]; | |
| 1092 NSSize minSize = [profileMenuButton_ minControlSize]; | |
| 1093 | |
| 1094 // Make room for the full screen button if necessary. | |
| 1095 if (!hasUpdatedProfileMenuButtonXOffset_) { | |
| 1096 hasUpdatedProfileMenuButtonXOffset_ = YES; | |
| 1097 if ([[profileMenuButton_ window] | |
| 1098 respondsToSelector:@selector(toggleFullScreen:)]) { | |
| 1099 NSButton* fullscreenButton = [[profileMenuButton_ window] | |
| 1100 standardWindowButton:NSWindowFullScreenButton]; | |
| 1101 if (fullscreenButton) { | |
| 1102 profileMenuButtonFrame.origin.x = NSMinX([fullscreenButton frame]) - | |
| 1103 NSWidth(profileMenuButtonFrame) - kProfileMenuButtonOffset; | |
| 1104 } | |
| 1105 } | |
| 1106 } | |
| 1107 | |
| 1108 // TODO(sail): Animate this. | |
| 1109 CGFloat availableWidth = NSMaxX(profileMenuButtonFrame) - maxX - | |
| 1110 kProfileMenuButtonOffset; | |
| 1111 if (availableWidth > minSize.width) { | |
| 1112 [profileMenuButton_ setShouldShowProfileDisplayName:YES]; | |
| 1113 } else { | |
| 1114 [profileMenuButton_ setShouldShowProfileDisplayName:NO]; | |
| 1115 } | |
| 1116 | |
| 1117 NSSize desiredSize = [profileMenuButton_ desiredControlSize]; | |
| 1118 NSRect rect; | |
| 1119 rect.size.width = std::min(desiredSize.width, | |
| 1120 std::max(availableWidth, minSize.width)); | |
| 1121 rect.size.height = desiredSize.height; | |
| 1122 rect.origin.y = NSMaxY(profileMenuButtonFrame) - rect.size.height; | |
| 1123 rect.origin.x = NSMaxX(profileMenuButtonFrame) - rect.size.width; | |
| 1124 [profileMenuButton_ setFrame:rect]; | |
| 1125 } | |
| 1126 | |
| 1127 [dragBlockingView_ setFrame:enclosingRect]; | 1042 [dragBlockingView_ setFrame:enclosingRect]; |
| 1128 | 1043 |
| 1129 // Mark that we've successfully completed layout of at least one tab. | 1044 // Mark that we've successfully completed layout of at least one tab. |
| 1130 initialLayoutComplete_ = YES; | 1045 initialLayoutComplete_ = YES; |
| 1131 } | 1046 } |
| 1132 | 1047 |
| 1133 // When we're told to layout from the public API we usually want to animate, | 1048 // When we're told to layout from the public API we usually want to animate, |
| 1134 // except when it's the first time. | 1049 // except when it's the first time. |
| 1135 - (void)layoutTabs { | 1050 - (void)layoutTabs { |
| 1136 [self layoutTabsWithAnimation:initialLayoutComplete_ regenerateSubviews:YES]; | 1051 [self layoutTabsWithAnimation:initialLayoutComplete_ regenerateSubviews:YES]; |
| (...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2118 NSInteger modelIndex = [self modelIndexForContentsView:tabContentsView]; | 2033 NSInteger modelIndex = [self modelIndexForContentsView:tabContentsView]; |
| 2119 NSInteger index = [self indexFromModelIndex:modelIndex]; | 2034 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 2120 BrowserWindowController* controller = | 2035 BrowserWindowController* controller = |
| 2121 (BrowserWindowController*)[[switchView_ window] windowController]; | 2036 (BrowserWindowController*)[[switchView_ window] windowController]; |
| 2122 DCHECK(index >= 0); | 2037 DCHECK(index >= 0); |
| 2123 if (index >= 0) { | 2038 if (index >= 0) { |
| 2124 [controller setTab:[self viewAtIndex:index] isDraggable:YES]; | 2039 [controller setTab:[self viewAtIndex:index] isDraggable:YES]; |
| 2125 } | 2040 } |
| 2126 } | 2041 } |
| 2127 | 2042 |
| 2128 - (BOOL)shouldShowProfileMenuButton { | |
| 2129 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kMultiProfiles)) | |
| 2130 return NO; | |
| 2131 if (browser_->profile()->IsOffTheRecord()) | |
| 2132 return NO; | |
| 2133 return (!browser_->profile()->GetPrefs()->GetString( | |
| 2134 prefs::kGoogleServicesUsername).empty()); | |
| 2135 } | |
| 2136 | |
| 2137 - (void)updateProfileMenuButton { | |
| 2138 if (![self shouldShowProfileMenuButton]) { | |
| 2139 [profileMenuButton_ setHidden:YES]; | |
| 2140 return; | |
| 2141 } | |
| 2142 | |
| 2143 std::string profileName = browser_->profile()->GetPrefs()->GetString( | |
| 2144 prefs::kGoogleServicesUsername); | |
| 2145 [profileMenuButton_ setProfileDisplayName: | |
| 2146 [NSString stringWithUTF8String:profileName.c_str()]]; | |
| 2147 [profileMenuButton_ setHidden:NO]; | |
| 2148 } | |
| 2149 | |
| 2150 @end | 2043 @end |
| OLD | NEW |