Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / web / WebPluginScrollbarImpl.cpp
1 /*
2  * Copyright (C) 2012 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
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26 #include "web/WebPluginScrollbarImpl.h"
27
28 #include "platform/KeyboardCodes.h"
29 #include "platform/graphics/GraphicsContext.h"
30 #include "platform/scroll/ScrollAnimator.h"
31 #include "platform/scroll/ScrollTypes.h"
32 #include "platform/scroll/Scrollbar.h"
33 #include "platform/scroll/ScrollbarTheme.h"
34 #include "public/platform/WebCanvas.h"
35 #include "public/platform/WebRect.h"
36 #include "public/platform/WebVector.h"
37 #include "public/web/WebInputEvent.h"
38 #include "public/web/WebPluginScrollbarClient.h"
39 #include "web/ScrollbarGroup.h"
40 #include "web/WebInputEventConversion.h"
41 #include "web/WebPluginContainerImpl.h"
42 #include "web/WebViewImpl.h"
43
44 using namespace blink;
45
46 namespace blink {
47
48 WebPluginScrollbar* WebPluginScrollbar::createForPlugin(Orientation orientation,
49                                                         WebPluginContainer* pluginContainer,
50                                                         WebPluginScrollbarClient* client)
51 {
52     WebPluginContainerImpl* plugin = toWebPluginContainerImpl(pluginContainer);
53     return new WebPluginScrollbarImpl(orientation, plugin->scrollbarGroup(), client);
54 }
55
56 int WebPluginScrollbar::defaultThickness()
57 {
58     return ScrollbarTheme::theme()->scrollbarThickness();
59 }
60
61 WebPluginScrollbarImpl::WebPluginScrollbarImpl(Orientation orientation,
62                                    ScrollbarGroup* group,
63                                    WebPluginScrollbarClient* client)
64     : m_group(group)
65     , m_client(client)
66     , m_scrollOffset(0)
67 {
68     m_scrollbar = Scrollbar::create(
69         static_cast<ScrollableArea*>(m_group),
70         static_cast<blink::ScrollbarOrientation>(orientation),
71         blink::RegularScrollbar);
72     m_group->scrollbarCreated(this);
73 }
74
75 WebPluginScrollbarImpl::~WebPluginScrollbarImpl()
76 {
77     m_group->scrollbarDestroyed(this);
78 }
79
80 void WebPluginScrollbarImpl::setScrollOffset(int scrollOffset)
81 {
82     m_scrollOffset = scrollOffset;
83     m_client->valueChanged(this);
84 }
85
86 void WebPluginScrollbarImpl::invalidateScrollbarRect(const IntRect& rect)
87 {
88     WebRect webrect(rect);
89     webrect.x += m_scrollbar->x();
90     webrect.y += m_scrollbar->y();
91     m_client->invalidateScrollbarRect(this, webrect);
92 }
93
94 void WebPluginScrollbarImpl::getTickmarks(Vector<IntRect>& tickmarks) const
95 {
96     WebVector<WebRect> ticks;
97     m_client->getTickmarks(const_cast<WebPluginScrollbarImpl*>(this), &ticks);
98     tickmarks.resize(ticks.size());
99     for (size_t i = 0; i < ticks.size(); ++i)
100         tickmarks[i] = ticks[i];
101 }
102
103 IntPoint WebPluginScrollbarImpl::convertFromContainingViewToScrollbar(const IntPoint& parentPoint) const
104 {
105     IntPoint offset(parentPoint.x() - m_scrollbar->x(), parentPoint.y() - m_scrollbar->y());
106     return m_scrollbar->Widget::convertFromContainingView(offset);
107 }
108
109 void WebPluginScrollbarImpl::scrollbarStyleChanged()
110 {
111     m_client->overlayChanged(this);
112 }
113
114 bool WebPluginScrollbarImpl::isOverlay() const
115 {
116     return m_scrollbar->isOverlayScrollbar();
117 }
118
119 int WebPluginScrollbarImpl::value() const
120 {
121     return m_scrollOffset;
122 }
123
124 WebPoint WebPluginScrollbarImpl::location() const
125 {
126     return m_scrollbar->frameRect().location();
127 }
128
129 WebSize WebPluginScrollbarImpl::size() const
130 {
131     return m_scrollbar->frameRect().size();
132 }
133
134 bool WebPluginScrollbarImpl::enabled() const
135 {
136     return m_scrollbar->enabled();
137 }
138
139 int WebPluginScrollbarImpl::maximum() const
140 {
141     return m_scrollbar->maximum();
142 }
143
144 int WebPluginScrollbarImpl::totalSize() const
145 {
146     return m_scrollbar->totalSize();
147 }
148
149 bool WebPluginScrollbarImpl::isScrollViewScrollbar() const
150 {
151     return m_scrollbar->isScrollViewScrollbar();
152 }
153
154 bool WebPluginScrollbarImpl::isScrollableAreaActive() const
155 {
156     return m_scrollbar->isScrollableAreaActive();
157 }
158
159 void WebPluginScrollbarImpl::getTickmarks(WebVector<WebRect>& tickmarks) const
160 {
161     m_client->getTickmarks(const_cast<WebPluginScrollbarImpl*>(this), &tickmarks);
162 }
163
164 WebScrollbar::ScrollbarControlSize WebPluginScrollbarImpl::controlSize() const
165 {
166     return static_cast<WebScrollbar::ScrollbarControlSize>(m_scrollbar->controlSize());
167 }
168
169 WebScrollbar::ScrollbarPart WebPluginScrollbarImpl::pressedPart() const
170 {
171     return static_cast<WebScrollbar::ScrollbarPart>(m_scrollbar->pressedPart());
172 }
173
174 WebScrollbar::ScrollbarPart WebPluginScrollbarImpl::hoveredPart() const
175 {
176     return static_cast<WebScrollbar::ScrollbarPart>(m_scrollbar->hoveredPart());
177 }
178
179 WebScrollbar::ScrollbarOverlayStyle WebPluginScrollbarImpl::scrollbarOverlayStyle() const
180 {
181     return static_cast<WebScrollbar::ScrollbarOverlayStyle>(m_scrollbar->scrollbarOverlayStyle());
182 }
183
184 WebScrollbar::Orientation WebPluginScrollbarImpl::orientation() const
185 {
186     if (m_scrollbar->orientation() == blink::HorizontalScrollbar)
187         return WebScrollbar::Horizontal;
188     return WebScrollbar::Vertical;
189 }
190
191 bool WebPluginScrollbarImpl::isLeftSideVerticalScrollbar() const
192 {
193     return false;
194 }
195
196 bool WebPluginScrollbarImpl::isCustomScrollbar() const
197 {
198     return m_scrollbar->isCustomScrollbar();
199 }
200
201 void WebPluginScrollbarImpl::setLocation(const WebRect& rect)
202 {
203     IntRect oldRect = m_scrollbar->frameRect();
204     m_scrollbar->setFrameRect(rect);
205     if (WebRect(oldRect) != rect)
206       m_scrollbar->invalidate();
207
208     int length = m_scrollbar->orientation() == HorizontalScrollbar ? m_scrollbar->width() : m_scrollbar->height();
209     m_scrollbar->setEnabled(m_scrollbar->totalSize() > length);
210     m_scrollbar->setProportion(length, m_scrollbar->totalSize());
211 }
212
213 void WebPluginScrollbarImpl::setValue(int position)
214 {
215     m_group->scrollToOffsetWithoutAnimation(m_scrollbar->orientation(), static_cast<float>(position));
216 }
217
218 void WebPluginScrollbarImpl::setDocumentSize(int size)
219 {
220     int length = m_scrollbar->orientation() == HorizontalScrollbar ? m_scrollbar->width() : m_scrollbar->height();
221     m_scrollbar->setEnabled(size > length);
222     m_scrollbar->setProportion(length, size);
223 }
224
225 void WebPluginScrollbarImpl::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
226 {
227     blink::ScrollDirection dir;
228     bool horizontal = m_scrollbar->orientation() == HorizontalScrollbar;
229     if (direction == ScrollForward)
230         dir = horizontal ? ScrollRight : ScrollDown;
231     else
232         dir = horizontal ? ScrollLeft : ScrollUp;
233
234     m_group->scroll(dir, static_cast<blink::ScrollGranularity>(granularity), multiplier);
235 }
236
237 void WebPluginScrollbarImpl::paint(WebCanvas* canvas, const WebRect& rect)
238 {
239     GraphicsContext context(canvas);
240     m_scrollbar->paint(&context, rect);
241 }
242
243 bool WebPluginScrollbarImpl::handleInputEvent(const WebInputEvent& event)
244 {
245     switch (event.type) {
246     case WebInputEvent::MouseDown:
247         return onMouseDown(event);
248     case WebInputEvent::MouseUp:
249         return onMouseUp(event);
250     case WebInputEvent::MouseMove:
251         return onMouseMove(event);
252     case WebInputEvent::MouseLeave:
253         return onMouseLeave(event);
254     case WebInputEvent::MouseWheel:
255         return onMouseWheel(event);
256     case WebInputEvent::KeyDown:
257         return onKeyDown(event);
258     case WebInputEvent::Undefined:
259     case WebInputEvent::MouseEnter:
260     case WebInputEvent::RawKeyDown:
261     case WebInputEvent::KeyUp:
262     case WebInputEvent::Char:
263     case WebInputEvent::TouchStart:
264     case WebInputEvent::TouchMove:
265     case WebInputEvent::TouchEnd:
266     case WebInputEvent::TouchCancel:
267     default:
268          break;
269     }
270     return false;
271 }
272
273 bool WebPluginScrollbarImpl::isAlphaLocked() const
274 {
275     return m_scrollbar->isAlphaLocked();
276 }
277
278 void WebPluginScrollbarImpl::setIsAlphaLocked(bool flag)
279 {
280     return m_scrollbar->setIsAlphaLocked(flag);
281 }
282
283 bool WebPluginScrollbarImpl::onMouseDown(const WebInputEvent& event)
284 {
285     WebMouseEvent mousedown = static_cast<const WebMouseEvent&>(event);
286     if (!m_scrollbar->frameRect().contains(mousedown.x, mousedown.y))
287         return false;
288
289     mousedown.x -= m_scrollbar->x();
290     mousedown.y -= m_scrollbar->y();
291     m_scrollbar->mouseDown(PlatformMouseEventBuilder(m_scrollbar.get(), mousedown));
292     return true;
293 }
294
295 bool WebPluginScrollbarImpl::onMouseUp(const WebInputEvent& event)
296 {
297     WebMouseEvent mouseup = static_cast<const WebMouseEvent&>(event);
298     if (m_scrollbar->pressedPart() == blink::NoPart)
299         return false;
300
301     m_scrollbar->mouseUp(PlatformMouseEventBuilder(m_scrollbar.get(), mouseup));
302     return true;
303 }
304
305 bool WebPluginScrollbarImpl::onMouseMove(const WebInputEvent& event)
306 {
307     WebMouseEvent mousemove = static_cast<const WebMouseEvent&>(event);
308     if (m_scrollbar->frameRect().contains(mousemove.x, mousemove.y)
309         || m_scrollbar->pressedPart() != blink::NoPart) {
310         mousemove.x -= m_scrollbar->x();
311         mousemove.y -= m_scrollbar->y();
312         m_scrollbar->mouseMoved(PlatformMouseEventBuilder(m_scrollbar.get(), mousemove));
313         return true;
314     }
315
316     if (m_scrollbar->hoveredPart() != blink::NoPart && !m_scrollbar->isOverlayScrollbar())
317         m_scrollbar->mouseExited();
318     return false;
319 }
320
321 bool WebPluginScrollbarImpl::onMouseLeave(const WebInputEvent& event)
322 {
323     if (m_scrollbar->hoveredPart() != blink::NoPart)
324         m_scrollbar->mouseExited();
325
326     return false;
327 }
328
329 bool WebPluginScrollbarImpl::onMouseWheel(const WebInputEvent& event)
330 {
331     WebMouseWheelEvent mousewheel = static_cast<const WebMouseWheelEvent&>(event);
332     PlatformWheelEventBuilder platformEvent(m_scrollbar.get(), mousewheel);
333     return m_group->handleWheelEvent(platformEvent);
334 }
335
336 bool WebPluginScrollbarImpl::onKeyDown(const WebInputEvent& event)
337 {
338     WebKeyboardEvent keyboard = static_cast<const WebKeyboardEvent&>(event);
339     int keyCode;
340     // We have to duplicate this logic from WebViewImpl because there it uses
341     // Char and RawKeyDown events, which don't exist at this point.
342     if (keyboard.windowsKeyCode == VKEY_SPACE)
343         keyCode = ((keyboard.modifiers & WebInputEvent::ShiftKey) ? VKEY_PRIOR : VKEY_NEXT);
344     else {
345         if (keyboard.modifiers == WebInputEvent::ControlKey) {
346             // Match FF behavior in the sense that Ctrl+home/end are the only Ctrl
347             // key combinations which affect scrolling. Safari is buggy in the
348             // sense that it scrolls the page for all Ctrl+scrolling key
349             // combinations. For e.g. Ctrl+pgup/pgdn/up/down, etc.
350             switch (keyboard.windowsKeyCode) {
351             case VKEY_HOME:
352             case VKEY_END:
353                 break;
354             default:
355                 return false;
356             }
357         }
358
359         if (keyboard.isSystemKey || (keyboard.modifiers & WebInputEvent::ShiftKey))
360             return false;
361
362         keyCode = keyboard.windowsKeyCode;
363     }
364     blink::ScrollDirection scrollDirection;
365     blink::ScrollGranularity scrollGranularity;
366     if (WebViewImpl::mapKeyCodeForScroll(keyCode, &scrollDirection, &scrollGranularity)) {
367         // Will return false if scroll direction wasn't compatible with this scrollbar.
368         return m_group->scroll(scrollDirection, scrollGranularity);
369     }
370     return false;
371 }
372
373 } // namespace blink