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