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 PopupItemPopupItem54 PopupItem(const String& label, Type type) 55 : label(label), type(type), yOffset(0) { } 56 String label; 57 Type type; 58 int yOffset; // y offset of this item, relative to the top of the popup. 59 bool enabled; 60 }; 61 62 // FIXME: Our FramelessScrollView classes should probably implement HostWindow! 63 64 // The PopupContainer class holds a PopupListBox (see cpp file). Its sole purpose is to be 65 // able to draw a border around its child. All its paint/event handling is 66 // just forwarded to the child listBox (with the appropriate transforms). 67 // NOTE: this class is exposed so it can be instantiated direcly for the 68 // autofill popup. We cannot use the Popup class directly in that case as the 69 // autofill popup should not be focused when shown and we want to forward the 70 // key events to it (through handleKeyEvent). 71 72 struct PopupContainerSettings { 73 // Whether the popup should get the focus when displayed. 74 bool focusOnShow; 75 76 // Whether the PopupMenuClient should be told to change its text when a 77 // new item is selected by using the arrow keys. 78 bool setTextOnIndexChange; 79 80 // Whether the selection should be accepted when the popup menu is 81 // closed (through ESC being pressed or the focus going away). 82 // Note that when TAB is pressed, the selection is always accepted 83 // regardless of this setting. 84 bool acceptOnAbandon; 85 86 // Whether the we should move the selection to the first/last item when 87 // the user presses down/up arrow keys and the last/first item is 88 // selected. 89 bool loopSelectionNavigation; 90 }; 91 92 class PopupContainer : public FramelessScrollView { 93 public: 94 static PassRefPtr<PopupContainer> create(PopupMenuClient*, 95 const PopupContainerSettings&); 96 97 // Whether a key event should be sent to this popup. 98 virtual bool isInterestedInEventForKey(int keyCode); 99 100 // FramelessScrollView 101 virtual void paint(GraphicsContext*, const IntRect&); 102 virtual void hide(); 103 virtual bool handleMouseDownEvent(const PlatformMouseEvent&); 104 virtual bool handleMouseMoveEvent(const PlatformMouseEvent&); 105 virtual bool handleMouseReleaseEvent(const PlatformMouseEvent&); 106 virtual bool handleWheelEvent(const PlatformWheelEvent&); 107 virtual bool handleKeyEvent(const PlatformKeyboardEvent&); 108 109 // PopupContainer methods 110 111 // Show the popup 112 void showPopup(FrameView*); 113 114 // Used on Mac Chromium for HTML select popup menus. 115 void showExternal(const IntRect&, FrameView*, int index); 116 117 // Show the popup in the specified rect for the specified frame. 118 // Note: this code was somehow arbitrarily factored-out of the Popup class 119 // so WebViewImpl can create a PopupContainer. This method is used for 120 // displaying auto complete popup menus on Mac Chromium, and for all 121 // popups on other platforms. 122 void show(const IntRect&, FrameView*, int index); 123 124 // Hide the popup. Do not call this directly: use client->hidePopup(). 125 void hidePopup(); 126 127 // Compute size of widget and children. 128 void layout(); 129 listBox()130 PopupListBox* listBox() const { return m_listBox.get(); } 131 132 // Gets the index of the item that the user is currently moused-over or 133 // has selected with the keyboard up/down arrows. 134 int selectedIndex() const; 135 136 // Refresh the popup values from the PopupMenuClient. 137 void refresh(); 138 139 // The menu per-item data. 140 const WTF::Vector<PopupItem*>& popupData() const; 141 142 // The height of a row in the menu. 143 int menuItemHeight() const; 144 145 private: 146 friend class WTF::RefCounted<PopupContainer>; 147 148 PopupContainer(PopupMenuClient*, const PopupContainerSettings&); 149 ~PopupContainer(); 150 151 // Paint the border. 152 void paintBorder(GraphicsContext*, const IntRect&); 153 154 RefPtr<PopupListBox> m_listBox; 155 156 PopupContainerSettings m_settings; 157 }; 158 159 } // namespace WebCore 160 161 #endif 162