1 /* 2 * Copyright (c) 2008, 2009, Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef PopupMenuChromium_h 32 #define PopupMenuChromium_h 33 34 #include "config.h" 35 36 #include "FramelessScrollView.h" 37 #include "IntRect.h" 38 #include "PlatformString.h" 39 #include "PopupMenu.h" 40 #include "PopupMenuPrivate.h" 41 #include "PopupMenuStyle.h" 42 43 namespace WebCore { 44 45 class ChromeClientChromium; 46 class FrameView; 47 class PopupListBox; 48 class PopupMenuClient; 49 50 // A container for the data for each menu item (e.g. represented by <option> 51 // or <optgroup> in a <select> widget) and is used by PopupListBox. 52 struct PopupItem { 53 enum Type { 54 TypeOption, 55 TypeGroup, 56 TypeSeparator 57 }; 58 59 PopupItem(const String& label, Type type) 60 : label(label) 61 , type(type) 62 , yOffset(0) 63 { 64 } 65 String label; 66 Type type; 67 int yOffset; // y offset of this item, relative to the top of the popup. 68 TextDirection textDirection; 69 bool hasTextDirectionOverride; 70 bool enabled; 71 }; 72 73 // FIXME: Our FramelessScrollView classes should probably implement HostWindow! 74 75 // The PopupContainer class holds a PopupListBox (see cpp file). Its sole purpose is to be 76 // able to draw a border around its child. All its paint/event handling is 77 // just forwarded to the child listBox (with the appropriate transforms). 78 // NOTE: this class is exposed so it can be instantiated direcly for the 79 // autofill popup. We cannot use the Popup class directly in that case as the 80 // autofill popup should not be focused when shown and we want to forward the 81 // key events to it (through handleKeyEvent). 82 83 struct PopupContainerSettings { 84 // Whether the PopupMenuClient should be told to change its text when a 85 // new item is selected by using the arrow keys. 86 bool setTextOnIndexChange; 87 88 // Whether the selection should be accepted when the popup menu is 89 // closed (through ESC being pressed or the focus going away). 90 // Note that when TAB is pressed, the selection is always accepted 91 // regardless of this setting. 92 bool acceptOnAbandon; 93 94 // Whether we should move the selection to the first/last item when 95 // the user presses down/up arrow keys and the last/first item is 96 // selected. 97 bool loopSelectionNavigation; 98 99 // Whether we should restrict the width of the PopupListBox or not. 100 // Autocomplete popups are restricted, combo-boxes (select tags) aren't. 101 bool restrictWidthOfListBox; 102 }; 103 104 class PopupContainer : public FramelessScrollView { 105 public: 106 enum PopupType { 107 Select, // HTML select popup. 108 Suggestion, // Autocomplete/autofill popup. 109 }; 110 111 static PassRefPtr<PopupContainer> create(PopupMenuClient*, PopupType, 112 const PopupContainerSettings&); 113 114 // Whether a key event should be sent to this popup. 115 virtual bool isInterestedInEventForKey(int keyCode); 116 117 // FramelessScrollView 118 virtual void paint(GraphicsContext*, const IntRect&); 119 virtual void hide(); 120 virtual bool handleMouseDownEvent(const PlatformMouseEvent&); 121 virtual bool handleMouseMoveEvent(const PlatformMouseEvent&); 122 virtual bool handleMouseReleaseEvent(const PlatformMouseEvent&); 123 virtual bool handleWheelEvent(const PlatformWheelEvent&); 124 virtual bool handleKeyEvent(const PlatformKeyboardEvent&); 125 126 // PopupContainer methods 127 128 // Show the popup 129 void showPopup(FrameView*); 130 131 // Show the popup in the specified rect for the specified frame. 132 // Note: this code was somehow arbitrarily factored-out of the Popup class 133 // so WebViewImpl can create a PopupContainer. This method is used for 134 // displaying auto complete popup menus on Mac Chromium, and for all 135 // popups on other platforms. 136 void showInRect(const IntRect&, FrameView*, int index); 137 138 // Hides the popup. 139 void hidePopup(); 140 141 // The popup was hidden. 142 void notifyPopupHidden(); 143 144 // Compute size of widget and children. Return right offset for RTL. 145 int layoutAndGetRightOffset(); 146 147 PopupListBox* listBox() const { return m_listBox.get(); } 148 149 // Gets the index of the item that the user is currently moused-over or 150 // has selected with the keyboard up/down arrows. 151 int selectedIndex() const; 152 153 // Refresh the popup values from the PopupMenuClient. 154 void refresh(const IntRect& targetControlRect); 155 156 // The menu per-item data. 157 const WTF::Vector<PopupItem*>& popupData() const; 158 159 // The height of a row in the menu. 160 int menuItemHeight() const; 161 162 // The size of the font being used. 163 int menuItemFontSize() const; 164 165 // The style of the menu being used. 166 PopupMenuStyle menuStyle() const; 167 168 PopupType popupType() const { return m_popupType; } 169 170 private: 171 friend class WTF::RefCounted<PopupContainer>; 172 173 PopupContainer(PopupMenuClient*, PopupType popupType, const PopupContainerSettings&); 174 ~PopupContainer(); 175 176 // Paint the border. 177 void paintBorder(GraphicsContext*, const IntRect&); 178 179 // Layout and calculate popup widget size and location and returns it as IntRect. 180 IntRect layoutAndCalculateWidgetRect(int targetControlHeight, const IntPoint& popupInitialCoordinate); 181 182 // Returns the ChromeClient of the page this popup is associated with. 183 ChromeClientChromium* chromeClientChromium(); 184 185 RefPtr<PopupListBox> m_listBox; 186 RefPtr<FrameView> m_frameView; 187 188 PopupContainerSettings m_settings; 189 PopupType m_popupType; 190 // Whether the popup is currently open. 191 bool m_popupOpen; 192 }; 193 194 class PopupMenuChromium : public PopupMenu { 195 public: 196 PopupMenuChromium(PopupMenuClient*); 197 ~PopupMenuChromium(); 198 199 virtual void show(const IntRect&, FrameView*, int index); 200 virtual void hide(); 201 virtual void updateFromElement(); 202 virtual void disconnectClient(); 203 204 private: 205 PopupMenuClient* client() const { return m_popupClient; } 206 207 PopupMenuClient* m_popupClient; 208 PopupMenuPrivate p; 209 }; 210 211 } // namespace WebCore 212 213 #endif 214