15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (c) 2011, Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
3093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef PopupListBox_h
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define PopupListBox_h
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "core/dom/Element.h"
357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "platform/scroll/ScrollTypes.h"
367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "platform/scroll/ScrollView.h"
371e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/text/TextDirection.h"
3893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/text/WTFString.h"
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
40c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
41e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Font;
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class GraphicsContext;
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class IntRect;
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class PlatformKeyboardEvent;
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class PlatformMouseEvent;
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class PlatformGestureEvent;
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class PlatformTouchEvent;
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class PlatformWheelEvent;
507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciclass PopupContainer;
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class PopupMenuClient;
5209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)typedef unsigned long long TimeStamp;
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class PopupContent {
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual void layout() = 0;
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual void setMaxHeight(int) = 0;
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual void setMaxWidthAndLayout(int) = 0;
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual int popupContentHeight() const = 0;
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual ~PopupContent() { };
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// A container for the data for each menu item (e.g. represented by <option>
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// or <optgroup> in a <select> widget) and is used by PopupListBox.
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct PopupItem {
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    enum Type {
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        TypeOption,
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        TypeGroup,
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        TypeSeparator
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    PopupItem(const String& label, Type type)
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : label(label)
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , type(type)
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , yOffset(0)
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String label;
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Type type;
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int yOffset; // y offset of this item, relative to the top of the popup.
81e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    TextDirection textDirection;
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool hasTextDirectionOverride;
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool enabled;
84e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    bool displayNone;
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci// This class manages the scrollable content inside a <select> popup.
887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciclass PopupListBox FINAL : public Widget, public ScrollableArea, public PopupContent {
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static PassRefPtr<PopupListBox> create(PopupMenuClient* client, bool deviceSupportsTouch, PopupContainer* container)
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return adoptRef(new PopupListBox(client, deviceSupportsTouch, container));
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Widget
967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual void invalidateRect(const IntRect&) OVERRIDE;
97e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    virtual void paint(GraphicsContext*, const IntRect&) OVERRIDE;
98e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    virtual HostWindow* hostWindow() const OVERRIDE;
997242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual void setFrameRect(const IntRect&) OVERRIDE;
1007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual IntPoint convertChildToSelf(const Widget* child, const IntPoint&) const OVERRIDE;
1017242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual IntPoint convertSelfToChild(const Widget* child, const IntPoint&) const OVERRIDE;
1027242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1037242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // ScrollableArea
1047242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) OVERRIDE;
1057242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual bool isActive() const OVERRIDE;
1067242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual bool scrollbarsCanBeActive() const OVERRIDE;
1077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual IntRect scrollableAreaBoundingBox() const OVERRIDE;
10851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    virtual bool shouldPlaceVerticalScrollbarOnLeft() const OVERRIDE;
1097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual int scrollSize(ScrollbarOrientation) const OVERRIDE;
1107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual void setScrollOffset(const IntPoint&) OVERRIDE;
1117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual bool isScrollCornerVisible() const OVERRIDE { return false; }
1127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual bool userInputScrollable(ScrollbarOrientation orientation) const OVERRIDE { return orientation == VerticalScrollbar; }
1137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual Scrollbar* verticalScrollbar() const OVERRIDE { return m_verticalScrollbar.get(); }
1147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual IntRect visibleContentRect(IncludeScrollbarsInRect = ExcludeScrollbars) const OVERRIDE;
1157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual IntSize contentsSize() const OVERRIDE { return m_contentsSize; }
1167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual IntPoint scrollPosition() const OVERRIDE { return visibleContentRect().location(); }
1177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual IntPoint maximumScrollPosition() const OVERRIDE; // The maximum position we can be scrolled to.
1187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual IntPoint minimumScrollPosition() const OVERRIDE; // The minimum position we can be scrolled to.
1197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual IntRect scrollCornerRect() const OVERRIDE { return IntRect(); }
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // PopupListBox methods
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1237242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool handleMouseDownEvent(const PlatformMouseEvent&);
1247242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool handleMouseMoveEvent(const PlatformMouseEvent&);
1257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool handleMouseReleaseEvent(const PlatformMouseEvent&);
1267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool handleWheelEvent(const PlatformWheelEvent&);
1277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool handleKeyEvent(const PlatformKeyboardEvent&);
1287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool handleTouchEvent(const PlatformTouchEvent&);
1297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    bool handleGestureEvent(const PlatformGestureEvent&);
1307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
13106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // Closes the popup
13206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    void abandon();
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Updates our internal list to match the client.
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void updateFromElement();
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Frees any allocated resources used in a particular popup session.
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void clear();
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Sets the index of the option that is displayed in the <select> widget in the page
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setOriginalIndex(int);
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
14393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Gets the index of the item that the user is currently moused over or has
14493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // selected with the keyboard. This is not the same as the original index,
14593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // since the user has not yet accepted this input.
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int selectedIndex() const { return m_selectedIndex; }
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Moves selection down/up the given number of items, scrolling if necessary.
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Positive is down. The resulting index will be clamped to the range
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // [0, numItems), and non-option items will be skipped.
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void adjustSelectedIndex(int delta);
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Returns the number of items in the list.
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int numItems() const { return static_cast<int>(m_items.size()); }
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setBaseWidth(int width) { m_baseWidth = std::min(m_maxWindowWidth, width); }
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Computes the size of widget and children.
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual void layout() OVERRIDE;
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Returns whether the popup wants to process events for the passed key.
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isInterestedInEventForKey(int keyCode);
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Gets the height of a row.
1657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    int getRowHeight(int index) const;
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
167e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    int getRowBaseWidth(int index);
168e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual void setMaxHeight(int maxHeight) OVERRIDE { m_maxHeight = maxHeight; }
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void setMaxWidth(int maxWidth) { m_maxWindowWidth = maxWidth; }
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual void setMaxWidthAndLayout(int) OVERRIDE;
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void disconnectClient() { m_popupClient = 0; }
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const Vector<PopupItem*>& items() const { return m_items; }
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    virtual int popupContentHeight() const OVERRIDE;
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    static const int defaultMaxHeight;
18293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
1837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciprotected:
1847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual void invalidateScrollCornerRect(const IntRect&) OVERRIDE { }
1857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    friend class PopupContainer;
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    friend class RefCounted<PopupListBox>;
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    PopupListBox(PopupMenuClient*, bool deviceSupportsTouch, PopupContainer*);
1917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    virtual ~PopupListBox();
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
19306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    // Hides the popup. Other classes should not call this. Use abandon instead.
19406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    void hidePopup();
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Returns true if the selection can be changed to index.
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Disabled items, or labels cannot be selected.
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isSelectableItem(int index);
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Select an index in the list, scrolling if necessary.
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void selectIndex(int index);
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
20393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // Accepts the selected index as the value to be displayed in the <select>
20493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // widget on the web page, and closes the popup. Returns true if index is
20593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // accepted.
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool acceptIndex(int index);
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Clears the selection (so no row appears selected).
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void clearSelection();
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Scrolls to reveal the given index.
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void scrollToRevealRow(int index);
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void scrollToRevealSelection() { scrollToRevealRow(m_selectedIndex); }
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Invalidates the row at the given index.
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void invalidateRow(int index);
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Get the bounds of a row.
219e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    IntRect getRowBounds(int index);
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Converts a point to an index of the row the point is over
222e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    int pointToRowIndex(const IntPoint&);
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Paint an individual row
225e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    void paintRow(GraphicsContext*, const IntRect&, int rowIndex);
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Test if the given point is within the bounds of the popup window.
228e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    bool isPointInBounds(const IntPoint&);
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Called when the user presses a text key. Does a prefix-search of the items.
231e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    void typeAheadFind(const PlatformKeyboardEvent&);
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Returns the font to use for the given row
2347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Font getRowFont(int index) const;
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Moves the selection down/up one item, taking care of looping back to the
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // first/last element if m_loopSelectionNavigation is true.
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void selectPreviousRow();
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void selectNextRow();
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    int scrollX() const { return scrollPosition().x(); }
2427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    int scrollY() const { return scrollPosition().y(); }
243e407fbf339543f622b6e9e8e40881204bde53b6bBen Murdoch    void updateScrollbars(IntPoint desiredOffset);
2447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void setHasVerticalScrollbar(bool);
2457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    Scrollbar* scrollbarAtWindowPoint(const IntPoint& windowPoint);
2467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    IntRect contentsToWindow(const IntRect&) const;
2477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void setContentsSize(const IntSize&);
2487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void adjustScrollbarExistence();
2497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void updateScrollbarGeometry();
2507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    IntRect windowClipRect() const;
2517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
25209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // If the device is a touch screen we increase the height of menu items
25309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // to make it easier to unambiguously touch them.
25409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    bool m_deviceSupportsTouch;
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
25693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // This is the index of the item marked as "selected" - i.e. displayed in
25793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // the widget on the page.
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_originalIndex;
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
26093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // This is the index of the item that the user is hovered over or has
26193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // selected using the keyboard in the list. They have not confirmed this
26293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // selection by clicking or pressing enter yet however.
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_selectedIndex;
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If >= 0, this is the index we should accept if the popup is "abandoned".
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // This is used for keyboard navigation, where we want the
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // selection to change immediately, and is only used if the settings
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // acceptOnAbandon field is true.
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_acceptedIndexOnAbandon;
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
27193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // This is the number of rows visible in the popup. The maximum number
27293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // visible at a time is defined as being kMaxVisibleRows. For a scrolled
27393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    // popup, this can be thought of as the page size in data units.
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_visibleRows;
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Our suggested width, not including scrollbar.
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_baseWidth;
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The maximum height we can be without being off-screen.
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_maxHeight;
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // A list of the options contained within the <select>
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Vector<PopupItem*> m_items;
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The <select> PopupMenuClient that opened us.
286e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    PopupMenuClient* m_popupClient;
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The scrollbar which has mouse capture. Mouse events go straight to this
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // if not null.
290e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    RefPtr<Scrollbar> m_capturingScrollbar;
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The last scrollbar that the mouse was over. Used for mouseover highlights.
293e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The string the user has typed so far into the popup. Used for typeAheadFind.
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    String m_typedString;
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The char the user has hit repeatedly. Used for typeAheadFind.
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    UChar m_repeatingChar;
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The last time the user hit a key. Used for typeAheadFind.
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    TimeStamp m_lastCharTime;
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If width exeeds screen width, we have to clip it.
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_maxWindowWidth;
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // To forward last mouse release event.
308e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    RefPtrWillBePersistent<Element> m_focusedElement;
3097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
3107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    PopupContainer* m_container;
3117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
3127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    RefPtr<Scrollbar> m_verticalScrollbar;
3137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    IntSize m_contentsSize;
3147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    IntPoint m_scrollOffset;
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
31709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} // namespace blink
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
320