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

Side by Side Diff: webkit/tools/test_shell/mac/test_webview_delegate.mm

Issue 92062: Clean up cocoa popup menu handling for test_shell (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2008 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 #include "webkit/tools/test_shell/test_webview_delegate.h" 5 #include "webkit/tools/test_shell/test_webview_delegate.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 #include "base/sys_string_conversions.h" 8 #include "base/sys_string_conversions.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" 10 #include "third_party/WebKit/WebKit/chromium/public/WebRect.h"
11 #include "webkit/glue/webcursor.h" 11 #include "webkit/glue/webcursor.h"
12 #include "webkit/glue/webview.h" 12 #include "webkit/glue/webview.h"
13 #include "webkit/glue/plugins/plugin_list.h" 13 #include "webkit/glue/plugins/plugin_list.h"
14 #include "webkit/glue/plugins/webplugin_delegate_impl.h" 14 #include "webkit/glue/plugins/webplugin_delegate_impl.h"
15 #include "webkit/glue/webmenurunner_mac.h"
15 #include "webkit/tools/test_shell/test_shell.h" 16 #include "webkit/tools/test_shell/test_shell.h"
16 17
17 using WebKit::WebRect; 18 using WebKit::WebRect;
18 19
19 // MenuDelegate ----------------------------------------------------------------
20 // A class for determining whether an item was selected from an HTML select
21 // control, or if the menu was dismissed without making a selection. If a menu
22 // item is selected, MenuDelegate is informed and sets a flag which can be
23 // queried after the menu has finished running.
24
25 @interface MenuDelegate : NSObject {
26 @private
27 NSMenu* menu_; // Non-owning
28 BOOL menuItemWasChosen_;
29 }
30 - (id)initWithItems:(const std::vector<WebMenuItem>&)items
31 forMenu:(NSMenu*)menu;
32 - (void)addItem:(const WebMenuItem&)item;
33 - (BOOL)menuItemWasChosen;
34 - (void)menuItemSelected:(id)sender;
35 @end
36
37 @implementation MenuDelegate
38
39 - (id)initWithItems:(const std::vector<WebMenuItem>&)items
40 forMenu:(NSMenu*)menu {
41 if ((self = [super init])) {
42 menu_ = menu;
43 menuItemWasChosen_ = NO;
44 for (int i = 0; i < static_cast<int>(items.size()); ++i)
45 [self addItem:items[i]];
46 }
47 return self;
48 }
49
50 - (void)addItem:(const WebMenuItem&)item {
51 if (item.type == WebMenuItem::SEPARATOR) {
52 [menu_ addItem:[NSMenuItem separatorItem]];
53 return;
54 }
55
56 NSString* title = base::SysUTF16ToNSString(item.label);
57 NSMenuItem* menu_item = [menu_ addItemWithTitle:title
58 action:@selector(menuItemSelected:)
59 keyEquivalent:@""];
60 [menu_item setEnabled:(item.enabled && item.type != WebMenuItem::GROUP)];
61 [menu_item setTarget:self];
62 }
63
64 // Reflects the result of the user's interaction with the popup menu. If NO, the
65 // menu was dismissed without the user choosing an item, which can happen if the
66 // user clicked outside the menu region or hit the escape key. If YES, the user
67 // selected an item from the menu.
68 - (BOOL)menuItemWasChosen {
69 return menuItemWasChosen_;
70 }
71
72 - (void)menuItemSelected:(id)sender {
73 menuItemWasChosen_ = YES;
74 }
75
76 @end // MenuDelegate
77
78
79 // WebViewDelegate ----------------------------------------------------------- 20 // WebViewDelegate -----------------------------------------------------------
80 21
81 TestWebViewDelegate::~TestWebViewDelegate() { 22 TestWebViewDelegate::~TestWebViewDelegate() {
82 } 23 }
83 24
84 WebPluginDelegate* TestWebViewDelegate::CreatePluginDelegate( 25 WebPluginDelegate* TestWebViewDelegate::CreatePluginDelegate(
85 WebView* webview, 26 WebView* webview,
86 const GURL& url, 27 const GURL& url,
87 const std::string& mime_type, 28 const std::string& mime_type,
88 const std::string& clsid, 29 const std::string& clsid,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 WindowOpenDisposition disposition) { 64 WindowOpenDisposition disposition) {
124 } 65 }
125 66
126 // Display a HTML select menu. 67 // Display a HTML select menu.
127 void TestWebViewDelegate::ShowAsPopupWithItems( 68 void TestWebViewDelegate::ShowAsPopupWithItems(
128 WebWidget* webview, 69 WebWidget* webview,
129 const WebRect& bounds, 70 const WebRect& bounds,
130 int item_height, 71 int item_height,
131 int selected_index, 72 int selected_index,
132 const std::vector<WebMenuItem>& items) { 73 const std::vector<WebMenuItem>& items) {
133 // Populate the menu. 74 // Set up the menu position.
134 NSMenu* menu = [[[NSMenu alloc] initWithTitle:@""] autorelease];
135 [menu setAutoenablesItems:NO];
136 MenuDelegate* menu_delegate =
137 [[[MenuDelegate alloc] initWithItems:items forMenu:menu] autorelease];
138
139 // Set up the button cell, converting to NSView coordinates. The menu is
140 // positioned such that the currently selected menu item appears over the
141 // popup button, which is the expected Mac popup menu behavior.
142 NSPopUpButtonCell* button = [[NSPopUpButtonCell alloc] initTextCell:@""
143 pullsDown:NO];
144 [button autorelease];
145 [button setMenu:menu];
146 [button selectItemAtIndex:selected_index];
147 NSView* web_view = shell_->webViewWnd(); 75 NSView* web_view = shell_->webViewWnd();
148 NSRect view_rect = [web_view bounds]; 76 NSRect view_rect = [web_view bounds];
149 int y_offset = bounds.y + bounds.height; 77 int y_offset = bounds.y + bounds.height;
150 NSRect position = NSMakeRect(bounds.x, view_rect.size.height - y_offset, 78 NSRect position = NSMakeRect(bounds.x, view_rect.size.height - y_offset,
151 bounds.width, bounds.height); 79 bounds.width, bounds.height);
152 80
153 // Display the menu, and set a flag to determine if something was chosen. If 81 // Display the menu.
154 // nothing was chosen (i.e., the user dismissed the popup by the "ESC" key or 82 WebMenuRunner* menu_runner =
pink (ping after 24hrs) 2009/04/27 14:14:59 can you use a scoped_nsobject here?
155 // clicking outside popup's region), send a dismiss message to WebKit. 83 [[[WebMenuRunner alloc] initWithItems:items] autorelease];
156 [button performClickWithFrame:position inView:shell_->webViewWnd()]; 84
85 [menu_runner runMenuInView:shell_->webViewWnd()
86 withBounds:position
87 initialIndex:selected_index];
157 88
158 // Get the selected item and forward to WebKit. WebKit expects an input event 89 // Get the selected item and forward to WebKit. WebKit expects an input event
159 // (mouse down, keyboard activity) for this, so we calculate the proper 90 // (mouse down, keyboard activity) for this, so we calculate the proper
160 // position based on the selected index and provided bounds. 91 // position based on the selected index and provided bounds.
161 WebWidgetHost* popup = shell_->popupHost(); 92 WebWidgetHost* popup = shell_->popupHost();
162 NSEvent* event = nil;
163 double event_time = (double)(AbsoluteToDuration(UpTime())) / 1000.0;
164 int window_num = [shell_->mainWnd() windowNumber]; 93 int window_num = [shell_->mainWnd() windowNumber];
165 94
166 if ([menu_delegate menuItemWasChosen]) { 95 NSEvent* event = CreateEventForMenuAction([menu_runner menuItemWasChosen],
96 window_num, item_height,
97 [menu_runner indexOfSelectedItem],
98 position, view_rect);
99 if ([menu_runner menuItemWasChosen]) {
167 // Construct a mouse up event to simulate the selection of an appropriate 100 // Construct a mouse up event to simulate the selection of an appropriate
168 // menu item. 101 // menu item.
169 NSPoint click_pos;
170 click_pos.x = position.size.width / 2;
171
172 // This is going to be hard to calculate since the button is painted by
173 // WebKit, the menu by Cocoa, and we have to translate the selected_item
174 // index to a coordinate that WebKit's PopupMenu expects which uses a
175 // different font *and* expects to draw the menu below the button like we do
176 // on Windows.
177 // The WebKit popup menu thinks it will draw just below the button, so
178 // create the click at the offset based on the selected item's index and
179 // account for the different coordinate system used by NSView.
180 int item_offset = [button indexOfSelectedItem] * item_height +
181 item_height / 2;
182 click_pos.y = view_rect.size.height - item_offset;
183 event = [NSEvent mouseEventWithType:NSLeftMouseUp
184 location:click_pos
185 modifierFlags:0
186 timestamp:event_time
187 windowNumber:window_num
188 context:nil
189 eventNumber:0
190 clickCount:1
191 pressure:1.0];
192 popup->MouseEvent(event); 102 popup->MouseEvent(event);
193 } else { 103 } else {
194 // Fake an ESC key event (keyCode = 0x1B, from webinputevent_mac.mm) and 104 // Fake an ESC key event (keyCode = 0x1B, from webinputevent_mac.mm) and
195 // forward that to WebKit. 105 // forward that to WebKit.
196 NSPoint key_pos;
197 key_pos.x = 0;
198 key_pos.y = 0;
199 event = [NSEvent keyEventWithType:NSKeyUp
200 location:key_pos
201 modifierFlags:0
202 timestamp:event_time
203 windowNumber:window_num
204 context:nil
205 characters:@""
206 charactersIgnoringModifiers:@""
207 isARepeat:NO
208 keyCode:0x1B];
209 popup->KeyEvent(event); 106 popup->KeyEvent(event);
210 } 107 }
211 } 108 }
212 109
213 void TestWebViewDelegate::CloseWidgetSoon(WebWidget* webwidget) { 110 void TestWebViewDelegate::CloseWidgetSoon(WebWidget* webwidget) {
214 if (webwidget == shell_->webView()) { 111 if (webwidget == shell_->webView()) {
215 NSWindow *win = shell_->mainWnd(); 112 NSWindow *win = shell_->mainWnd();
216 // Tell Cocoa to close the window, which will let the window's delegate 113 // Tell Cocoa to close the window, which will let the window's delegate
217 // handle getting rid of the shell. |shell_| will still be alive for a short 114 // handle getting rid of the shell. |shell_| will still be alive for a short
218 // period of time after this call returns (cleanup is done after going back 115 // period of time after this call returns (cleanup is done after going back
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 void TestWebViewDelegate::SetPageTitle(const std::wstring& title) { 203 void TestWebViewDelegate::SetPageTitle(const std::wstring& title) {
307 [[shell_->webViewHost()->view_handle() window] 204 [[shell_->webViewHost()->view_handle() window]
308 setTitle:[NSString stringWithUTF8String:WideToUTF8(title).c_str()]]; 205 setTitle:[NSString stringWithUTF8String:WideToUTF8(title).c_str()]];
309 } 206 }
310 207
311 void TestWebViewDelegate::SetAddressBarURL(const GURL& url) { 208 void TestWebViewDelegate::SetAddressBarURL(const GURL& url) {
312 const char* frameURL = url.spec().c_str(); 209 const char* frameURL = url.spec().c_str();
313 NSString *address = [NSString stringWithUTF8String:frameURL]; 210 NSString *address = [NSString stringWithUTF8String:frameURL];
314 [shell_->editWnd() setStringValue:address]; 211 [shell_->editWnd() setStringValue:address];
315 } 212 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698