| 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/wrench_menu/wrench_menu_controller.h" | 5 #import "chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/mac/bundle_locations.h" | 8 #include "base/mac/bundle_locations.h" |
| 9 #include "base/scoped_observer.h" | 9 #include "base/scoped_observer.h" |
| 10 #include "base/strings/string16.h" | 10 #include "base/strings/string16.h" |
| 11 #include "base/strings/sys_string_conversions.h" | 11 #include "base/strings/sys_string_conversions.h" |
| 12 #include "chrome/app/chrome_command_ids.h" | 12 #include "chrome/app/chrome_command_ids.h" |
| 13 #import "chrome/browser/app_controller_mac.h" | 13 #import "chrome/browser/app_controller_mac.h" |
| 14 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
| 15 #include "chrome/browser/ui/browser.h" | 15 #include "chrome/browser/ui/browser.h" |
| 16 #include "chrome/browser/ui/browser_window.h" | 16 #include "chrome/browser/ui/browser_window.h" |
| 17 #import "chrome/browser/ui/cocoa/accelerators_cocoa.h" | 17 #import "chrome/browser/ui/cocoa/accelerators_cocoa.h" |
| 18 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h" | 18 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h" |
| 19 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.h" | 19 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.h" |
| 20 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | 20 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| 21 #import "chrome/browser/ui/cocoa/encoding_menu_controller_delegate_mac.h" | 21 #import "chrome/browser/ui/cocoa/encoding_menu_controller_delegate_mac.h" |
| 22 #import "chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h" | 22 #import "chrome/browser/ui/cocoa/extensions/browser_actions_container_view.h" |
| 23 #import "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h" | 23 #import "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h" |
| 24 #import "chrome/browser/ui/cocoa/l10n_util.h" | 24 #import "chrome/browser/ui/cocoa/l10n_util.h" |
| 25 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" | 25 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" |
| 26 #import "chrome/browser/ui/cocoa/wrench_menu/menu_tracked_root_view.h" | 26 #import "chrome/browser/ui/cocoa/wrench_menu/menu_tracked_root_view.h" |
| 27 #import "chrome/browser/ui/cocoa/wrench_menu/recent_tabs_menu_model_delegate.h" | 27 #import "chrome/browser/ui/cocoa/wrench_menu/recent_tabs_menu_model_delegate.h" |
| 28 #include "chrome/browser/ui/toolbar/app_menu_model.h" |
| 28 #include "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h" | 29 #include "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h" |
| 29 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" | 30 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" |
| 30 #include "chrome/browser/ui/toolbar/toolbar_actions_bar_observer.h" | 31 #include "chrome/browser/ui/toolbar/toolbar_actions_bar_observer.h" |
| 31 #include "chrome/browser/ui/toolbar/wrench_menu_model.h" | |
| 32 #include "chrome/grit/generated_resources.h" | 32 #include "chrome/grit/generated_resources.h" |
| 33 #include "components/ui/zoom/zoom_event_manager.h" | 33 #include "components/ui/zoom/zoom_event_manager.h" |
| 34 #include "content/public/browser/user_metrics.h" | 34 #include "content/public/browser/user_metrics.h" |
| 35 #include "ui/base/l10n/l10n_util.h" | 35 #include "ui/base/l10n/l10n_util.h" |
| 36 #include "ui/base/models/menu_model.h" | 36 #include "ui/base/models/menu_model.h" |
| 37 #include "ui/gfx/geometry/size.h" | 37 #include "ui/gfx/geometry/size.h" |
| 38 | 38 |
| 39 namespace { | 39 namespace { |
| 40 // Padding amounts on the left/right of a custom menu item (like the browser | 40 // Padding amounts on the left/right of a custom menu item (like the browser |
| 41 // actions overflow container). | 41 // actions overflow container). |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 : controller_(controller) { | 93 : controller_(controller) { |
| 94 subscription_ = manager->AddZoomLevelChangedCallback( | 94 subscription_ = manager->AddZoomLevelChangedCallback( |
| 95 base::Bind(&ZoomLevelObserver::OnZoomLevelChanged, | 95 base::Bind(&ZoomLevelObserver::OnZoomLevelChanged, |
| 96 base::Unretained(this))); | 96 base::Unretained(this))); |
| 97 } | 97 } |
| 98 | 98 |
| 99 ~ZoomLevelObserver() {} | 99 ~ZoomLevelObserver() {} |
| 100 | 100 |
| 101 private: | 101 private: |
| 102 void OnZoomLevelChanged(const content::HostZoomMap::ZoomLevelChange& change) { | 102 void OnZoomLevelChanged(const content::HostZoomMap::ZoomLevelChange& change) { |
| 103 WrenchMenuModel* wrenchMenuModel = [controller_ wrenchMenuModel]; | 103 AppMenuModel* appMenuModel = [controller_ appMenuModel]; |
| 104 wrenchMenuModel->UpdateZoomControls(); | 104 appMenuModel->UpdateZoomControls(); |
| 105 const base::string16 level = | 105 const base::string16 level = |
| 106 wrenchMenuModel->GetLabelForCommandId(IDC_ZOOM_PERCENT_DISPLAY); | 106 appMenuModel->GetLabelForCommandId(IDC_ZOOM_PERCENT_DISPLAY); |
| 107 [[controller_ zoomDisplay] setTitle:SysUTF16ToNSString(level)]; | 107 [[controller_ zoomDisplay] setTitle:SysUTF16ToNSString(level)]; |
| 108 } | 108 } |
| 109 | 109 |
| 110 scoped_ptr<content::HostZoomMap::Subscription> subscription_; | 110 scoped_ptr<content::HostZoomMap::Subscription> subscription_; |
| 111 | 111 |
| 112 WrenchMenuController* controller_; // Weak; owns this. | 112 WrenchMenuController* controller_; // Weak; owns this. |
| 113 | 113 |
| 114 DISALLOW_COPY_AND_ASSIGN(ZoomLevelObserver); | 114 DISALLOW_COPY_AND_ASSIGN(ZoomLevelObserver); |
| 115 }; | 115 }; |
| 116 | 116 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 - (void)dealloc { | 156 - (void)dealloc { |
| 157 [self browserWillBeDestroyed]; | 157 [self browserWillBeDestroyed]; |
| 158 [super dealloc]; | 158 [super dealloc]; |
| 159 } | 159 } |
| 160 | 160 |
| 161 - (void)browserWillBeDestroyed { | 161 - (void)browserWillBeDestroyed { |
| 162 // This method indicates imminent destruction. Destroy owned objects that hold | 162 // This method indicates imminent destruction. Destroy owned objects that hold |
| 163 // a weak Browser*, or pass this call onto reference counted objects. | 163 // a weak Browser*, or pass this call onto reference counted objects. |
| 164 recentTabsMenuModelDelegate_.reset(); | 164 recentTabsMenuModelDelegate_.reset(); |
| 165 [self setModel:nullptr]; | 165 [self setModel:nullptr]; |
| 166 wrenchMenuModel_.reset(); | 166 appMenuModel_.reset(); |
| 167 buttonViewController_.reset(); | 167 buttonViewController_.reset(); |
| 168 | 168 |
| 169 // The observers should most likely already be destroyed (since they're reset | 169 // The observers should most likely already be destroyed (since they're reset |
| 170 // in -menuDidClose:), but sometimes shutdown can be funny, so make sure to | 170 // in -menuDidClose:), but sometimes shutdown can be funny, so make sure to |
| 171 // not leave any dangling observers. | 171 // not leave any dangling observers. |
| 172 zoom_level_observer_.reset(); | 172 zoom_level_observer_.reset(); |
| 173 toolbar_actions_bar_observer_.reset(); | 173 toolbar_actions_bar_observer_.reset(); |
| 174 | 174 |
| 175 [browserActionsController_ browserWillBeDestroyed]; | 175 [browserActionsController_ browserWillBeDestroyed]; |
| 176 | 176 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 | 280 |
| 281 - (NSMenu*)bookmarkSubMenu { | 281 - (NSMenu*)bookmarkSubMenu { |
| 282 NSString* title = l10n_util::GetNSStringWithFixup(IDS_BOOKMARKS_MENU); | 282 NSString* title = l10n_util::GetNSStringWithFixup(IDS_BOOKMARKS_MENU); |
| 283 return [[[self menu] itemWithTitle:title] submenu]; | 283 return [[[self menu] itemWithTitle:title] submenu]; |
| 284 } | 284 } |
| 285 | 285 |
| 286 - (void)updateBookmarkSubMenu { | 286 - (void)updateBookmarkSubMenu { |
| 287 NSMenu* bookmarkMenu = [self bookmarkSubMenu]; | 287 NSMenu* bookmarkMenu = [self bookmarkSubMenu]; |
| 288 DCHECK(bookmarkMenu); | 288 DCHECK(bookmarkMenu); |
| 289 | 289 |
| 290 bookmarkMenuBridge_.reset( | 290 bookmarkMenuBridge_.reset(new BookmarkMenuBridge( |
| 291 new BookmarkMenuBridge([self wrenchMenuModel]->browser()->profile(), | 291 [self appMenuModel]->browser()->profile(), bookmarkMenu)); |
| 292 bookmarkMenu)); | |
| 293 } | 292 } |
| 294 | 293 |
| 295 - (void)updateBrowserActionsSubmenu { | 294 - (void)updateBrowserActionsSubmenu { |
| 296 MenuTrackedRootView* view = | 295 MenuTrackedRootView* view = |
| 297 [buttonViewController_ toolbarActionsOverflowItem]; | 296 [buttonViewController_ toolbarActionsOverflowItem]; |
| 298 BrowserActionsContainerView* containerView = | 297 BrowserActionsContainerView* containerView = |
| 299 [buttonViewController_ overflowActionsContainerView]; | 298 [buttonViewController_ overflowActionsContainerView]; |
| 300 | 299 |
| 301 // Find the preferred container size for the menu width. | 300 // Find the preferred container size for the menu width. |
| 302 int menuWidth = [[self menu] size].width; | 301 int menuWidth = [[self menu] size].width; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 332 | 331 |
| 333 - (void)menuWillOpen:(NSMenu*)menu { | 332 - (void)menuWillOpen:(NSMenu*)menu { |
| 334 [super menuWillOpen:menu]; | 333 [super menuWillOpen:menu]; |
| 335 | 334 |
| 336 zoom_level_observer_.reset( | 335 zoom_level_observer_.reset( |
| 337 new WrenchMenuControllerInternal::ZoomLevelObserver( | 336 new WrenchMenuControllerInternal::ZoomLevelObserver( |
| 338 self, | 337 self, |
| 339 ui_zoom::ZoomEventManager::GetForBrowserContext( | 338 ui_zoom::ZoomEventManager::GetForBrowserContext( |
| 340 browser_->profile()))); | 339 browser_->profile()))); |
| 341 NSString* title = base::SysUTF16ToNSString( | 340 NSString* title = base::SysUTF16ToNSString( |
| 342 [self wrenchMenuModel]->GetLabelForCommandId(IDC_ZOOM_PERCENT_DISPLAY)); | 341 [self appMenuModel]->GetLabelForCommandId(IDC_ZOOM_PERCENT_DISPLAY)); |
| 343 [[[buttonViewController_ zoomItem] viewWithTag:IDC_ZOOM_PERCENT_DISPLAY] | 342 [[[buttonViewController_ zoomItem] viewWithTag:IDC_ZOOM_PERCENT_DISPLAY] |
| 344 setTitle:title]; | 343 setTitle:title]; |
| 345 content::RecordAction(UserMetricsAction("ShowAppMenu")); | 344 content::RecordAction(UserMetricsAction("ShowAppMenu")); |
| 346 | 345 |
| 347 NSImage* icon = [self wrenchMenuModel]->browser()->window()->IsFullscreen() ? | 346 NSImage* icon = [self appMenuModel]->browser()->window()->IsFullscreen() |
| 348 [NSImage imageNamed:NSImageNameExitFullScreenTemplate] : | 347 ? [NSImage imageNamed:NSImageNameExitFullScreenTemplate] |
| 349 [NSImage imageNamed:NSImageNameEnterFullScreenTemplate]; | 348 : [NSImage imageNamed:NSImageNameEnterFullScreenTemplate]; |
| 350 [[buttonViewController_ zoomFullScreen] setImage:icon]; | 349 [[buttonViewController_ zoomFullScreen] setImage:icon]; |
| 351 } | 350 } |
| 352 | 351 |
| 353 - (void)menuDidClose:(NSMenu*)menu { | 352 - (void)menuDidClose:(NSMenu*)menu { |
| 354 [super menuDidClose:menu]; | 353 [super menuDidClose:menu]; |
| 355 // We don't need to observe changes to zoom or toolbar size when the menu is | 354 // We don't need to observe changes to zoom or toolbar size when the menu is |
| 356 // closed, since we instantiate it with the proper value and recreate the menu | 355 // closed, since we instantiate it with the proper value and recreate the menu |
| 357 // on each show. (We do this in -menuNeedsUpdate:, which is called when the | 356 // on each show. (We do this in -menuNeedsUpdate:, which is called when the |
| 358 // menu is about to be displayed at the start of a tracking session.) | 357 // menu is about to be displayed at the start of a tracking session.) |
| 359 zoom_level_observer_.reset(); | 358 zoom_level_observer_.reset(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 // to wonky behavior (e.g. http://crbug.com/49716). To avoid this, schedule | 405 // to wonky behavior (e.g. http://crbug.com/49716). To avoid this, schedule |
| 407 // the dispatch on the outermost run loop. | 406 // the dispatch on the outermost run loop. |
| 408 [self performSelector:@selector(performCommandDispatch:) | 407 [self performSelector:@selector(performCommandDispatch:) |
| 409 withObject:[NSNumber numberWithInt:tag] | 408 withObject:[NSNumber numberWithInt:tag] |
| 410 afterDelay:0.0]; | 409 afterDelay:0.0]; |
| 411 } | 410 } |
| 412 } | 411 } |
| 413 | 412 |
| 414 // Used to perform the actual dispatch on the outermost runloop. | 413 // Used to perform the actual dispatch on the outermost runloop. |
| 415 - (void)performCommandDispatch:(NSNumber*)tag { | 414 - (void)performCommandDispatch:(NSNumber*)tag { |
| 416 [self wrenchMenuModel]->ExecuteCommand([tag intValue], 0); | 415 [self appMenuModel]->ExecuteCommand([tag intValue], 0); |
| 417 } | 416 } |
| 418 | 417 |
| 419 - (WrenchMenuModel*)wrenchMenuModel { | 418 - (AppMenuModel*)appMenuModel { |
| 420 // Don't use |wrenchMenuModel_| so that a test can override the generic one. | 419 // Don't use |appMenuModel_| so that a test can override the generic one. |
| 421 return static_cast<WrenchMenuModel*>(model_); | 420 return static_cast<AppMenuModel*>(model_); |
| 422 } | 421 } |
| 423 | 422 |
| 424 - (void)updateRecentTabsSubmenu { | 423 - (void)updateRecentTabsSubmenu { |
| 425 ui::MenuModel* model = [self recentTabsMenuModel]; | 424 ui::MenuModel* model = [self recentTabsMenuModel]; |
| 426 if (model) { | 425 if (model) { |
| 427 recentTabsMenuModelDelegate_.reset( | 426 recentTabsMenuModelDelegate_.reset( |
| 428 new RecentTabsMenuModelDelegate(model, [self recentTabsSubmenu])); | 427 new RecentTabsMenuModelDelegate(model, [self recentTabsSubmenu])); |
| 429 } | 428 } |
| 430 } | 429 } |
| 431 | 430 |
| 432 - (BrowserActionsController*)browserActionsController { | 431 - (BrowserActionsController*)browserActionsController { |
| 433 return browserActionsController_.get(); | 432 return browserActionsController_.get(); |
| 434 } | 433 } |
| 435 | 434 |
| 436 - (void)createModel { | 435 - (void)createModel { |
| 437 DCHECK(browser_); | 436 DCHECK(browser_); |
| 438 recentTabsMenuModelDelegate_.reset(); | 437 recentTabsMenuModelDelegate_.reset(); |
| 439 wrenchMenuModel_.reset( | 438 appMenuModel_.reset(new AppMenuModel(acceleratorDelegate_.get(), browser_)); |
| 440 new WrenchMenuModel(acceleratorDelegate_.get(), browser_)); | 439 [self setModel:appMenuModel_.get()]; |
| 441 [self setModel:wrenchMenuModel_.get()]; | |
| 442 | 440 |
| 443 buttonViewController_.reset( | 441 buttonViewController_.reset( |
| 444 [[WrenchMenuButtonViewController alloc] initWithController:self]); | 442 [[WrenchMenuButtonViewController alloc] initWithController:self]); |
| 445 [buttonViewController_ view]; | 443 [buttonViewController_ view]; |
| 446 | 444 |
| 447 // See comment in containerSuperviewFrameChanged:. | 445 // See comment in containerSuperviewFrameChanged:. |
| 448 NSView* containerSuperview = | 446 NSView* containerSuperview = |
| 449 [[buttonViewController_ overflowActionsContainerView] superview]; | 447 [[buttonViewController_ overflowActionsContainerView] superview]; |
| 450 [containerSuperview setPostsFrameChangedNotifications:YES]; | 448 [containerSuperview setPostsFrameChangedNotifications:YES]; |
| 451 } | 449 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 NSString* title = l10n_util::GetNSStringWithFixup(IDS_RECENT_TABS_MENU); | 516 NSString* title = l10n_util::GetNSStringWithFixup(IDS_RECENT_TABS_MENU); |
| 519 return [[[self menu] itemWithTitle:title] submenu]; | 517 return [[[self menu] itemWithTitle:title] submenu]; |
| 520 } | 518 } |
| 521 | 519 |
| 522 // The recent tabs menu model is recognized by the existence of either the | 520 // The recent tabs menu model is recognized by the existence of either the |
| 523 // kRecentlyClosedHeaderCommandId or the kDisabledRecentlyClosedHeaderCommandId. | 521 // kRecentlyClosedHeaderCommandId or the kDisabledRecentlyClosedHeaderCommandId. |
| 524 - (RecentTabsSubMenuModel*)recentTabsMenuModel { | 522 - (RecentTabsSubMenuModel*)recentTabsMenuModel { |
| 525 int index = 0; | 523 int index = 0; |
| 526 // Start searching at the wrench menu model level, |model| will be updated | 524 // Start searching at the wrench menu model level, |model| will be updated |
| 527 // only if the command we're looking for is found in one of the [sub]menus. | 525 // only if the command we're looking for is found in one of the [sub]menus. |
| 528 ui::MenuModel* model = [self wrenchMenuModel]; | 526 ui::MenuModel* model = [self appMenuModel]; |
| 529 if (ui::MenuModel::GetModelAndIndexForCommandId( | 527 if (ui::MenuModel::GetModelAndIndexForCommandId( |
| 530 RecentTabsSubMenuModel::kRecentlyClosedHeaderCommandId, &model, | 528 RecentTabsSubMenuModel::kRecentlyClosedHeaderCommandId, &model, |
| 531 &index)) { | 529 &index)) { |
| 532 return static_cast<RecentTabsSubMenuModel*>(model); | 530 return static_cast<RecentTabsSubMenuModel*>(model); |
| 533 } | 531 } |
| 534 if (ui::MenuModel::GetModelAndIndexForCommandId( | 532 if (ui::MenuModel::GetModelAndIndexForCommandId( |
| 535 RecentTabsSubMenuModel::kDisabledRecentlyClosedHeaderCommandId, | 533 RecentTabsSubMenuModel::kDisabledRecentlyClosedHeaderCommandId, |
| 536 &model, &index)) { | 534 &model, &index)) { |
| 537 return static_cast<RecentTabsSubMenuModel*>(model); | 535 return static_cast<RecentTabsSubMenuModel*>(model); |
| 538 } | 536 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 // (and thus, after all our ability to adjust it normally). Throw in the | 600 // (and thus, after all our ability to adjust it normally). Throw in the |
| 603 // towel, and simply don't let the frame move from where it's supposed to be. | 601 // towel, and simply don't let the frame move from where it's supposed to be. |
| 604 // TODO(devlin): Yet another Cocoa hack. It'd be good to find a workaround, | 602 // TODO(devlin): Yet another Cocoa hack. It'd be good to find a workaround, |
| 605 // but unlikely unless we replace the Cocoa menu implementation. | 603 // but unlikely unless we replace the Cocoa menu implementation. |
| 606 NSView* containerSuperview = [overflowActionsContainerView_ superview]; | 604 NSView* containerSuperview = [overflowActionsContainerView_ superview]; |
| 607 if (NSMinX([containerSuperview frame]) != 0) | 605 if (NSMinX([containerSuperview frame]) != 0) |
| 608 [containerSuperview setFrameOrigin:NSZeroPoint]; | 606 [containerSuperview setFrameOrigin:NSZeroPoint]; |
| 609 } | 607 } |
| 610 | 608 |
| 611 @end // @implementation WrenchMenuButtonViewController | 609 @end // @implementation WrenchMenuButtonViewController |
| OLD | NEW |