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/strings/string16.h" | 9 #include "base/strings/string16.h" |
10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 - (void)createModel; | 50 - (void)createModel; |
51 - (void)adjustPositioning; | 51 - (void)adjustPositioning; |
52 - (void)performCommandDispatch:(NSNumber*)tag; | 52 - (void)performCommandDispatch:(NSNumber*)tag; |
53 - (NSButton*)zoomDisplay; | 53 - (NSButton*)zoomDisplay; |
54 - (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item; | 54 - (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item; |
55 - (void)removeAllItems:(NSMenu*)menu; | 55 - (void)removeAllItems:(NSMenu*)menu; |
56 - (NSMenu*)recentTabsSubmenu; | 56 - (NSMenu*)recentTabsSubmenu; |
57 - (RecentTabsSubMenuModel*)recentTabsMenuModel; | 57 - (RecentTabsSubMenuModel*)recentTabsMenuModel; |
58 - (int)maxWidthForMenuModel:(ui::MenuModel*)model | 58 - (int)maxWidthForMenuModel:(ui::MenuModel*)model |
59 modelIndex:(int)modelIndex; | 59 modelIndex:(int)modelIndex; |
| 60 - (void)containerSuperviewFrameChanged:(NSNotification*)notification; |
60 @end | 61 @end |
61 | 62 |
62 namespace WrenchMenuControllerInternal { | 63 namespace WrenchMenuControllerInternal { |
63 | 64 |
64 // A C++ delegate that handles the accelerators in the wrench menu. | 65 // A C++ delegate that handles the accelerators in the wrench menu. |
65 class AcceleratorDelegate : public ui::AcceleratorProvider { | 66 class AcceleratorDelegate : public ui::AcceleratorProvider { |
66 public: | 67 public: |
67 bool GetAcceleratorForCommandId(int command_id, | 68 bool GetAcceleratorForCommandId(int command_id, |
68 ui::Accelerator* out_accelerator) override { | 69 ui::Accelerator* out_accelerator) override { |
69 AcceleratorsCocoa* keymap = AcceleratorsCocoa::GetInstance(); | 70 AcceleratorsCocoa* keymap = AcceleratorsCocoa::GetInstance(); |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 bookmarkMenu)); | 252 bookmarkMenu)); |
252 } | 253 } |
253 | 254 |
254 - (void)updateBrowserActionsSubmenu { | 255 - (void)updateBrowserActionsSubmenu { |
255 MenuTrackedRootView* view = | 256 MenuTrackedRootView* view = |
256 [buttonViewController_ toolbarActionsOverflowItem]; | 257 [buttonViewController_ toolbarActionsOverflowItem]; |
257 BrowserActionsContainerView* containerView = | 258 BrowserActionsContainerView* containerView = |
258 [buttonViewController_ overflowActionsContainerView]; | 259 [buttonViewController_ overflowActionsContainerView]; |
259 | 260 |
260 // Find the preferred container size for the menu width. | 261 // Find the preferred container size for the menu width. |
261 int maxContainerWidth = | 262 int menuWidth = [[self menu] size].width; |
262 [[self menu] size].width - kLeftPadding - kRightPadding; | 263 int maxContainerWidth = menuWidth - kLeftPadding - kRightPadding; |
| 264 // Don't let the menu change sizes on us. (We lift this restriction every time |
| 265 // the menu updates, so if something changes, this won't leave us with an |
| 266 // awkward size.) |
| 267 [[self menu] setMinimumWidth:menuWidth]; |
263 gfx::Size preferredContainerSize = | 268 gfx::Size preferredContainerSize = |
264 [browserActionsController_ sizeForOverflowWidth:maxContainerWidth]; | 269 [browserActionsController_ sizeForOverflowWidth:maxContainerWidth]; |
265 | 270 |
266 // Set the origins and preferred size for the container. | 271 // Set the origins and preferred size for the container. |
267 // View hierarchy is as follows (from parent > child): | 272 // View hierarchy is as follows (from parent > child): |
268 // |view| > |anonymous view| > containerView. We have to set the origin | 273 // |view| > |anonymous view| > containerView. We have to set the origin |
269 // and size of each for it display properly. | 274 // and size of each for it display properly. |
270 // The parent views each have a size of the full width of the menu, so we can | 275 // The parent views each have a size of the full width of the menu, so we can |
271 // properly position the container. | 276 // properly position the container. |
272 NSSize parentSize = | 277 NSSize parentSize = NSMakeSize(menuWidth, preferredContainerSize.height()); |
273 NSMakeSize([[self menu] size].width, preferredContainerSize.height()); | |
274 [view setFrameSize:parentSize]; | 278 [view setFrameSize:parentSize]; |
275 [[containerView superview] setFrameSize:parentSize]; | 279 [[containerView superview] setFrameSize:parentSize]; |
276 | 280 |
277 // The container view gets its preferred size. | 281 // The container view gets its preferred size. |
278 [containerView setFrameSize:NSMakeSize(preferredContainerSize.width(), | 282 [containerView setFrameSize:NSMakeSize(preferredContainerSize.width(), |
279 preferredContainerSize.height())]; | 283 preferredContainerSize.height())]; |
280 [browserActionsController_ update]; | 284 [browserActionsController_ update]; |
281 | 285 |
282 [view setFrameOrigin:NSZeroPoint]; | 286 [view setFrameOrigin:NSZeroPoint]; |
283 [[containerView superview] setFrameOrigin:NSZeroPoint]; | 287 [[containerView superview] setFrameOrigin:NSZeroPoint]; |
(...skipping 12 matching lines...) Expand all Loading... |
296 NSImage* icon = [self wrenchMenuModel]->browser()->window()->IsFullscreen() ? | 300 NSImage* icon = [self wrenchMenuModel]->browser()->window()->IsFullscreen() ? |
297 [NSImage imageNamed:NSImageNameExitFullScreenTemplate] : | 301 [NSImage imageNamed:NSImageNameExitFullScreenTemplate] : |
298 [NSImage imageNamed:NSImageNameEnterFullScreenTemplate]; | 302 [NSImage imageNamed:NSImageNameEnterFullScreenTemplate]; |
299 [[buttonViewController_ zoomFullScreen] setImage:icon]; | 303 [[buttonViewController_ zoomFullScreen] setImage:icon]; |
300 } | 304 } |
301 | 305 |
302 - (void)menuNeedsUpdate:(NSMenu*)menu { | 306 - (void)menuNeedsUpdate:(NSMenu*)menu { |
303 // First empty out the menu and create a new model. | 307 // First empty out the menu and create a new model. |
304 [self removeAllItems:menu]; | 308 [self removeAllItems:menu]; |
305 [self createModel]; | 309 [self createModel]; |
| 310 [menu setMinimumWidth:0]; |
306 | 311 |
307 // Create a new menu, which cannot be swapped because the tracking is about to | 312 // Create a new menu, which cannot be swapped because the tracking is about to |
308 // start, so simply copy the items. | 313 // start, so simply copy the items. |
309 NSMenu* newMenu = [self menuFromModel:model_]; | 314 NSMenu* newMenu = [self menuFromModel:model_]; |
310 NSArray* itemArray = [newMenu itemArray]; | 315 NSArray* itemArray = [newMenu itemArray]; |
311 [self removeAllItems:newMenu]; | 316 [self removeAllItems:newMenu]; |
312 for (NSMenuItem* item in itemArray) { | 317 for (NSMenuItem* item in itemArray) { |
313 [menu addItem:item]; | 318 [menu addItem:item]; |
314 } | 319 } |
315 | 320 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 - (void)createModel { | 379 - (void)createModel { |
375 DCHECK(browser_); | 380 DCHECK(browser_); |
376 recentTabsMenuModelDelegate_.reset(); | 381 recentTabsMenuModelDelegate_.reset(); |
377 wrenchMenuModel_.reset( | 382 wrenchMenuModel_.reset( |
378 new WrenchMenuModel(acceleratorDelegate_.get(), browser_)); | 383 new WrenchMenuModel(acceleratorDelegate_.get(), browser_)); |
379 [self setModel:wrenchMenuModel_.get()]; | 384 [self setModel:wrenchMenuModel_.get()]; |
380 | 385 |
381 buttonViewController_.reset( | 386 buttonViewController_.reset( |
382 [[WrenchMenuButtonViewController alloc] initWithController:self]); | 387 [[WrenchMenuButtonViewController alloc] initWithController:self]); |
383 [buttonViewController_ view]; | 388 [buttonViewController_ view]; |
| 389 |
| 390 // See comment in containerSuperviewFrameChanged:. |
| 391 NSView* containerSuperview = |
| 392 [[buttonViewController_ overflowActionsContainerView] superview]; |
| 393 [containerSuperview setPostsFrameChangedNotifications:YES]; |
| 394 [[NSNotificationCenter defaultCenter] |
| 395 addObserver:self |
| 396 selector:@selector(containerSuperviewFrameChanged:) |
| 397 name:NSViewFrameDidChangeNotification |
| 398 object:containerSuperview]; |
384 } | 399 } |
385 | 400 |
386 // Fit the localized strings into the Cut/Copy/Paste control, then resize the | 401 // Fit the localized strings into the Cut/Copy/Paste control, then resize the |
387 // whole menu item accordingly. | 402 // whole menu item accordingly. |
388 - (void)adjustPositioning { | 403 - (void)adjustPositioning { |
389 const CGFloat kButtonPadding = 12; | 404 const CGFloat kButtonPadding = 12; |
390 CGFloat delta = 0; | 405 CGFloat delta = 0; |
391 | 406 |
392 // Go through the three buttons from right-to-left, adjusting the size to fit | 407 // Go through the three buttons from right-to-left, adjusting the size to fit |
393 // the localized strings while keeping them all aligned on their horizontal | 408 // the localized strings while keeping them all aligned on their horizontal |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 // menu. | 491 // menu. |
477 - (int)maxWidthForMenuModel:(ui::MenuModel*)model | 492 - (int)maxWidthForMenuModel:(ui::MenuModel*)model |
478 modelIndex:(int)modelIndex { | 493 modelIndex:(int)modelIndex { |
479 RecentTabsSubMenuModel* recentTabsMenuModel = [self recentTabsMenuModel]; | 494 RecentTabsSubMenuModel* recentTabsMenuModel = [self recentTabsMenuModel]; |
480 if (recentTabsMenuModel && recentTabsMenuModel == model) { | 495 if (recentTabsMenuModel && recentTabsMenuModel == model) { |
481 return recentTabsMenuModel->GetMaxWidthForItemAtIndex(modelIndex); | 496 return recentTabsMenuModel->GetMaxWidthForItemAtIndex(modelIndex); |
482 } | 497 } |
483 return -1; | 498 return -1; |
484 } | 499 } |
485 | 500 |
| 501 - (void)containerSuperviewFrameChanged:(NSNotification*)notification { |
| 502 // AppKit menus were probably never designed with a view like the browser |
| 503 // actions container in mind, and, as a result, we come across a few oddities. |
| 504 // One of these is that the container's superview will, on some versions of |
| 505 // OSX, change frame position sometime after the the menu begins tracking |
| 506 // (and thus, after all our ability to adjust it normally). Throw in the |
| 507 // towel, and simply don't let the frame move from where it's supposed to be. |
| 508 // TODO(devlin): Yet another Cocoa hack. It'd be good to find a workaround, |
| 509 // but unlikely unless we replace the Cocoa menu implementation. |
| 510 NSView* containerSuperview = |
| 511 [[buttonViewController_ overflowActionsContainerView] superview]; |
| 512 if (NSMinX([containerSuperview frame]) != 0) |
| 513 [containerSuperview setFrameOrigin:NSZeroPoint]; |
| 514 } |
| 515 |
486 @end // @implementation WrenchMenuController | 516 @end // @implementation WrenchMenuController |
487 | 517 |
488 //////////////////////////////////////////////////////////////////////////////// | 518 //////////////////////////////////////////////////////////////////////////////// |
489 | 519 |
490 @implementation WrenchMenuButtonViewController | 520 @implementation WrenchMenuButtonViewController |
491 | 521 |
492 @synthesize editItem = editItem_; | 522 @synthesize editItem = editItem_; |
493 @synthesize editCut = editCut_; | 523 @synthesize editCut = editCut_; |
494 @synthesize editCopy = editCopy_; | 524 @synthesize editCopy = editCopy_; |
495 @synthesize editPaste = editPaste_; | 525 @synthesize editPaste = editPaste_; |
(...skipping 11 matching lines...) Expand all Loading... |
507 controller_ = controller; | 537 controller_ = controller; |
508 } | 538 } |
509 return self; | 539 return self; |
510 } | 540 } |
511 | 541 |
512 - (IBAction)dispatchWrenchMenuCommand:(id)sender { | 542 - (IBAction)dispatchWrenchMenuCommand:(id)sender { |
513 [controller_ dispatchWrenchMenuCommand:sender]; | 543 [controller_ dispatchWrenchMenuCommand:sender]; |
514 } | 544 } |
515 | 545 |
516 @end // @implementation WrenchMenuButtonViewController | 546 @end // @implementation WrenchMenuButtonViewController |
OLD | NEW |