OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |