diff options
author | paulg@google.com <paulg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-24 19:05:03 +0000 |
---|---|---|
committer | paulg@google.com <paulg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-24 19:05:03 +0000 |
commit | 6b01318fe807d9a6dca2a31ce7f0242ef3c93453 (patch) | |
tree | 21d1c01eca0241e4b8526744b2dacb094967f2ac /webkit/tools/test_shell | |
parent | c4848bad345fa487c5abc4645d1721d38aa28ac5 (diff) | |
download | chromium_src-6b01318fe807d9a6dca2a31ce7f0242ef3c93453.zip chromium_src-6b01318fe807d9a6dca2a31ce7f0242ef3c93453.tar.gz chromium_src-6b01318fe807d9a6dca2a31ce7f0242ef3c93453.tar.bz2 |
First stage of implementing HTML select popup menus for
the Mac test_shell. Once the changes to
WebKit/WebCore/platform/chromium/PopupMenuChromium* have
been upstreamed (then landed in our tree), we can enable
them in test_shell.
The WebKit part is contained in this bug:
https://bugs.webkit.org/show_bug.cgi?id=24692
BUG=5095 (http://crbug.com/5095)
Review URL: http://codereview.chromium.org/48149
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12382 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/tools/test_shell')
-rwxr-xr-x | webkit/tools/test_shell/mac/test_webview_delegate.mm | 145 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell_mac.mm | 3 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_webview_delegate.h | 5 | ||||
-rwxr-xr-x | webkit/tools/test_shell/test_webview_delegate_gtk.cc | 8 | ||||
-rwxr-xr-x | webkit/tools/test_shell/test_webview_delegate_win.cc | 8 |
5 files changed, 167 insertions, 2 deletions
diff --git a/webkit/tools/test_shell/mac/test_webview_delegate.mm b/webkit/tools/test_shell/mac/test_webview_delegate.mm index e80f75a..039e34f3 100755 --- a/webkit/tools/test_shell/mac/test_webview_delegate.mm +++ b/webkit/tools/test_shell/mac/test_webview_delegate.mm @@ -5,6 +5,7 @@ #include "webkit/tools/test_shell/test_webview_delegate.h" #import <Cocoa/Cocoa.h> +#include "base/sys_string_conversions.h" #include "base/string_util.h" #include "webkit/glue/webcursor.h" #include "webkit/glue/webview.h" @@ -12,6 +13,63 @@ #include "webkit/glue/plugins/webplugin_delegate_impl.h" #include "webkit/tools/test_shell/test_shell.h" +// MenuDelegate ---------------------------------------------------------------- +// A class for determining whether an item was selected from an HTML select +// control, or if the menu was dismissed without making a selection. If a menu +// item is selected, MenuDelegate is informed and sets a flag which can be +// queried after the menu has finished running. + +@interface MenuDelegate : NSObject { + @private + NSMenu* menu_; // Non-owning + BOOL menuItemWasChosen_; +} +- (id)initWithItems:(const std::vector<MenuItem>&)items forMenu:(NSMenu*)menu; +- (void)addItem:(const MenuItem&)item; +- (BOOL)menuItemWasChosen; +- (void)menuItemSelected:(id)sender; +@end + +@implementation MenuDelegate + +- (id)initWithItems:(const std::vector<MenuItem>&)items forMenu:(NSMenu*)menu { + if ((self = [super init])) { + menu_ = menu; + menuItemWasChosen_ = NO; + for (int i = 0; i < static_cast<int>(items.size()); ++i) + [self addItem:items[i]]; + } + return self; +} + +- (void)addItem:(const MenuItem&)item { + if (item.type == MenuItem::SEPARATOR) { + [menu_ addItem:[NSMenuItem separatorItem]]; + return; + } + + NSString* title = base::SysUTF16ToNSString(item.label); + NSMenuItem* menu_item = [menu_ addItemWithTitle:title + action:@selector(menuItemSelected:) + keyEquivalent:@""]; + [menu_item setEnabled:(item.enabled && item.type != MenuItem::GROUP)]; + [menu_item setTarget:self]; +} + +// Reflects the result of the user's interaction with the popup menu. If NO, the +// menu was dismissed without the user choosing an item, which can happen if the +// user clicked outside the menu region or hit the escape key. If YES, the user +// selected an item from the menu. +- (BOOL)menuItemWasChosen { + return menuItemWasChosen_; +} + +- (void)menuItemSelected:(id)sender { + menuItemWasChosen_ = YES; +} + +@end // MenuDelegate + // WebViewDelegate ----------------------------------------------------------- @@ -60,6 +118,93 @@ void TestWebViewDelegate::Show(WebWidget* webview, WindowOpenDisposition disposition) { } +// Display a HTML select menu. +void TestWebViewDelegate::ShowWithItems( + WebWidget* webview, + const gfx::Rect& bounds, + int item_height, + int selected_index, + const std::vector<MenuItem>& items) { + // Populate the menu. + NSMenu* menu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; + [menu setAutoenablesItems:NO]; + MenuDelegate* menu_delegate = + [[[MenuDelegate alloc] initWithItems:items forMenu:menu] autorelease]; + + // Set up the button cell, converting to NSView coordinates. The menu is + // positioned such that the currently selected menu item appears over the + // popup button, which is the expected Mac popup menu behavior. + NSPopUpButtonCell* button = [[NSPopUpButtonCell alloc] initTextCell:@"" + pullsDown:NO]; + [button autorelease]; + [button setMenu:menu]; + [button selectItemAtIndex:selected_index]; + NSView* web_view = shell_->webViewWnd(); + NSRect view_rect = [web_view bounds]; + int y_offset = bounds.y() + bounds.height(); + NSRect position = NSMakeRect(bounds.x(), view_rect.size.height - y_offset, + bounds.width(), bounds.height()); + + // Display the menu, and set a flag to determine if something was chosen. If + // nothing was chosen (i.e., the user dismissed the popup by the "ESC" key or + // clicking outside popup's region), send a dismiss message to WebKit. + [button performClickWithFrame:position inView:shell_->webViewWnd()]; + + // Get the selected item and forward to WebKit. WebKit expects an input event + // (mouse down, keyboard activity) for this, so we calculate the proper + // position based on the selected index and provided bounds. + WebWidgetHost* popup = shell_->popupHost(); + NSEvent* event = nil; + double event_time = (double)(AbsoluteToDuration(UpTime())) / 1000.0; + int window_num = [shell_->mainWnd() windowNumber]; + + if ([menu_delegate menuItemWasChosen]) { + // Construct a mouse up event to simulate the selection of an appropriate + // menu item. + NSPoint click_pos; + click_pos.x = position.size.width / 2; + + // This is going to be hard to calculate since the button is painted by + // WebKit, the menu by Cocoa, and we have to translate the selected_item + // index to a coordinate that WebKit's PopupMenu expects which uses a + // different font *and* expects to draw the menu below the button like we do + // on Windows. + // The WebKit popup menu thinks it will draw just below the button, so + // create the click at the offset based on the selected item's index and + // account for the different coordinate system used by NSView. + int item_offset = [button indexOfSelectedItem] * item_height + + item_height / 2; + click_pos.y = view_rect.size.height - item_offset; + event = [NSEvent mouseEventWithType:NSLeftMouseUp + location:click_pos + modifierFlags:0 + timestamp:event_time + windowNumber:window_num + context:nil + eventNumber:0 + clickCount:1 + pressure:1.0]; + popup->MouseEvent(event); + } else { + // Fake an ESC key event (keyCode = 0x1B, from webinputevent_mac.mm) and + // forward that to WebKit. + NSPoint key_pos; + key_pos.x = 0; + key_pos.y = 0; + event = [NSEvent keyEventWithType:NSKeyUp + location:key_pos + modifierFlags:0 + timestamp:event_time + windowNumber:window_num + context:nil + characters:@"" + charactersIgnoringModifiers:@"" + isARepeat:NO + keyCode:0x1B]; + popup->KeyEvent(event); + } +} + void TestWebViewDelegate::CloseWidgetSoon(WebWidget* webwidget) { if (webwidget == shell_->webView()) { NSWindow *win = shell_->mainWnd(); diff --git a/webkit/tools/test_shell/test_shell_mac.mm b/webkit/tools/test_shell/test_shell_mac.mm index a3cd0f1..5df878e 100644 --- a/webkit/tools/test_shell/test_shell_mac.mm +++ b/webkit/tools/test_shell/test_shell_mac.mm @@ -460,8 +460,7 @@ void TestShell::DestroyWindow(gfx::NativeWindow windowHandle) { WebWidget* TestShell::CreatePopupWidget(WebView* webview) { DCHECK(!m_popupHost); - m_popupHost = WebWidgetHost::Create(NULL, delegate_.get()); - // ShowWindow(popupWnd(), SW_SHOW); + m_popupHost = WebWidgetHost::Create(webViewWnd(), delegate_.get()); return m_popupHost->webwidget(); } diff --git a/webkit/tools/test_shell/test_webview_delegate.h b/webkit/tools/test_shell/test_webview_delegate.h index a0dcbf9..c24eccc 100644 --- a/webkit/tools/test_shell/test_webview_delegate.h +++ b/webkit/tools/test_shell/test_webview_delegate.h @@ -214,6 +214,11 @@ class TestWebViewDelegate : public base::RefCounted<TestWebViewDelegate>, virtual void DidScrollRect(WebWidget* webwidget, int dx, int dy, const gfx::Rect& clip_rect); virtual void Show(WebWidget* webview, WindowOpenDisposition disposition); + virtual void ShowWithItems(WebWidget* webwidget, + const gfx::Rect& bounds, + int item_height, + int selected_index, + const std::vector<MenuItem>& items); virtual void CloseWidgetSoon(WebWidget* webwidget); virtual void Focus(WebWidget* webwidget); virtual void Blur(WebWidget* webwidget); diff --git a/webkit/tools/test_shell/test_webview_delegate_gtk.cc b/webkit/tools/test_shell/test_webview_delegate_gtk.cc index 8c9399c..620de76 100755 --- a/webkit/tools/test_shell/test_webview_delegate_gtk.cc +++ b/webkit/tools/test_shell/test_webview_delegate_gtk.cc @@ -113,6 +113,14 @@ void TestWebViewDelegate::Show(WebWidget* webwidget, gtk_widget_show_all(window); } +void TestWebViewDelegate::ShowWithItems(WebWidget* webwidget, + const gfx::Rect& bounds, + int item_height, + int selected_index, + const std::vector<MenuItem>& items) { + NOTIMPLEMENTED(); +} + void TestWebViewDelegate::CloseWidgetSoon(WebWidget* webwidget) { if (webwidget == shell_->webView()) { MessageLoop::current()->PostTask(FROM_HERE, NewRunnableFunction( diff --git a/webkit/tools/test_shell/test_webview_delegate_win.cc b/webkit/tools/test_shell/test_webview_delegate_win.cc index 6a10617..ff4a7e2 100755 --- a/webkit/tools/test_shell/test_webview_delegate_win.cc +++ b/webkit/tools/test_shell/test_webview_delegate_win.cc @@ -78,6 +78,14 @@ void TestWebViewDelegate::Show(WebWidget* webwidget, WindowOpenDisposition) { } } +void TestWebViewDelegate::ShowWithItems(WebWidget* webwidget, + const gfx::Rect& bounds, + int item_height, + int selected_index, + const std::vector<MenuItem>& items) { + NOTIMPLEMENTED(); +} + void TestWebViewDelegate::CloseWidgetSoon(WebWidget* webwidget) { if (webwidget == shell_->webView()) { PostMessage(shell_->mainWnd(), WM_CLOSE, 0, 0); |