diff options
author | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-05 19:28:08 +0000 |
---|---|---|
committer | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-05 19:28:08 +0000 |
commit | 89ac46c97e6a3b2f2726bd11d52824d27ee26a24 (patch) | |
tree | c976f9689ff7fabd3c3e54e06ed051d1bd4544c7 /webkit/port/platform/chromium/PopupMenuChromium.cpp | |
parent | 9ac105a1023bc696e619e5714c524e1a3ffdc2ef (diff) | |
download | chromium_src-89ac46c97e6a3b2f2726bd11d52824d27ee26a24.zip chromium_src-89ac46c97e6a3b2f2726bd11d52824d27ee26a24.tar.gz chromium_src-89ac46c97e6a3b2f2726bd11d52824d27ee26a24.tar.bz2 |
This CL adds the autofill UI in forms.
When the user types text in a text field in a form, the renderer queries the browser for suggestion based on the entered text and displays the suggestions in a popup.
Listeners are set on the form text field in a similar fashion than for password save.
The popup showing the suggestion uses the same mechanism as the select popup. Note that a difference between the select and the autofill popup is that the autofill should not take focus, so the page still has focus and the user can still type in while it shows.
The creation of the render widget was modified for that purpose so we can specify the popup should not be focused when shown.
Review URL: http://codereview.chromium.org/8885
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4804 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port/platform/chromium/PopupMenuChromium.cpp')
-rw-r--r-- | webkit/port/platform/chromium/PopupMenuChromium.cpp | 133 |
1 files changed, 59 insertions, 74 deletions
diff --git a/webkit/port/platform/chromium/PopupMenuChromium.cpp b/webkit/port/platform/chromium/PopupMenuChromium.cpp index d30df68..ae9f164 100644 --- a/webkit/port/platform/chromium/PopupMenuChromium.cpp +++ b/webkit/port/platform/chromium/PopupMenuChromium.cpp @@ -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 kMaxHeight = 500; 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 @@ public: // 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 @@ static PlatformWheelEvent constructRelativeWheelEvent(const PlatformWheelEvent& // 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 @@ void PopupContainer::showPopup(FrameView* view) 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,6 +436,33 @@ void PopupContainer::paintBorder(GraphicsContext* gc, const IntRect& rect) 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 @@ bool PopupListBox::handleWheelEvent(const PlatformWheelEvent& event) 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 @@ PopupMenu::~PopupMenu() 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() |