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 #include "PopupMenuClient.h" 36 37 #include "FramelessScrollView.h" 38 #include "IntRect.h" 39 40 namespace WebCore { 41 42 class FrameView; 43 class PopupListBox; 44 45 // A container for the data for each menu item (e.g. represented by <option> 46 // or <optgroup> in a <select> widget) and is used by PopupListBox. 47 struct PopupItem { 48 enum Type { 49 TypeOption, 50 TypeGroup, 51 TypeSeparator 52 }; 53 54 PopupItem(const String& label, Type type) 55 : label(label) 56 , type(type) 57 , yOffset(0) 58 { 59 } 60 String label; 61 Type type; 62 int yOffset; // y offset of this item, relative to the top of the popup. 63 bool enabled; 64 }; 65 66 // FIXME: Our FramelessScrollView classes should probably implement HostWindow! 67 68 // The PopupContainer class holds a PopupListBox (see cpp file). Its sole purpose is to be 69 // able to draw a border around its child. All its paint/event handling is 70 // just forwarded to the child listBox (with the appropriate transforms). 71 // NOTE: this class is exposed so it can be instantiated direcly for the 72 // autofill popup. We cannot use the Popup class directly in that case as the 73 // autofill popup should not be focused when shown and we want to forward the 74 // key events to it (through handleKeyEvent). 75 76 struct PopupContainerSettings { 77 // Whether the popup should get the focus when displayed. 78 bool focusOnShow; 79 80 // Whether the PopupMenuClient should be told to change its text when a 81 // new item is selected by using the arrow keys. 82 bool setTextOnIndexChange; 83 84 // Whether the selection should be accepted when the popup menu is 85 // closed (through ESC being pressed or the focus going away). 86 // Note that when TAB is pressed, the selection is always accepted 87 // regardless of this setting. 88 bool acceptOnAbandon; 89 90 // Whether we should move the selection to the first/last item when 91 // the user presses down/up arrow keys and the last/first item is 92 // selected. 93 bool loopSelectionNavigation; 94 95 // Whether we should restrict the width of the PopupListBox or not. 96 // Autocomplete popups are restricted, combo-boxes (select tags) aren't. 97 bool restrictWidthOfListBox; 98 99 // A hint on the display directionality of the item text in popup menu. 100 // 101 // We could either display the items in the drop-down using its DOM element's 102 // directionality, or we could display the items in the drop-down using heuristics: 103 // such as in its first strong directionality character's direction. 104 // Please refer to the discussion (especially comment #7 and #10) in 105 // https://bugs.webkit.org/show_bug.cgi?id=27889 for details. 106 enum DirectionalityHint { 107 // Use the DOM element's directionality to display the item text in popup menu. 108 DOMElementDirection, 109 // Use the item text's first strong-directional character's directionality 110 // to display the item text in popup menu. 111 FirstStrongDirectionalCharacterDirection, 112 }; 113 DirectionalityHint itemTextDirectionalityHint; 114 }; 115 116 class PopupContainer : public FramelessScrollView { 117 public: 118 static PassRefPtr<PopupContainer> create(PopupMenuClient*, 119 const PopupContainerSettings&); 120 121 // Whether a key event should be sent to this popup. 122 virtual bool isInterestedInEventForKey(int keyCode); 123 124 // FramelessScrollView 125 virtual void paint(GraphicsContext*, const IntRect&); 126 virtual void hide(); 127 virtual bool handleMouseDownEvent(const PlatformMouseEvent&); 128 virtual bool handleMouseMoveEvent(const PlatformMouseEvent&); 129 virtual bool handleMouseReleaseEvent(const PlatformMouseEvent&); 130 virtual bool handleWheelEvent(const PlatformWheelEvent&); 131 virtual bool handleKeyEvent(const PlatformKeyboardEvent&); 132 133 // PopupContainer methods 134 135 // Show the popup 136 void showPopup(FrameView*); 137 138 // Used on Mac Chromium for HTML select popup menus. 139 void showExternal(const IntRect&, FrameView*, int index); 140 141 // Show the popup in the specified rect for the specified frame. 142 // Note: this code was somehow arbitrarily factored-out of the Popup class 143 // so WebViewImpl can create a PopupContainer. This method is used for 144 // displaying auto complete popup menus on Mac Chromium, and for all 145 // popups on other platforms. 146 void show(const IntRect&, FrameView*, int index); 147 148 // Hide the popup. 149 void hidePopup(); 150 151 // Compute size of widget and children. 152 void layout(); 153 154 PopupListBox* listBox() const { return m_listBox.get(); } 155 156 // Gets the index of the item that the user is currently moused-over or 157 // has selected with the keyboard up/down arrows. 158 int selectedIndex() const; 159 160 // Refresh the popup values from the PopupMenuClient. 161 void refresh(); 162 163 // The menu per-item data. 164 const WTF::Vector<PopupItem*>& popupData() const; 165 166 // The height of a row in the menu. 167 int menuItemHeight() const; 168 169 private: 170 friend class WTF::RefCounted<PopupContainer>; 171 172 PopupContainer(PopupMenuClient*, const PopupContainerSettings&); 173 ~PopupContainer(); 174 175 // Paint the border. 176 void paintBorder(GraphicsContext*, const IntRect&); 177 178 RefPtr<PopupListBox> m_listBox; 179 180 PopupContainerSettings m_settings; 181 }; 182 183 } // namespace WebCore 184 185 #endif 186