| Index: webkit/port/platform/chromium/PopupMenuChromium.cpp
|
| ===================================================================
|
| --- webkit/port/platform/chromium/PopupMenuChromium.cpp (revision 4621)
|
| +++ webkit/port/platform/chromium/PopupMenuChromium.cpp (working copy)
|
| @@ -36,9 +36,9 @@
|
| #include "ChromeClientChromium.h"
|
| #include "Document.h"
|
| #include "Font.h"
|
| -#include "Frame.h"
|
| #include "FrameView.h"
|
| #include "FontSelector.h"
|
| +#include "Frame.h"
|
| #include "FramelessScrollView.h"
|
| #include "FramelessScrollViewClient.h"
|
| #include "GraphicsContext.h"
|
| @@ -57,6 +57,8 @@
|
| #include "Widget.h"
|
| #pragma warning(pop)
|
|
|
| +#include "webkit/port/platform/chromium/PopupMenuChromium.h"
|
| +
|
| using namespace WTF;
|
| using namespace Unicode;
|
|
|
| @@ -72,51 +74,6 @@
|
| static const int kBorderSize = 1;
|
| static const TimeStamp kTypeAheadTimeoutMs = 1000;
|
|
|
| -class PopupListBox;
|
| -
|
| -// TODO(darin): Our FramelessScrollView classes need to implement HostWindow!
|
| -
|
| -// This class holds a PopupListBox. Its sole purpose is to be able to draw
|
| -// a border around its child. All its paint/event handling is just forwarded
|
| -// to the child listBox (with the appropriate transforms).
|
| -class PopupContainer : public FramelessScrollView, public RefCounted<PopupContainer> {
|
| -public:
|
| - static PassRefPtr<PopupContainer> create(PopupMenuClient* client);
|
| -
|
| - // FramelessScrollView
|
| - virtual void paint(GraphicsContext* gc, const IntRect& rect);
|
| - virtual void hide();
|
| - virtual bool handleMouseDownEvent(const PlatformMouseEvent& event);
|
| - virtual bool handleMouseMoveEvent(const PlatformMouseEvent& event);
|
| - virtual bool handleMouseReleaseEvent(const PlatformMouseEvent& event);
|
| - virtual bool handleWheelEvent(const PlatformWheelEvent& event);
|
| - virtual bool handleKeyEvent(const PlatformKeyboardEvent& event);
|
| -
|
| - // PopupContainer methods
|
| -
|
| - // Show the popup
|
| - void showPopup(FrameView* view);
|
| -
|
| - // Hide the popup. Do not call this directly: use client->hidePopup().
|
| - void hidePopup();
|
| -
|
| - // Compute size of widget and children.
|
| - void layout();
|
| -
|
| - PopupListBox* listBox() const { return m_listBox.get(); }
|
| -
|
| -private:
|
| - friend class RefCounted<PopupContainer>;
|
| -
|
| - PopupContainer(PopupMenuClient* client);
|
| - ~PopupContainer();
|
| -
|
| - // Paint the border.
|
| - void paintBorder(GraphicsContext* gc, const IntRect& rect);
|
| -
|
| - RefPtr<PopupListBox> m_listBox;
|
| -};
|
| -
|
| // This class uses WebCore code to paint and handle events for a drop-down list
|
| // box ("combobox" on Windows).
|
| class PopupListBox : public FramelessScrollView, public RefCounted<PopupListBox> {
|
| @@ -170,6 +127,9 @@
|
| // Compute size of widget and children.
|
| void layout();
|
|
|
| + // Returns whether the popup wants to process events for the passed key.
|
| + bool isInterestedInEventForKey(int key_code);
|
| +
|
| private:
|
| friend class PopupContainer;
|
| friend class RefCounted<PopupListBox>;
|
| @@ -327,13 +287,15 @@
|
| // PopupContainer implementation
|
|
|
| // static
|
| -PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client)
|
| +PassRefPtr<PopupContainer> PopupContainer::create(PopupMenuClient* client,
|
| + bool focusOnShow)
|
| {
|
| - return adoptRef(new PopupContainer(client));
|
| + return adoptRef(new PopupContainer(client, focusOnShow));
|
| }
|
|
|
| -PopupContainer::PopupContainer(PopupMenuClient* client)
|
| - : m_listBox(new PopupListBox(client))
|
| +PopupContainer::PopupContainer(PopupMenuClient* client, bool focusOnShow)
|
| + : m_listBox(new PopupListBox(client)),
|
| + m_focusOnShow(focusOnShow)
|
| {
|
| // FrameViews are created with a refcount of 1 so it needs releasing after we
|
| // assign it to a RefPtr.
|
| @@ -367,7 +329,7 @@
|
| if (widgetRect.bottom() > static_cast<int>(screen.bottom()))
|
| widgetRect.move(0, -(widgetRect.height() + selectHeight));
|
|
|
| - chromeClient->popupOpened(this, widgetRect);
|
| + chromeClient->popupOpened(this, widgetRect, m_focusOnShow);
|
| }
|
|
|
| // Must get called after we have a client and containingWindow.
|
| @@ -474,7 +436,34 @@
|
| gc->drawRect(IntRect(tx + width() - kBorderSize, ty, kBorderSize, height()));
|
| }
|
|
|
| +bool PopupContainer::isInterestedInEventForKey(int key_code) {
|
| + return m_listBox->isInterestedInEventForKey(key_code);
|
| +}
|
|
|
| +void PopupContainer::show(const IntRect& r, FrameView* v, int index) {
|
| + // The rect is the size of the select box. It's usually larger than we need.
|
| + // subtract border size so that usually the container will be displayed
|
| + // exactly the same width as the select box.
|
| + listBox()->setBaseWidth(max(r.width() - kBorderSize * 2, 0));
|
| +
|
| + listBox()->updateFromElement();
|
| +
|
| + // We set the selected item in updateFromElement(), and disregard the
|
| + // index passed into this function (same as Webkit's PopupMenuWin.cpp)
|
| + // TODO(ericroman): make sure this is correct, and add an assertion.
|
| + // DCHECK(popupWindow(popup)->listBox()->selectedIndex() == index);
|
| +
|
| + // Convert point to main window coords.
|
| + IntPoint location = v->contentsToWindow(r.location());
|
| +
|
| + // Move it below the select widget.
|
| + location.move(0, r.height());
|
| +
|
| + IntRect popupRect(location, r.size());
|
| + setFrameRect(popupRect);
|
| + showPopup(v);
|
| +}
|
| +
|
| ///////////////////////////////////////////////////////////////////////////////
|
| // PopupListBox implementation
|
|
|
| @@ -548,6 +537,23 @@
|
| return true;
|
| }
|
|
|
| +// Should be kept in sync with handleKeyEvent().
|
| +bool PopupListBox::isInterestedInEventForKey(int key_code) {
|
| + switch (key_code) {
|
| + case VKEY_ESCAPE:
|
| + case VKEY_RETURN:
|
| + case VKEY_UP:
|
| + case VKEY_DOWN:
|
| + case VKEY_PRIOR:
|
| + case VKEY_NEXT:
|
| + case VKEY_HOME:
|
| + case VKEY_END:
|
| + return true;
|
| + default:
|
| + return false;
|
| + }
|
| +}
|
| +
|
| bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event)
|
| {
|
| if (event.type() == PlatformKeyboardEvent::KeyUp)
|
| @@ -1036,29 +1042,8 @@
|
|
|
| void PopupMenu::show(const IntRect& r, FrameView* v, int index)
|
| {
|
| - p.m_popup = PopupContainer::create(client());
|
| -
|
| - // The rect is the size of the select box. It's usually larger than we need.
|
| - // subtract border size so that usually the container will be displayed
|
| - // exactly the same width as the select box.
|
| - p.m_popup->listBox()->setBaseWidth(max(r.width() - kBorderSize * 2, 0));
|
| -
|
| - updateFromElement();
|
| -
|
| - // We set the selected item in updateFromElement(), and disregard the
|
| - // index passed into this function (same as Webkit's PopupMenuWin.cpp)
|
| - // TODO(ericroman): make sure this is correct, and add an assertion.
|
| - // DCHECK(popupWindow(m_popup)->listBox()->selectedIndex() == index);
|
| -
|
| - // Convert point to main window coords.
|
| - IntPoint location = v->contentsToWindow(r.location());
|
| -
|
| - // Move it below the select widget.
|
| - location.move(0, r.height());
|
| -
|
| - IntRect popupRect(location, r.size());
|
| - p.m_popup->setFrameRect(popupRect);
|
| - p.m_popup->showPopup(v);
|
| + p.m_popup = PopupContainer::create(client(), true);
|
| + p.m_popup->show(r, v, index);
|
| }
|
|
|
| void PopupMenu::hide()
|
|
|