Source/WebKit2/ChangeLog

 12013-09-13 Eunmi Lee <eunmi15.lee@samsung.com>
 2
 3 [EFL][WK2] Implement pan and flick gesture.
 4 https://bugs.webkit.org/show_bug.cgi?id=107101
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Implement pan gesture to scroll page by movement of point and stop
 9 scrolling smoothly using ease-in-out-quad algorithm after touched
 10 point is removed from the screen.
 11
 12 Use Ecore_Animator in order to process movement once per each framing
 13 time slot instead of processing all movement.
 14
 15 * PlatformEfl.cmake:
 16 * UIProcess/API/efl/EwkView.cpp:
 17 (EwkView::scrollBy):
 18 * UIProcess/API/efl/EwkView.h:
 19 * UIProcess/API/efl/GestureRecognizer.cpp:
 20 (WebKit::GestureHandler::view):
 21 (WebKit::GestureHandler::GestureHandler):
 22 (WebKit::GestureHandler::~GestureHandler):
 23 (WebKit::GestureHandler::reset):
 24 (WebKit::GestureHandler::panAnimatorCallback):
 25 (WebKit::GestureHandler::handlePanStarted):
 26 (WebKit::GestureHandler::handlePan):
 27 (WebKit::GestureHandler::handlePanFinished):
 28 (WebKit::GestureHandler::flickAnimatorCallback):
 29 (WebKit::GestureHandler::handleFlick):
 30 (WebKit::GestureRecognizer::noGesture):
 31 (WebKit::GestureRecognizer::reset):
 32 * UIProcess/efl/EasingCurves.cpp: Added.
 33 (WebKit::easeInOutQuad):
 34 * UIProcess/efl/EasingCurves.h: Added.
 35
1362013-09-11 Simon Fraser <simon.fraser@apple.com>
237
338 Make sure that layout is up-to-date when moving a WKView into a window, to avoid !needsLayout() assertions in RenderView::paint()

Source/WebKit2/PlatformEfl.cmake

@@list(APPEND WebKit2_SOURCES
106106 UIProcess/efl/ContextHistoryClientEfl.cpp
107107 UIProcess/efl/ContextMenuClientEfl.cpp
108108 UIProcess/efl/DownloadManagerEfl.cpp
 109 UIProcess/efl/EasingCurves.cpp
109110 UIProcess/efl/EwkTouchEvent.cpp
110111 UIProcess/efl/EwkTouchPoint.cpp
111112 UIProcess/efl/FindClientEfl.cpp

Source/WebKit2/UIProcess/API/efl/EwkView.cpp

@@void EwkView::didFindZoomableArea(const WKPoint& point, const WKRect& area)
13941394 UNUSED_PARAM(area);
13951395}
13961396
 1397bool EwkView::scrollBy(const IntSize& offset)
 1398{
 1399 WKPoint oldPosition = WKViewGetContentPosition(wkView());
 1400 FloatPoint newPosition(oldPosition.x + offset.width(), oldPosition.y + offset.height());
 1401
 1402 // Update new position to the PageViewportController.
 1403 float contentScale = WKViewGetContentScaleFactor(wkView());
 1404 newPosition.scale(1 / contentScale, 1 / contentScale);
 1405 newPosition = m_pageViewportController->boundContentsPositionAtScale(newPosition, contentScale);
 1406 m_pageViewportController->didChangeContentsVisibility(newPosition, contentScale);
 1407
 1408 // Update new position to the WKView.
 1409 WKPoint position = WKPointMake(newPosition.x() * contentScale, newPosition.y() * contentScale);
 1410 WKViewSetContentPosition(wkView(), position);
 1411
 1412 // If the page position has not changed, notify the caller using the return value.
 1413 return !(oldPosition == position);
 1414}
 1415
13971416Evas_Smart_Class EwkView::parentSmartClass = EVAS_SMART_CLASS_INIT_NULL;
13981417
13991418// Free Ewk View functions.

Source/WebKit2/UIProcess/API/efl/EwkView.h

@@public:
202202 void informURLChange();
203203
204204 PassRefPtr<cairo_surface_t> takeSnapshot();
 205 bool scrollBy(const WebCore::IntSize&);
205206
206207 void didFindZoomableArea(const WKPoint&, const WKRect&);
207208

Source/WebKit2/UIProcess/API/efl/GestureRecognizer.cpp

2727#include "config.h"
2828#include "GestureRecognizer.h"
2929
 30#include "EasingCurves.h"
3031#include "EwkView.h"
3132#include "NotImplemented.h"
3233#include "WKSharedAPICast.h"

@@public:
4344 {
4445 return adoptPtr(new GestureHandler(ewkView));
4546 }
 47 ~GestureHandler();
4648
47  void handleSingleTap(const WebCore::IntPoint&);
48  void handleDoubleTap(const WebCore::IntPoint&);
49  void handleTapAndHold(const WebCore::IntPoint&);
50  void handlePanStarted(const WebCore::IntPoint&);
51  void handlePan(const WebCore::IntPoint&);
 49 EwkView* view() { return m_ewkView; }
 50
 51 void reset();
 52 void handleSingleTap(const IntPoint&);
 53 void handleDoubleTap(const IntPoint&);
 54 void handleTapAndHold(const IntPoint&);
 55 void handlePanStarted(const IntPoint&);
 56 void handlePan(const IntPoint&);
5257 void handlePanFinished();
53  void handlePinchStarted(const Vector<WebCore::IntPoint>&);
54  void handlePinch(const Vector<WebCore::IntPoint>&);
 58 void handleFlick(const IntSize&);
 59 void handlePinchStarted(const Vector<IntPoint>&);
 60 void handlePinch(const Vector<IntPoint>&);
5561 void handlePinchFinished();
5662
5763private:
5864 explicit GestureHandler(EwkView*);
5965
 66 static Eina_Bool panAnimatorCallback(void*);
 67 static Eina_Bool flickAnimatorCallback(void*);
 68
 69 static const int s_historyCapacity = 5;
 70
6071 EwkView* m_ewkView;
 72 IntPoint m_lastPoint;
 73 IntPoint m_currentPoint;
 74 bool m_isCurrentPointUpdated;
 75 Ecore_Animator* m_panAnimator;
 76 Ecore_Animator* m_flickAnimator;
 77 IntSize m_flickOffset;
 78 unsigned m_flickDuration;
 79 unsigned m_flickIndex;
 80
 81 struct HistoryItem {
 82 IntPoint point;
 83 double timestamp;
 84 };
 85 Vector<HistoryItem> m_history;
 86 size_t m_oldestHistoryItemIndex;
6187};
6288
6389GestureHandler::GestureHandler(EwkView* ewkView)
6490 : m_ewkView(ewkView)
 91 , m_isCurrentPointUpdated(false)
 92 , m_panAnimator(0)
 93 , m_flickAnimator(0)
 94 , m_flickDuration(0)
 95 , m_flickIndex(0)
 96 , m_oldestHistoryItemIndex(0)
6597{
 98 m_history.reserveInitialCapacity(s_historyCapacity);
 99}
 100
 101GestureHandler::~GestureHandler()
 102{
 103 reset();
 104}
 105
 106void GestureHandler::reset()
 107{
 108 if (m_panAnimator) {
 109 ecore_animator_del(m_panAnimator);
 110 m_panAnimator = 0;
 111
 112 m_oldestHistoryItemIndex = 0;
 113 m_history.resize(0);
 114 }
 115
 116 if (m_flickAnimator) {
 117 ecore_animator_del(m_flickAnimator);
 118 m_flickAnimator = 0;
 119 }
66120}
67121
68122void GestureHandler::handleSingleTap(const IntPoint&)

@@void GestureHandler::handleTapAndHold(const IntPoint&)
80134 notImplemented();
81135}
82136
83 void GestureHandler::handlePanStarted(const IntPoint&)
 137Eina_Bool GestureHandler::panAnimatorCallback(void* data)
84138{
85  notImplemented();
 139 GestureHandler* gestureHandler = static_cast<GestureHandler*>(data);
 140 if (!gestureHandler->m_isCurrentPointUpdated || gestureHandler->m_lastPoint == gestureHandler->m_currentPoint)
 141 return ECORE_CALLBACK_RENEW;
 142
 143 gestureHandler->view()->scrollBy(gestureHandler->m_lastPoint - gestureHandler->m_currentPoint);
 144 gestureHandler->m_lastPoint = gestureHandler->m_currentPoint;
 145 gestureHandler->m_isCurrentPointUpdated = false;
 146
 147 return ECORE_CALLBACK_RENEW;
86148}
87149
88 void GestureHandler::handlePan(const IntPoint&)
 150void GestureHandler::handlePanStarted(const IntPoint& point)
89151{
90  notImplemented();
 152 ASSERT(!m_panAnimator);
 153 m_panAnimator = ecore_animator_add(panAnimatorCallback, this);
 154 m_lastPoint = m_currentPoint = point;
 155}
 156
 157void GestureHandler::handlePan(const IntPoint& point)
 158{
 159 m_currentPoint = point;
 160 m_isCurrentPointUpdated = true;
 161
 162 // Save current point to use to calculate offset of flick.
 163 HistoryItem item = { m_currentPoint, ecore_time_get() };
 164 if (m_history.size() < m_history.capacity())
 165 m_history.uncheckedAppend(item);
 166 else {
 167 m_history[m_oldestHistoryItemIndex++] = item;
 168 if (m_oldestHistoryItemIndex == m_history.capacity())
 169 m_oldestHistoryItemIndex = 0;
 170 }
91171}
92172
93173void GestureHandler::handlePanFinished()
94174{
95  notImplemented();
 175 ASSERT(m_panAnimator);
 176 ecore_animator_del(m_panAnimator);
 177 m_panAnimator = 0;
 178
 179 if (!m_history.isEmpty()) {
 180 // Calculate offset to move during one frame.
 181 const HistoryItem& firstHistoryItem = m_history[m_oldestHistoryItemIndex];
 182 double frame = (ecore_time_get() - firstHistoryItem.timestamp) / ecore_animator_frametime_get();
 183 IntSize offset = firstHistoryItem.point - m_currentPoint;
 184 offset.scale(1 / frame);
 185 handleFlick(offset);
 186 }
 187
 188 m_oldestHistoryItemIndex = 0;
 189 m_history.resize(0);
 190}
 191
 192Eina_Bool GestureHandler::flickAnimatorCallback(void* data)
 193{
 194 GestureHandler* gestureHandler = static_cast<GestureHandler*>(data);
 195 float multiplier = easeInOutQuad(gestureHandler->m_flickIndex, 0, 1.0, gestureHandler->m_flickDuration);
 196 float offsetWidth = gestureHandler->m_flickOffset.width() * multiplier;
 197 float offsetHeight = gestureHandler->m_flickOffset.height() * multiplier;
 198 offsetWidth = (offsetWidth > 0) ? ceilf(offsetWidth) : floorf(offsetWidth);
 199 offsetHeight = (offsetHeight > 0) ? ceilf(offsetHeight) : floorf(offsetHeight);
 200 IntSize offset(offsetWidth, offsetHeight);
 201 gestureHandler->m_flickIndex--;
 202
 203 if (offset.isZero() || !gestureHandler->view()->scrollBy(offset) || !gestureHandler->m_flickIndex) {
 204 gestureHandler->m_flickAnimator = 0;
 205 return ECORE_CALLBACK_CANCEL;
 206 }
 207
 208 return ECORE_CALLBACK_RENEW;
 209}
 210
 211void GestureHandler::handleFlick(const IntSize& offset)
 212{
 213 m_flickOffset = offset;
 214 m_flickIndex = m_flickDuration = 1 / ecore_animator_frametime_get();
 215 m_flickAnimator = ecore_animator_add(flickAnimatorCallback, this);
96216}
97217
98218void GestureHandler::handlePinchStarted(const Vector<IntPoint>&)

@@void GestureRecognizer::noGesture(WKEventType type, WKArrayRef touchPoints)
196316{
197317 switch (type) {
198318 case kWKEventTypeTouchStart:
 319 m_gestureHandler->reset();
 320
199321 m_recognizerFunction = &GestureRecognizer::singleTapGesture;
200322 m_firstPressedPoint = toIntPoint(getPointAtIndex(touchPoints, 0));
201323 ASSERT(!m_tapAndHoldTimer);

@@void GestureRecognizer::pinchGesture(WKEventType type, WKArrayRef touchPoints)
340462void GestureRecognizer::reset()
341463{
342464 stopTapTimers();
 465 m_gestureHandler->reset();
343466
344467 m_recognizerFunction = &GestureRecognizer::noGesture;
345468}

Source/WebKit2/UIProcess/efl/EasingCurves.cpp

 1/*
 2 * Copyright (C) 2001 Robert Penner. All rights reserved.
 3 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
 4 *
 5 * Redistribution and use in source and binary forms, with or without
 6 * modification, are permitted provided that the following conditions
 7 * are met:
 8 * 1. Redistributions of source code must retain the above copyright
 9 * notice, this list of conditions and the following disclaimer.
 10 * 2. Redistributions in binary form must reproduce the above copyright
 11 * notice, this list of conditions and the following disclaimer in the
 12 * documentation and/or other materials provided with the distribution.
 13 * 3. Neither the name of the author nor the names of contributors may be
 14 * used to endorse or promote products derived from this software
 15 * without specific prior written permission.
 16 *
 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"AS IS"
 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 27 * POSSIBILITY OF SUCH DAMAGE.
 28 */
 29
 30/*
 31 * Robert Penner's easing equations. http://www.robertpenner.com/easing/
 32 * static function easeInOutQuad (t:Number, b:Number, c:Number, d:Number):Number {
 33 * if ((t/=d/2) < 1) return c/2*t*t + b;
 34 * return -c/2 * ((--t)*(t-2) - 1) + b;
 35 * }
 36 */
 37namespace WebKit {
 38
 39float easeInOutQuad(float time, const float base, const float constant, const unsigned duration)
 40{
 41 if (time > duration || time < 0)
 42 return 0;
 43
 44 if ((time /= (duration / 2)) < 1)
 45 return (constant / 2) * time * time + base;
 46
 47 time -= 1;
 48 return -1 * (constant / 2) * (time * (time - 2) - 1) + base;
 49}
 50
 51} // namespace WebKit

Source/WebKit2/UIProcess/efl/EasingCurves.h

 1/*
 2 * Copyright (C) 2001 Robert Penner. All rights reserved.
 3 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
 4 *
 5 * Redistribution and use in source and binary forms, with or without
 6 * modification, are permitted provided that the following conditions
 7 * are met:
 8 * 1. Redistributions of source code must retain the above copyright
 9 * notice, this list of conditions and the following disclaimer.
 10 * 2. Redistributions in binary form must reproduce the above copyright
 11 * notice, this list of conditions and the following disclaimer in the
 12 * documentation and/or other materials provided with the distribution.
 13 * 3. Neither the name of the author nor the names of contributors may be
 14 * used to endorse or promote products derived from this software
 15 * without specific prior written permission.
 16 *
 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"AS IS"
 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 27 * POSSIBILITY OF SUCH DAMAGE.
 28 */
 29
 30#ifndef EasingCurves_h
 31#define EasingCurves_h
 32
 33namespace WebKit {
 34
 35float easeInOutQuad(float time, const float base, const float constant, const unsigned duration);
 36
 37} // namespace WebKit
 38
 39#endif // EasingCurves_h