summaryrefslogtreecommitdiffstats
path: root/webkit/tools/test_shell
diff options
context:
space:
mode:
authorpaulg@google.com <paulg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-24 19:05:03 +0000
committerpaulg@google.com <paulg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-24 19:05:03 +0000
commit6b01318fe807d9a6dca2a31ce7f0242ef3c93453 (patch)
tree21d1c01eca0241e4b8526744b2dacb094967f2ac /webkit/tools/test_shell
parentc4848bad345fa487c5abc4645d1721d38aa28ac5 (diff)
downloadchromium_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-xwebkit/tools/test_shell/mac/test_webview_delegate.mm145
-rw-r--r--webkit/tools/test_shell/test_shell_mac.mm3
-rw-r--r--webkit/tools/test_shell/test_webview_delegate.h5
-rwxr-xr-xwebkit/tools/test_shell/test_webview_delegate_gtk.cc8
-rwxr-xr-xwebkit/tools/test_shell/test_webview_delegate_win.cc8
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);