• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 #include "config.h"
32 #include "WebPopupMenuImpl.h"
33 
34 #include "Cursor.h"
35 #include "FramelessScrollView.h"
36 #include "FrameView.h"
37 #include "IntRect.h"
38 #include "painting/GraphicsContextBuilder.h"
39 #include "PlatformKeyboardEvent.h"
40 #include "PlatformMouseEvent.h"
41 #include "PlatformWheelEvent.h"
42 #include "SkiaUtils.h"
43 
44 #include "WebInputEvent.h"
45 #include "WebInputEventConversion.h"
46 #include "WebRect.h"
47 #include "WebWidgetClient.h"
48 
49 #include <skia/ext/platform_canvas.h>
50 
51 using namespace WebCore;
52 
53 namespace WebKit {
54 
55 // WebPopupMenu ---------------------------------------------------------------
56 
create(WebWidgetClient * client)57 WebPopupMenu* WebPopupMenu::create(WebWidgetClient* client)
58 {
59     // Pass the WebPopupMenuImpl's self-reference to the caller.
60     return adoptRef(new WebPopupMenuImpl(client)).leakRef();
61 }
62 
63 // WebWidget ------------------------------------------------------------------
64 
WebPopupMenuImpl(WebWidgetClient * client)65 WebPopupMenuImpl::WebPopupMenuImpl(WebWidgetClient* client)
66     : m_client(client)
67     , m_widget(0)
68 {
69     // set to impossible point so we always get the first mouse pos
70     m_lastMousePosition = WebPoint(-1, -1);
71 }
72 
~WebPopupMenuImpl()73 WebPopupMenuImpl::~WebPopupMenuImpl()
74 {
75     if (m_widget)
76         m_widget->setClient(0);
77 }
78 
Init(FramelessScrollView * widget,const WebRect & bounds)79 void WebPopupMenuImpl::Init(FramelessScrollView* widget, const WebRect& bounds)
80 {
81     m_widget = widget;
82     m_widget->setClient(this);
83 
84     if (m_client) {
85         m_client->setWindowRect(bounds);
86         m_client->show(WebNavigationPolicy());  // Policy is ignored
87     }
88 }
89 
MouseMove(const WebMouseEvent & event)90 void WebPopupMenuImpl::MouseMove(const WebMouseEvent& event)
91 {
92     // don't send mouse move messages if the mouse hasn't moved.
93     if (event.x != m_lastMousePosition.x || event.y != m_lastMousePosition.y) {
94         m_lastMousePosition = WebPoint(event.x, event.y);
95         m_widget->handleMouseMoveEvent(PlatformMouseEventBuilder(m_widget, event));
96     }
97 }
98 
MouseLeave(const WebMouseEvent & event)99 void WebPopupMenuImpl::MouseLeave(const WebMouseEvent& event)
100 {
101     m_widget->handleMouseMoveEvent(PlatformMouseEventBuilder(m_widget, event));
102 }
103 
MouseDown(const WebMouseEvent & event)104 void WebPopupMenuImpl::MouseDown(const WebMouseEvent& event)
105 {
106     m_widget->handleMouseDownEvent(PlatformMouseEventBuilder(m_widget, event));
107 }
108 
MouseUp(const WebMouseEvent & event)109 void WebPopupMenuImpl::MouseUp(const WebMouseEvent& event)
110 {
111     mouseCaptureLost();
112     m_widget->handleMouseReleaseEvent(PlatformMouseEventBuilder(m_widget, event));
113 }
114 
MouseWheel(const WebMouseWheelEvent & event)115 void WebPopupMenuImpl::MouseWheel(const WebMouseWheelEvent& event)
116 {
117     m_widget->handleWheelEvent(PlatformWheelEventBuilder(m_widget, event));
118 }
119 
KeyEvent(const WebKeyboardEvent & event)120 bool WebPopupMenuImpl::KeyEvent(const WebKeyboardEvent& event)
121 {
122     return m_widget->handleKeyEvent(PlatformKeyboardEventBuilder(event));
123 }
124 
125 // WebWidget -------------------------------------------------------------------
126 
close()127 void WebPopupMenuImpl::close()
128 {
129     if (m_widget)
130         m_widget->hide();
131 
132     m_client = 0;
133 
134     deref();  // Balances ref() from WebWidget::Create
135 }
136 
resize(const WebSize & newSize)137 void WebPopupMenuImpl::resize(const WebSize& newSize)
138 {
139     if (m_size == newSize)
140         return;
141     m_size = newSize;
142 
143     if (m_widget) {
144         IntRect newGeometry(0, 0, m_size.width, m_size.height);
145         m_widget->setFrameRect(newGeometry);
146     }
147 
148     if (m_client) {
149         WebRect damagedRect(0, 0, m_size.width, m_size.height);
150         m_client->didInvalidateRect(damagedRect);
151     }
152 }
153 
animate()154 void WebPopupMenuImpl::animate()
155 {
156 }
157 
layout()158 void WebPopupMenuImpl::layout()
159 {
160 }
161 
paint(WebCanvas * canvas,const WebRect & rect)162 void WebPopupMenuImpl::paint(WebCanvas* canvas, const WebRect& rect)
163 {
164     if (!m_widget)
165         return;
166 
167     if (!rect.isEmpty())
168         m_widget->paint(&GraphicsContextBuilder(canvas).context(), rect);
169 }
170 
themeChanged()171 void WebPopupMenuImpl::themeChanged()
172 {
173     notImplemented();
174 }
175 
composite(bool finish)176 void WebPopupMenuImpl::composite(bool finish)
177 {
178     notImplemented();
179 }
180 
handleInputEvent(const WebInputEvent & inputEvent)181 bool WebPopupMenuImpl::handleInputEvent(const WebInputEvent& inputEvent)
182 {
183     if (!m_widget)
184         return false;
185 
186     // TODO (jcampan): WebKit seems to always return false on mouse events
187     // methods. For now we'll assume it has processed them (as we are only
188     // interested in whether keyboard events are processed).
189     switch (inputEvent.type) {
190     case WebInputEvent::MouseMove:
191         MouseMove(*static_cast<const WebMouseEvent*>(&inputEvent));
192         return true;
193 
194     case WebInputEvent::MouseLeave:
195         MouseLeave(*static_cast<const WebMouseEvent*>(&inputEvent));
196         return true;
197 
198     case WebInputEvent::MouseWheel:
199         MouseWheel(*static_cast<const WebMouseWheelEvent*>(&inputEvent));
200         return true;
201 
202     case WebInputEvent::MouseDown:
203         MouseDown(*static_cast<const WebMouseEvent*>(&inputEvent));
204         return true;
205 
206     case WebInputEvent::MouseUp:
207         MouseUp(*static_cast<const WebMouseEvent*>(&inputEvent));
208         return true;
209 
210     // In Windows, RawKeyDown only has information about the physical key, but
211     // for "selection", we need the information about the character the key
212     // translated into. For English, the physical key value and the character
213     // value are the same, hence, "selection" works for English. But for other
214     // languages, such as Hebrew, the character value is different from the
215     // physical key value. Thus, without accepting Char event type which
216     // contains the key's character value, the "selection" won't work for
217     // non-English languages, such as Hebrew.
218     case WebInputEvent::RawKeyDown:
219     case WebInputEvent::KeyDown:
220     case WebInputEvent::KeyUp:
221     case WebInputEvent::Char:
222         return KeyEvent(*static_cast<const WebKeyboardEvent*>(&inputEvent));
223 
224     default:
225         break;
226     }
227     return false;
228 }
229 
mouseCaptureLost()230 void WebPopupMenuImpl::mouseCaptureLost()
231 {
232 }
233 
setFocus(bool enable)234 void WebPopupMenuImpl::setFocus(bool enable)
235 {
236 }
237 
setComposition(const WebString & text,const WebVector<WebCompositionUnderline> & underlines,int selectionStart,int selectionEnd)238 bool WebPopupMenuImpl::setComposition(
239     const WebString& text, const WebVector<WebCompositionUnderline>& underlines,
240     int selectionStart, int selectionEnd)
241 {
242     return false;
243 }
244 
confirmComposition()245 bool WebPopupMenuImpl::confirmComposition()
246 {
247     return false;
248 }
249 
confirmComposition(const WebString & text)250 bool WebPopupMenuImpl::confirmComposition(const WebString& text)
251 {
252     return false;
253 }
254 
textInputType()255 WebTextInputType WebPopupMenuImpl::textInputType()
256 {
257     return WebTextInputTypeNone;
258 }
259 
caretOrSelectionBounds()260 WebRect WebPopupMenuImpl::caretOrSelectionBounds()
261 {
262     return WebRect();
263 }
264 
setTextDirection(WebTextDirection direction)265 void WebPopupMenuImpl::setTextDirection(WebTextDirection direction)
266 {
267 }
268 
269 
270 //-----------------------------------------------------------------------------
271 // WebCore::HostWindow
272 
invalidateContents(const IntRect &,bool)273 void WebPopupMenuImpl::invalidateContents(const IntRect&, bool)
274 {
275     notImplemented();
276 }
277 
invalidateWindow(const IntRect &,bool)278 void WebPopupMenuImpl::invalidateWindow(const IntRect&, bool)
279 {
280     notImplemented();
281 }
282 
invalidateContentsAndWindow(const IntRect & paintRect,bool)283 void WebPopupMenuImpl::invalidateContentsAndWindow(const IntRect& paintRect, bool /*immediate*/)
284 {
285     if (paintRect.isEmpty())
286         return;
287     if (m_client)
288         m_client->didInvalidateRect(paintRect);
289 }
290 
invalidateContentsForSlowScroll(const IntRect & updateRect,bool immediate)291 void WebPopupMenuImpl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate)
292 {
293     invalidateContentsAndWindow(updateRect, immediate);
294 }
295 
scheduleAnimation()296 void WebPopupMenuImpl::scheduleAnimation()
297 {
298 }
299 
scroll(const IntSize & scrollDelta,const IntRect & scrollRect,const IntRect & clipRect)300 void WebPopupMenuImpl::scroll(const IntSize& scrollDelta,
301                               const IntRect& scrollRect,
302                               const IntRect& clipRect)
303 {
304     if (m_client) {
305         int dx = scrollDelta.width();
306         int dy = scrollDelta.height();
307         m_client->didScrollRect(dx, dy, clipRect);
308     }
309 }
310 
screenToWindow(const IntPoint & point) const311 IntPoint WebPopupMenuImpl::screenToWindow(const IntPoint& point) const
312 {
313     notImplemented();
314     return IntPoint();
315 }
316 
windowToScreen(const IntRect & rect) const317 IntRect WebPopupMenuImpl::windowToScreen(const IntRect& rect) const
318 {
319     notImplemented();
320     return IntRect();
321 }
322 
scrollRectIntoView(const IntRect &,const ScrollView *) const323 void WebPopupMenuImpl::scrollRectIntoView(const IntRect&, const ScrollView*) const
324 {
325     // Nothing to be done here since we do not have the concept of a container
326     // that implements its own scrolling.
327 }
328 
scrollbarsModeDidChange() const329 void WebPopupMenuImpl::scrollbarsModeDidChange() const
330 {
331     // Nothing to be done since we have no concept of different scrollbar modes.
332 }
333 
setCursor(const WebCore::Cursor &)334 void WebPopupMenuImpl::setCursor(const WebCore::Cursor&)
335 {
336 }
337 
338 //-----------------------------------------------------------------------------
339 // WebCore::FramelessScrollViewClient
340 
popupClosed(FramelessScrollView * widget)341 void WebPopupMenuImpl::popupClosed(FramelessScrollView* widget)
342 {
343     ASSERT(widget == m_widget);
344     if (m_widget) {
345         m_widget->setClient(0);
346         m_widget = 0;
347     }
348     m_client->closeWidgetSoon();
349 }
350 
351 } // namespace WebKit
352