Chromium Code Reviews| 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 |