OLD | NEW |
| (Empty) |
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 "PlatformContextSkia.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 | |
57 WebPopupMenu* WebPopupMenu::create(WebWidgetClient* client) | |
58 { | |
59 return new WebPopupMenuImpl(client); | |
60 } | |
61 | |
62 // WebWidget ------------------------------------------------------------------ | |
63 | |
64 WebPopupMenuImpl::WebPopupMenuImpl(WebWidgetClient* client) | |
65 : m_client(client) | |
66 , m_widget(0) | |
67 { | |
68 // set to impossible point so we always get the first mouse pos | |
69 m_lastMousePosition = WebPoint(-1, -1); | |
70 } | |
71 | |
72 WebPopupMenuImpl::~WebPopupMenuImpl() | |
73 { | |
74 if (m_widget) | |
75 m_widget->setClient(0); | |
76 } | |
77 | |
78 void WebPopupMenuImpl::Init(FramelessScrollView* widget, const WebRect& bounds) | |
79 { | |
80 m_widget = widget; | |
81 m_widget->setClient(this); | |
82 | |
83 if (m_client) { | |
84 m_client->setWindowRect(bounds); | |
85 m_client->show(WebNavigationPolicy()); // Policy is ignored | |
86 } | |
87 } | |
88 | |
89 void WebPopupMenuImpl::MouseMove(const WebMouseEvent& event) | |
90 { | |
91 // don't send mouse move messages if the mouse hasn't moved. | |
92 if (event.x != m_lastMousePosition.x || event.y != m_lastMousePosition.y) { | |
93 m_lastMousePosition = WebPoint(event.x, event.y); | |
94 m_widget->handleMouseMoveEvent(PlatformMouseEventBuilder(m_widget, event)); | |
95 } | |
96 } | |
97 | |
98 void WebPopupMenuImpl::MouseLeave(const WebMouseEvent& event) | |
99 { | |
100 m_widget->handleMouseMoveEvent(PlatformMouseEventBuilder(m_widget, event)); | |
101 } | |
102 | |
103 void WebPopupMenuImpl::MouseDown(const WebMouseEvent& event) | |
104 { | |
105 m_widget->handleMouseDownEvent(PlatformMouseEventBuilder(m_widget, event)); | |
106 } | |
107 | |
108 void WebPopupMenuImpl::MouseUp(const WebMouseEvent& event) | |
109 { | |
110 mouseCaptureLost(); | |
111 m_widget->handleMouseReleaseEvent(PlatformMouseEventBuilder(m_widget, event)); | |
112 } | |
113 | |
114 void WebPopupMenuImpl::MouseWheel(const WebMouseWheelEvent& event) | |
115 { | |
116 m_widget->handleWheelEvent(PlatformWheelEventBuilder(m_widget, event)); | |
117 } | |
118 | |
119 bool WebPopupMenuImpl::KeyEvent(const WebKeyboardEvent& event) | |
120 { | |
121 return m_widget->handleKeyEvent(PlatformKeyboardEventBuilder(event)); | |
122 } | |
123 | |
124 // WebWidget ------------------------------------------------------------------- | |
125 | |
126 void WebPopupMenuImpl::close() | |
127 { | |
128 if (m_widget) | |
129 m_widget->hide(); | |
130 | |
131 m_client = 0; | |
132 | |
133 deref(); // Balances ref() from WebWidget::Create | |
134 } | |
135 | |
136 void WebPopupMenuImpl::resize(const WebSize& newSize) | |
137 { | |
138 if (m_size == newSize) | |
139 return; | |
140 m_size = newSize; | |
141 | |
142 if (m_widget) { | |
143 IntRect newGeometry(0, 0, m_size.width, m_size.height); | |
144 m_widget->setFrameRect(newGeometry); | |
145 } | |
146 | |
147 if (m_client) { | |
148 WebRect damagedRect(0, 0, m_size.width, m_size.height); | |
149 m_client->didInvalidateRect(damagedRect); | |
150 } | |
151 } | |
152 | |
153 void WebPopupMenuImpl::layout() | |
154 { | |
155 } | |
156 | |
157 void WebPopupMenuImpl::paint(WebCanvas* canvas, const WebRect& rect) | |
158 { | |
159 if (!m_widget) | |
160 return; | |
161 | |
162 if (!rect.isEmpty()) { | |
163 #if WEBKIT_USING_CG | |
164 GraphicsContext gc(canvas); | |
165 #elif WEBKIT_USING_SKIA | |
166 PlatformContextSkia context(canvas); | |
167 // PlatformGraphicsContext is actually a pointer to PlatformContextSkia. | |
168 GraphicsContext gc(reinterpret_cast<PlatformGraphicsContext*>(&context)); | |
169 #else | |
170 notImplemented(); | |
171 #endif | |
172 m_widget->paint(&gc, rect); | |
173 } | |
174 } | |
175 | |
176 bool WebPopupMenuImpl::handleInputEvent(const WebInputEvent& inputEvent) | |
177 { | |
178 if (!m_widget) | |
179 return false; | |
180 | |
181 // TODO (jcampan): WebKit seems to always return false on mouse events | |
182 // methods. For now we'll assume it has processed them (as we are only | |
183 // interested in whether keyboard events are processed). | |
184 switch (inputEvent.type) { | |
185 case WebInputEvent::MouseMove: | |
186 MouseMove(*static_cast<const WebMouseEvent*>(&inputEvent)); | |
187 return true; | |
188 | |
189 case WebInputEvent::MouseLeave: | |
190 MouseLeave(*static_cast<const WebMouseEvent*>(&inputEvent)); | |
191 return true; | |
192 | |
193 case WebInputEvent::MouseWheel: | |
194 MouseWheel(*static_cast<const WebMouseWheelEvent*>(&inputEvent)); | |
195 return true; | |
196 | |
197 case WebInputEvent::MouseDown: | |
198 MouseDown(*static_cast<const WebMouseEvent*>(&inputEvent)); | |
199 return true; | |
200 | |
201 case WebInputEvent::MouseUp: | |
202 MouseUp(*static_cast<const WebMouseEvent*>(&inputEvent)); | |
203 return true; | |
204 | |
205 // In Windows, RawKeyDown only has information about the physical key, but | |
206 // for "selection", we need the information about the character the key | |
207 // translated into. For English, the physical key value and the character | |
208 // value are the same, hence, "selection" works for English. But for other | |
209 // languages, such as Hebrew, the character value is different from the | |
210 // physical key value. Thus, without accepting Char event type which | |
211 // contains the key's character value, the "selection" won't work for | |
212 // non-English languages, such as Hebrew. | |
213 case WebInputEvent::RawKeyDown: | |
214 case WebInputEvent::KeyDown: | |
215 case WebInputEvent::KeyUp: | |
216 case WebInputEvent::Char: | |
217 return KeyEvent(*static_cast<const WebKeyboardEvent*>(&inputEvent)); | |
218 | |
219 default: | |
220 break; | |
221 } | |
222 return false; | |
223 } | |
224 | |
225 void WebPopupMenuImpl::mouseCaptureLost() | |
226 { | |
227 } | |
228 | |
229 void WebPopupMenuImpl::setFocus(bool enable) | |
230 { | |
231 } | |
232 | |
233 bool WebPopupMenuImpl::handleCompositionEvent( | |
234 WebCompositionCommand command, int cursorPosition, int targetStart, | |
235 int targetEnd, const WebString& imeString) | |
236 { | |
237 return false; | |
238 } | |
239 | |
240 bool WebPopupMenuImpl::queryCompositionStatus(bool* enabled, WebRect* caretRect) | |
241 { | |
242 return false; | |
243 } | |
244 | |
245 void WebPopupMenuImpl::setTextDirection(WebTextDirection direction) | |
246 { | |
247 } | |
248 | |
249 | |
250 //----------------------------------------------------------------------------- | |
251 // WebCore::HostWindow | |
252 | |
253 void WebPopupMenuImpl::repaint(const IntRect& paintRect, | |
254 bool contentChanged, | |
255 bool immediate, | |
256 bool repaintContentOnly) | |
257 { | |
258 // Ignore spurious calls. | |
259 if (!contentChanged || paintRect.isEmpty()) | |
260 return; | |
261 if (m_client) | |
262 m_client->didInvalidateRect(paintRect); | |
263 } | |
264 | |
265 void WebPopupMenuImpl::scroll(const IntSize& scrollDelta, | |
266 const IntRect& scrollRect, | |
267 const IntRect& clipRect) | |
268 { | |
269 if (m_client) { | |
270 int dx = scrollDelta.width(); | |
271 int dy = scrollDelta.height(); | |
272 m_client->didScrollRect(dx, dy, clipRect); | |
273 } | |
274 } | |
275 | |
276 IntPoint WebPopupMenuImpl::screenToWindow(const IntPoint& point) const | |
277 { | |
278 notImplemented(); | |
279 return IntPoint(); | |
280 } | |
281 | |
282 IntRect WebPopupMenuImpl::windowToScreen(const IntRect& rect) const | |
283 { | |
284 notImplemented(); | |
285 return IntRect(); | |
286 } | |
287 | |
288 void WebPopupMenuImpl::scrollRectIntoView(const IntRect&, const ScrollView*) const | |
289 { | |
290 // Nothing to be done here since we do not have the concept of a container | |
291 // that implements its own scrolling. | |
292 } | |
293 | |
294 void WebPopupMenuImpl::scrollbarsModeDidChange() const | |
295 { | |
296 // Nothing to be done since we have no concept of different scrollbar modes. | |
297 } | |
298 | |
299 //----------------------------------------------------------------------------- | |
300 // WebCore::FramelessScrollViewClient | |
301 | |
302 void WebPopupMenuImpl::popupClosed(FramelessScrollView* widget) | |
303 { | |
304 ASSERT(widget == m_widget); | |
305 if (m_widget) { | |
306 m_widget->setClient(0); | |
307 m_widget = 0; | |
308 } | |
309 m_client->closeWidgetSoon(); | |
310 } | |
311 | |
312 } // namespace WebKit | |
OLD | NEW |