1/*
2 * This file is part of the select element renderer in WebCore.
3 *
4 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
5 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB.  If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#ifndef RenderMenuList_h
25#define RenderMenuList_h
26
27#include "PopupMenu.h"
28#include "PopupMenuClient.h"
29#include "RenderFlexibleBox.h"
30
31#if PLATFORM(MAC)
32#define POPUP_MENU_PULLS_DOWN 0
33#else
34#define POPUP_MENU_PULLS_DOWN 1
35#endif
36
37namespace WebCore {
38
39class RenderText;
40
41#if ENABLE(NO_LISTBOX_RENDERING)
42class RenderMenuList : public RenderFlexibleBox, private ListPopupMenuClient {
43#else
44class RenderMenuList : public RenderFlexibleBox, private PopupMenuClient {
45#endif
46
47public:
48    RenderMenuList(Element*);
49    virtual ~RenderMenuList();
50
51public:
52    bool popupIsVisible() const { return m_popupIsVisible; }
53    void showPopup();
54    void hidePopup();
55
56    void setOptionsChanged(bool changed) { m_optionsChanged = changed; }
57
58    void didSetSelectedIndex();
59
60    String text() const;
61
62private:
63    virtual bool isMenuList() const { return true; }
64
65    virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
66    virtual void removeChild(RenderObject*);
67    virtual bool createsAnonymousWrapper() const { return true; }
68    virtual bool canHaveChildren() const { return false; }
69
70    virtual void updateFromElement();
71
72    virtual bool hasControlClip() const { return true; }
73    virtual IntRect controlClipRect(int tx, int ty) const;
74
75    virtual const char* renderName() const { return "RenderMenuList"; }
76
77    virtual void computePreferredLogicalWidths();
78
79    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
80
81    virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
82
83    // PopupMenuClient methods
84    virtual String itemText(unsigned listIndex) const;
85    virtual String itemLabel(unsigned listIndex) const;
86    virtual String itemIcon(unsigned listIndex) const;
87    virtual String itemToolTip(unsigned listIndex) const;
88    virtual String itemAccessibilityText(unsigned listIndex) const;
89    virtual bool itemIsEnabled(unsigned listIndex) const;
90    virtual PopupMenuStyle itemStyle(unsigned listIndex) const;
91    virtual PopupMenuStyle menuStyle() const;
92    virtual int clientInsetLeft() const;
93    virtual int clientInsetRight() const;
94    virtual int clientPaddingLeft() const;
95    virtual int clientPaddingRight() const;
96    virtual int listSize() const;
97    virtual int selectedIndex() const;
98    virtual void popupDidHide();
99    virtual bool itemIsSeparator(unsigned listIndex) const;
100    virtual bool itemIsLabel(unsigned listIndex) const;
101    virtual bool itemIsSelected(unsigned listIndex) const;
102    virtual void setTextFromItem(unsigned listIndex);
103    virtual bool valueShouldChangeOnHotTrack() const { return true; }
104    virtual bool shouldPopOver() const { return !POPUP_MENU_PULLS_DOWN; }
105    virtual void valueChanged(unsigned listIndex, bool fireOnChange = true);
106    virtual void selectionChanged(unsigned, bool) {}
107    virtual void selectionCleared() {}
108    virtual FontSelector* fontSelector() const;
109    virtual HostWindow* hostWindow() const;
110    virtual PassRefPtr<Scrollbar> createScrollbar(ScrollableArea*, ScrollbarOrientation, ScrollbarControlSize);
111
112#if ENABLE(NO_LISTBOX_RENDERING)
113    virtual void listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow = true);
114    virtual bool multiple();
115#endif
116
117    virtual bool hasLineIfEmpty() const { return true; }
118
119    Color itemBackgroundColor(unsigned listIndex) const;
120
121    void createInnerBlock();
122    void adjustInnerStyle();
123    void setText(const String&);
124    void setTextFromOption(int optionIndex);
125    void updateOptionsWidth();
126
127    RenderText* m_buttonText;
128    RenderBlock* m_innerBlock;
129
130    bool m_optionsChanged;
131    int m_optionsWidth;
132
133    int m_lastSelectedIndex;
134
135    RefPtr<RenderStyle> m_optionStyle;
136
137    RefPtr<PopupMenu> m_popup;
138    bool m_popupIsVisible;
139};
140
141inline RenderMenuList* toRenderMenuList(RenderObject* object)
142{
143    ASSERT(!object || object->isMenuList());
144    return static_cast<RenderMenuList*>(object);
145}
146
147// This will catch anyone doing an unnecessary cast.
148void toRenderMenuList(const RenderMenuList*);
149
150}
151
152#endif
153