diff options
author | Steve Block <steveblock@google.com> | 2011-05-06 11:45:16 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2011-05-12 13:44:10 +0100 |
commit | cad810f21b803229eb11403f9209855525a25d57 (patch) | |
tree | 29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /Source/WebCore/platform/haiku/PopupMenuHaiku.cpp | |
parent | 121b0cf4517156d0ac5111caf9830c51b69bae8f (diff) | |
download | external_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.cpp | 192 |
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 + |