summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/haiku/PopupMenuHaiku.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-06 11:45:16 +0100
committerSteve Block <steveblock@google.com>2011-05-12 13:44:10 +0100
commitcad810f21b803229eb11403f9209855525a25d57 (patch)
tree29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /Source/WebCore/platform/haiku/PopupMenuHaiku.cpp
parent121b0cf4517156d0ac5111caf9830c51b69bae8f (diff)
downloadexternal_webkit-cad810f21b803229eb11403f9209855525a25d57.zip
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'Source/WebCore/platform/haiku/PopupMenuHaiku.cpp')
-rw-r--r--Source/WebCore/platform/haiku/PopupMenuHaiku.cpp192
1 files changed, 192 insertions, 0 deletions
diff --git a/Source/WebCore/platform/haiku/PopupMenuHaiku.cpp b/Source/WebCore/platform/haiku/PopupMenuHaiku.cpp
new file mode 100644
index 0000000..e3edb83
--- /dev/null
+++ b/Source/WebCore/platform/haiku/PopupMenuHaiku.cpp
@@ -0,0 +1,192 @@
+/*
+ * This file is part of the popup menu implementation for <select> elements in WebCore.
+ *
+ * Copyright (C) 2010 Stephan Aßmus <superstippi@gmx.de>
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+#include "PopupMenuHaiku.h"
+
+#include "FrameView.h"
+
+#include "NotImplemented.h"
+#include <Application.h>
+#include <Handler.h>
+#include <MenuItem.h>
+#include <Message.h>
+#include <PopUpMenu.h>
+#include <String.h>
+#include <Window.h>
+#include <support/Autolock.h>
+#include <support/Locker.h>
+
+namespace WebCore {
+
+static const uint32 kPopupResult = 'pmrs';
+static const uint32 kPopupHidden = 'pmhd';
+
+// This BHandler is added to the application (main) thread, so that we
+// invoke methods on the PopupMenuClient within the main thread.
+class PopupMenuHandler : public BHandler {
+public:
+ PopupMenuHandler(PopupMenuClient* popupClient)
+ : m_popupClient(popupClient)
+ {
+ }
+
+ virtual void MessageReceived(BMessage* message)
+ {
+ switch (message->what) {
+ case kPopupResult: {
+ int32 index = 0;
+ message->FindInt32("index", &index);
+ m_popupClient->valueChanged(index);
+ break;
+ }
+ case kPopupHidden:
+ m_popupClient->popupDidHide();
+ break;
+
+ default:
+ BHandler::MessageReceived(message);
+ }
+ }
+
+private:
+ PopupMenuClient* m_popupClient;
+};
+
+class HaikuPopup : public BPopUpMenu {
+public:
+ HaikuPopup(PopupMenuClient* popupClient)
+ : BPopUpMenu("WebCore Popup", true, false)
+ , m_popupClient(popupClient)
+ , m_Handler(popupClient)
+ {
+ if (be_app->Lock()) {
+ be_app->AddHandler(&m_Handler);
+ be_app->Unlock();
+ }
+ SetAsyncAutoDestruct(false);
+ }
+
+ virtual ~HaikuPopup()
+ {
+ if (be_app->Lock()) {
+ be_app->RemoveHandler(&m_Handler);
+ be_app->Unlock();
+ }
+ }
+
+ void show(const IntRect& rect, FrameView* view, int index)
+ {
+ // Clean out the menu first
+ for (int32 i = CountItems() - 1; i >= 0; i--)
+ delete RemoveItem(i);
+
+ // Popuplate the menu from the client
+ int itemCount = m_popupClient->listSize();
+ for (int i = 0; i < itemCount; i++) {
+ if (m_popupClient->itemIsSeparator(i))
+ AddSeparatorItem();
+ else {
+ // NOTE: WebCore distinguishes between "Group" and "Label"
+ // here, but both types of item (radio or check mark) currently
+ // look the same on Haiku.
+ BString label(m_popupClient->itemText(i));
+ BMessage* message = new BMessage(kPopupResult);
+ message->AddInt32("index", i);
+ BMenuItem* item = new BMenuItem(label.String(), message);
+ AddItem(item);
+ item->SetTarget(BMessenger(&m_Handler));
+ item->SetEnabled(m_popupClient->itemIsEnabled(i));
+ item->SetMarked(i == index);
+ }
+ }
+
+ // We need to force a layout now, or the item frames will not be
+ // computed yet, so we cannot move the current item under the mouse.
+ DoLayout();
+
+ // Account for frame of menu field
+ BRect screenRect(view->contentsToScreen(rect));
+ screenRect.OffsetBy(2, 2);
+ // Move currently selected item under the mouse.
+ if (BMenuItem* item = ItemAt(index))
+ screenRect.OffsetBy(0, -item->Frame().top);
+
+ BRect openRect = Bounds().OffsetToSelf(screenRect.LeftTop());
+
+ Go(screenRect.LeftTop(), true, true, openRect, true);
+ }
+
+ void hide()
+ {
+ if (!IsHidden())
+ Hide();
+ }
+
+private:
+ virtual void Hide()
+ {
+ BPopUpMenu::Hide();
+ be_app->PostMessage(kPopupHidden, &m_Handler);
+ }
+
+ PopupMenuClient* m_popupClient;
+ PopupMenuHandler m_Handler;
+};
+
+PopupMenuHaiku::PopupMenuHaiku(PopupMenuClient* client)
+ : m_popupClient(client)
+ , m_menu(new HaikuPopup(client))
+{
+ // We don't need additional references to the client, since we completely
+ // control any sub-objects we create that need it as well.
+}
+
+PopupMenuHaiku::~PopupMenuHaiku()
+{
+ delete m_menu;
+}
+
+void PopupMenuHaiku::disconnectClient()
+{
+ m_popupClient = 0;
+}
+
+void PopupMenuHaiku::show(const IntRect& rect, FrameView* view, int index)
+{
+ // The menu will update itself from the PopupMenuClient before showing.
+ m_menu->show(rect, view, index);
+}
+
+void PopupMenuHaiku::hide()
+{
+ m_menu->hide();
+}
+
+void PopupMenuHaiku::updateFromElement()
+{
+ client()->setTextFromItem(m_popupClient->selectedIndex());
+}
+
+} // namespace WebCore
+