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 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 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 73 WebPopupMenuImpl::~WebPopupMenuImpl() 74 { 75 if (m_widget) 76 m_widget->setClient(0); 77 } 78 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 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 99 void WebPopupMenuImpl::MouseLeave(const WebMouseEvent& event) 100 { 101 m_widget->handleMouseMoveEvent(PlatformMouseEventBuilder(m_widget, event)); 102 } 103 104 void WebPopupMenuImpl::MouseDown(const WebMouseEvent& event) 105 { 106 m_widget->handleMouseDownEvent(PlatformMouseEventBuilder(m_widget, event)); 107 } 108 109 void WebPopupMenuImpl::MouseUp(const WebMouseEvent& event) 110 { 111 mouseCaptureLost(); 112 m_widget->handleMouseReleaseEvent(PlatformMouseEventBuilder(m_widget, event)); 113 } 114 115 void WebPopupMenuImpl::MouseWheel(const WebMouseWheelEvent& event) 116 { 117 m_widget->handleWheelEvent(PlatformWheelEventBuilder(m_widget, event)); 118 } 119 120 bool WebPopupMenuImpl::KeyEvent(const WebKeyboardEvent& event) 121 { 122 return m_widget->handleKeyEvent(PlatformKeyboardEventBuilder(event)); 123 } 124 125 // WebWidget ------------------------------------------------------------------- 126 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 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 154 void WebPopupMenuImpl::animate() 155 { 156 } 157 158 void WebPopupMenuImpl::layout() 159 { 160 } 161 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 171 void WebPopupMenuImpl::themeChanged() 172 { 173 notImplemented(); 174 } 175 176 void WebPopupMenuImpl::composite(bool finish) 177 { 178 notImplemented(); 179 } 180 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 230 void WebPopupMenuImpl::mouseCaptureLost() 231 { 232 } 233 234 void WebPopupMenuImpl::setFocus(bool enable) 235 { 236 } 237 238 bool WebPopupMenuImpl::setComposition( 239 const WebString& text, const WebVector<WebCompositionUnderline>& underlines, 240 int selectionStart, int selectionEnd) 241 { 242 return false; 243 } 244 245 bool WebPopupMenuImpl::confirmComposition() 246 { 247 return false; 248 } 249 250 bool WebPopupMenuImpl::confirmComposition(const WebString& text) 251 { 252 return false; 253 } 254 255 WebTextInputType WebPopupMenuImpl::textInputType() 256 { 257 return WebTextInputTypeNone; 258 } 259 260 WebRect WebPopupMenuImpl::caretOrSelectionBounds() 261 { 262 return WebRect(); 263 } 264 265 void WebPopupMenuImpl::setTextDirection(WebTextDirection direction) 266 { 267 } 268 269 270 //----------------------------------------------------------------------------- 271 // WebCore::HostWindow 272 273 void WebPopupMenuImpl::invalidateContents(const IntRect&, bool) 274 { 275 notImplemented(); 276 } 277 278 void WebPopupMenuImpl::invalidateWindow(const IntRect&, bool) 279 { 280 notImplemented(); 281 } 282 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 291 void WebPopupMenuImpl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) 292 { 293 invalidateContentsAndWindow(updateRect, immediate); 294 } 295 296 void WebPopupMenuImpl::scheduleAnimation() 297 { 298 } 299 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 311 IntPoint WebPopupMenuImpl::screenToWindow(const IntPoint& point) const 312 { 313 notImplemented(); 314 return IntPoint(); 315 } 316 317 IntRect WebPopupMenuImpl::windowToScreen(const IntRect& rect) const 318 { 319 notImplemented(); 320 return IntRect(); 321 } 322 323 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 329 void WebPopupMenuImpl::scrollbarsModeDidChange() const 330 { 331 // Nothing to be done since we have no concept of different scrollbar modes. 332 } 333 334 void WebPopupMenuImpl::setCursor(const WebCore::Cursor&) 335 { 336 } 337 338 //----------------------------------------------------------------------------- 339 // WebCore::FramelessScrollViewClient 340 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