1 2 /* 3 * Copyright (c) 2011, Google Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above 12 * copyright notice, this list of conditions and the following disclaimer 13 * in the documentation and/or other materials provided with the 14 * distribution. 15 * * Neither the name of Google Inc. nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef PopupContainer_h 33 #define PopupContainer_h 34 35 #include "platform/PopupMenuStyle.h" 36 #include "platform/geometry/FloatQuad.h" 37 #include "web/PopupListBox.h" 38 39 namespace blink { 40 41 class ChromeClient; 42 class FrameView; 43 class PopupContainerClient; 44 class PopupMenuClient; 45 struct WebPopupMenuInfo; 46 47 // This class wraps a PopupListBox. It positions the popup, paints the border 48 // around it, and forwards input events. 49 // FIXME(skobes): This class can probably be combined with PopupListBox. 50 class PopupContainer FINAL : public Widget { 51 public: 52 static PassRefPtr<PopupContainer> create(PopupMenuClient*, bool deviceSupportsTouch); 53 54 // Whether a key event should be sent to this popup. 55 bool isInterestedInEventForKey(int keyCode); 56 57 // Widget 58 virtual void paint(GraphicsContext*, const IntRect&) OVERRIDE; 59 virtual void hide() OVERRIDE; 60 virtual HostWindow* hostWindow() const OVERRIDE; 61 virtual void invalidateRect(const IntRect&) OVERRIDE; 62 virtual IntPoint convertChildToSelf(const Widget* child, const IntPoint&) const OVERRIDE; 63 virtual IntPoint convertSelfToChild(const Widget* child, const IntPoint&) const OVERRIDE; 64 65 // PopupContainer methods 66 67 bool handleMouseDownEvent(const PlatformMouseEvent&); 68 bool handleMouseMoveEvent(const PlatformMouseEvent&); 69 bool handleMouseReleaseEvent(const PlatformMouseEvent&); 70 bool handleWheelEvent(const PlatformWheelEvent&); 71 bool handleKeyEvent(const PlatformKeyboardEvent&); 72 bool handleTouchEvent(const PlatformTouchEvent&); 73 bool handleGestureEvent(const PlatformGestureEvent&); 74 client()75 PopupContainerClient* client() const { return m_client; } setClient(PopupContainerClient * client)76 void setClient(PopupContainerClient* client) { m_client = client; } 77 78 // Show the popup 79 void showPopup(FrameView*); 80 81 // Show the popup in the specified rect for the specified frame. 82 // Note: this code was somehow arbitrarily factored-out of the Popup class 83 // so WebViewImpl can create a PopupContainer. This method is used for 84 // displaying auto complete popup menus on Mac Chromium, and for all 85 // popups on other platforms. 86 void showInRect(const FloatQuad& controlPosition, const IntSize& controlSize, FrameView*, int index); 87 88 // Hides the popup. 89 void hidePopup(); 90 91 // The popup was hidden. 92 void notifyPopupHidden(); 93 listBox()94 PopupListBox* listBox() const { return m_listBox.get(); } 95 96 bool isRTL() const; 97 98 // Gets the index of the item that the user is currently moused-over or 99 // has selected with the keyboard up/down arrows. 100 int selectedIndex() const; 101 102 // Refresh the popup values from the PopupMenuClient. 103 IntRect refresh(const IntRect& targetControlRect); 104 105 // The menu per-item data. 106 const Vector<PopupItem*>& popupData() const; 107 108 // The height of a row in the menu. 109 int menuItemHeight() const; 110 111 // The size of the font being used. 112 int menuItemFontSize() const; 113 114 // The style of the menu being used. 115 PopupMenuStyle menuStyle() const; 116 117 // While hovering popup menu window, we want to show tool tip message. 118 String getSelectedItemToolTip(); 119 120 // This is public for testing. 121 static IntRect layoutAndCalculateWidgetRectInternal(IntRect widgetRectInScreen, int targetControlHeight, const FloatRect& windowRect, const FloatRect& screen, bool isRTL, const int rtlOffset, const int verticalOffset, const IntSize& transformOffset, PopupContent*, bool& needToResizeView); 122 disconnectClient()123 void disconnectClient() { m_listBox->disconnectClient(); } 124 updateFromElement()125 void updateFromElement() { m_listBox->updateFromElement(); } 126 127 private: 128 friend class WTF::RefCounted<PopupContainer>; 129 130 PopupContainer(PopupMenuClient*, bool deviceSupportsTouch); 131 virtual ~PopupContainer(); 132 133 // Paint the border. 134 void paintBorder(GraphicsContext*, const IntRect&); 135 136 // Layout and calculate popup widget size and location and returns it as IntRect. 137 IntRect layoutAndCalculateWidgetRect(int targetControlHeight, const IntSize& transformOffset, const IntPoint& popupInitialCoordinate); 138 139 void fitToListBox(); 140 141 void popupOpened(const IntRect& bounds); 142 void getPopupMenuInfo(WebPopupMenuInfo*); 143 144 // Returns the ChromeClient of the page this popup is associated with. 145 ChromeClient& chromeClient(); 146 147 RefPtr<PopupListBox> m_listBox; 148 RefPtr<FrameView> m_frameView; 149 150 // m_controlPosition contains the transformed position of the 151 // <select>/<input> associated with this popup. m_controlSize is the size 152 // of the <select>/<input> without transform. 153 // The popup menu will be positioned as follows: 154 // LTR : If the popup is positioned down it will align with the bottom left 155 // of m_controlPosition (p4) 156 // If the popup is positioned up it will align with the top left of 157 // m_controlPosition (p1) 158 // RTL : If the popup is positioned down it will align with the bottom right 159 // of m_controlPosition (p3) 160 // If the popup is positioned up it will align with the top right of 161 // m_controlPosition (p2) 162 FloatQuad m_controlPosition; 163 IntSize m_controlSize; 164 165 // Whether the popup is currently open. 166 bool m_popupOpen; 167 168 PopupContainerClient* m_client; 169 }; 170 171 } // namespace blink 172 173 #endif 174