Home | History | Annotate | Download | only in src
      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