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

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

Issue 3072014: [Mac] Enable click-drag-release behavior in the Wrench menu's custom items. (Closed)
Patch Set: address comments Created 10 years, 4 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
« no previous file with comments | « chrome/browser/cocoa/wrench_menu_controller.h ('k') | chrome/chrome_browser.gypi » ('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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/wrench_menu_controller.h" 5 #import "chrome/browser/cocoa/wrench_menu_controller.h"
6 6
7 #include "app/menus/menu_model.h" 7 #include "app/menus/menu_model.h"
8 #include "base/sys_string_conversions.h" 8 #include "base/sys_string_conversions.h"
9 #include "chrome/app/chrome_dll_resource.h" 9 #include "chrome/app/chrome_dll_resource.h"
10 #include "chrome/browser/browser.h" 10 #include "chrome/browser/browser.h"
11 #include "chrome/browser/browser_window.h" 11 #include "chrome/browser/browser_window.h"
12 #import "chrome/browser/cocoa/menu_tracked_root_view.h"
12 #import "chrome/browser/cocoa/toolbar_controller.h" 13 #import "chrome/browser/cocoa/toolbar_controller.h"
13 #include "chrome/browser/wrench_menu_model.h" 14 #include "chrome/browser/wrench_menu_model.h"
14 15
15 @interface WrenchMenuController (Private) 16 @interface WrenchMenuController (Private)
16 - (void)adjustPositioning; 17 - (void)adjustPositioning;
17 - (void)performCommandDispatch:(NSNumber*)tag; 18 - (void)performCommandDispatch:(NSNumber*)tag;
18 @end 19 @end
19 20
20 @implementation WrenchMenuController 21 @implementation WrenchMenuController
21 22
(...skipping 19 matching lines...) Expand all
41 // Handle the special-cased menu items. 42 // Handle the special-cased menu items.
42 int command_id = model->GetCommandIdAt(modelIndex); 43 int command_id = model->GetCommandIdAt(modelIndex);
43 scoped_nsobject<NSMenuItem> customItem( 44 scoped_nsobject<NSMenuItem> customItem(
44 [[NSMenuItem alloc] initWithTitle:@"" 45 [[NSMenuItem alloc] initWithTitle:@""
45 action:nil 46 action:nil
46 keyEquivalent:@""]); 47 keyEquivalent:@""]);
47 switch (command_id) { 48 switch (command_id) {
48 case IDC_EDIT_MENU: 49 case IDC_EDIT_MENU:
49 DCHECK(editItem_); 50 DCHECK(editItem_);
50 [customItem setView:editItem_]; 51 [customItem setView:editItem_];
52 [editItem_ setMenuItem:customItem];
51 break; 53 break;
52 case IDC_ZOOM_MENU: 54 case IDC_ZOOM_MENU:
53 DCHECK(zoomItem_); 55 DCHECK(zoomItem_);
54 [customItem setView:zoomItem_]; 56 [customItem setView:zoomItem_];
57 [zoomItem_ setMenuItem:customItem];
55 break; 58 break;
56 default: 59 default:
57 NOTREACHED(); 60 NOTREACHED();
58 break; 61 break;
59 } 62 }
60 [self adjustPositioning]; 63 [self adjustPositioning];
61 [menu insertItem:customItem.get() atIndex:index]; 64 [menu insertItem:customItem.get() atIndex:index];
62 } 65 }
63 66
64 - (NSMenu*)menu { 67 - (NSMenu*)menu {
65 NSMenu* menu = [super menu]; 68 NSMenu* menu = [super menu];
66 if (![menu delegate]) { 69 if (![menu delegate]) {
67 [menu setDelegate:self]; 70 [menu setDelegate:self];
68 } 71 }
69 return menu; 72 return menu;
70 } 73 }
71 74
72 - (void)menuWillOpen:(NSMenu*)menu { 75 - (void)menuWillOpen:(NSMenu*)menu {
73 NSString* title = base::SysUTF16ToNSString( 76 NSString* title = base::SysUTF16ToNSString(
74 [self wrenchMenuModel]->GetLabelForCommandId(IDC_ZOOM_PERCENT_DISPLAY)); 77 [self wrenchMenuModel]->GetLabelForCommandId(IDC_ZOOM_PERCENT_DISPLAY));
75 [[zoomItem_ viewWithTag:IDC_ZOOM_PERCENT_DISPLAY] setTitle:title]; 78 [[zoomItem_ viewWithTag:IDC_ZOOM_PERCENT_DISPLAY] setTitle:title];
79
76 bool plusEnabled = [self wrenchMenuModel]->IsCommandIdEnabled(IDC_ZOOM_PLUS); 80 bool plusEnabled = [self wrenchMenuModel]->IsCommandIdEnabled(IDC_ZOOM_PLUS);
77 bool minusEnabled = [self wrenchMenuModel]->IsCommandIdEnabled( 81 bool minusEnabled = [self wrenchMenuModel]->IsCommandIdEnabled(
78 IDC_ZOOM_MINUS); 82 IDC_ZOOM_MINUS);
79
80 [zoomPlus_ setEnabled:plusEnabled]; 83 [zoomPlus_ setEnabled:plusEnabled];
81 [zoomMinus_ setEnabled:minusEnabled]; 84 [zoomMinus_ setEnabled:minusEnabled];
82 85
83 NSImage* icon = [self wrenchMenuModel]->browser()->window()->IsFullscreen() ? 86 NSImage* icon = [self wrenchMenuModel]->browser()->window()->IsFullscreen() ?
84 [NSImage imageNamed:NSImageNameExitFullScreenTemplate] : 87 [NSImage imageNamed:NSImageNameExitFullScreenTemplate] :
85 [NSImage imageNamed:NSImageNameEnterFullScreenTemplate]; 88 [NSImage imageNamed:NSImageNameEnterFullScreenTemplate];
86 [zoomFullScreen_ setImage:icon]; 89 [zoomFullScreen_ setImage:icon];
87 } 90 }
88 91
89 // Used to dispatch commands from the Wrench menu. The custom items within the 92 // Used to dispatch commands from the Wrench menu. The custom items within the
90 // menu cannot be hooked up directly to First Responder because the window in 93 // menu cannot be hooked up directly to First Responder because the window in
91 // which the controls reside is not the BrowserWindowController, but a 94 // which the controls reside is not the BrowserWindowController, but a
92 // NSCarbonMenuWindow; this screws up the typical |-commandDispatch:| system. 95 // NSCarbonMenuWindow; this screws up the typical |-commandDispatch:| system.
93 - (IBAction)dispatchWrenchMenuCommand:(id)sender { 96 - (IBAction)dispatchWrenchMenuCommand:(id)sender {
94 NSInteger tag = [sender tag]; 97 NSInteger tag = [sender tag];
95
96 // NSSegmentedControls (used for the Edit item) need a little help to get the
97 // command_id of the pressed item.
98 if ([sender isKindOfClass:[NSSegmentedControl class]])
99 tag = [[sender cell] tagForSegment:[sender selectedSegment]];
100
101 // The custom views within the Wrench menu are abnormal and keep the menu open 98 // The custom views within the Wrench menu are abnormal and keep the menu open
102 // after a target-action. Close the menu manually. 99 // after a target-action. Close the menu manually.
103 // TODO(rsesek): It'd be great if the zoom buttons didn't have to close the 100 // TODO(rsesek): It'd be great if the zoom buttons didn't have to close the
104 // menu. See http://crbug.com/48679 for more info. 101 // menu. See http://crbug.com/48679 for more info.
105 [menu_ cancelTracking]; 102 [menu_ cancelTracking];
106 [self dispatchCommandInternal:tag]; 103 [self dispatchCommandInternal:tag];
107 } 104 }
108 105
109 - (void)dispatchCommandInternal:(NSInteger)tag { 106 - (void)dispatchCommandInternal:(NSInteger)tag {
110 // Executing certain commands from the nested run loop of the menu can lead 107 // Executing certain commands from the nested run loop of the menu can lead
111 // to wonky behavior (e.g. http://crbug.com/49716). To avoid this, schedule 108 // to wonky behavior (e.g. http://crbug.com/49716). To avoid this, schedule
112 // the dispatch on the outermost run loop. 109 // the dispatch on the outermost run loop.
113 [self performSelector:@selector(performCommandDispatch:) 110 [self performSelector:@selector(performCommandDispatch:)
114 withObject:[NSNumber numberWithInt:tag] 111 withObject:[NSNumber numberWithInt:tag]
115 afterDelay:0.0]; 112 afterDelay:0.0];
116 } 113 }
117 114
118 // Used to perform the actual dispatch on the outermost runloop. 115 // Used to perform the actual dispatch on the outermost runloop.
119 - (void)performCommandDispatch:(NSNumber*)tag { 116 - (void)performCommandDispatch:(NSNumber*)tag {
120 [self wrenchMenuModel]->ExecuteCommand([tag intValue]); 117 [self wrenchMenuModel]->ExecuteCommand([tag intValue]);
121 } 118 }
122 119
123 - (WrenchMenuModel*)wrenchMenuModel { 120 - (WrenchMenuModel*)wrenchMenuModel {
124 return static_cast<WrenchMenuModel*>(model_); 121 return static_cast<WrenchMenuModel*>(model_);
125 } 122 }
126 123
127 // Fit the localized strings into the Cut/Copy/Paste control, then resize the 124 // Fit the localized strings into the Cut/Copy/Paste control, then resize the
128 // whole menu item accordingly. 125 // whole menu item accordingly.
129 - (void)adjustPositioning { 126 - (void)adjustPositioning {
127 const CGFloat kButtonPadding = 12;
128 CGFloat delta = 0;
129
130 // Go through the three buttons from right-to-left, adjusting the size to fit
131 // the localized strings while keeping them all aligned on their horizontal
132 // edges.
133 const size_t kAdjustViewCount = 3;
134 NSButton* views[kAdjustViewCount] = { editPaste_, editCopy_, editCut_ };
135 for (size_t i = 0; i < kAdjustViewCount; ++i) {
Nico 2010/08/03 18:21:10 nit: why not NSButton* views[] = { editPaste_,
136 NSButton* button = views[i];
137 CGFloat originalWidth = NSWidth([button frame]);
138
139 // Do not let |-sizeToFit| change the height of the button.
140 NSSize size = [button frame].size;
141 [button sizeToFit];
142 size.width = [button frame].size.width + kButtonPadding;
143 [button setFrameSize:size];
144
145 CGFloat newWidth = size.width;
146 delta += newWidth - originalWidth;
147
148 NSRect frame = [button frame];
149 frame.origin.x -= delta;
150 [button setFrame:frame];
151 }
152
153 // Resize the menu item by the total amound the buttons changed so that the
154 // spacing between the buttons and the title remains the same.
130 NSRect itemFrame = [editItem_ frame]; 155 NSRect itemFrame = [editItem_ frame];
131 NSRect controlFrame = [editControl_ frame]; 156 itemFrame.size.width += delta;
132
133 CGFloat originalControlWidth = NSWidth(controlFrame);
134 // Maintain the carefully pixel-pushed gap between the edge of the menu and
135 // the rightmost control.
136 CGFloat edge = NSWidth(itemFrame) -
137 (controlFrame.origin.x + originalControlWidth);
138
139 // Resize the edit segmented control to fit the localized strings.
140 [editControl_ sizeToFit];
141 controlFrame = [editControl_ frame];
142 CGFloat resizeAmount = NSWidth(controlFrame) - originalControlWidth;
143
144 // Adjust the size of the entire menu item to account for changes in the size
145 // of the segmented control.
146 itemFrame.size.width += resizeAmount;
147 [editItem_ setFrame:itemFrame]; 157 [editItem_ setFrame:itemFrame];
148 158
149 // Keep the spacing between the right edges of the menu and the control. 159 // Also resize the superview of the buttons, which is an NSView used to slide
150 controlFrame.origin.x = NSWidth(itemFrame) - edge - NSWidth(controlFrame); 160 // when the item title is too big and GTM resizes it.
151 [editControl_ setFrame:controlFrame]; 161 NSRect parentFrame = [[editCut_ superview] frame];
162 parentFrame.size.width += delta;
163 parentFrame.origin.x -= delta;
164 [[editCut_ superview] setFrame:parentFrame];
152 } 165 }
153 166
154 @end // @implementation WrenchMenuController 167 @end // @implementation WrenchMenuController
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/wrench_menu_controller.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698