5bfa5922f5c450150e6bd57923bd1eff6eab4bad
[framework/osp/web.git] / src / controls / FWebCtrl_GestureState.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FWebCtrl_GestureState.cpp
20  * @brief               The file contains the definition of _Web class.
21  *
22  * The file contains the definition of _Web class.
23  */
24 #include <Ecore.h>
25 #include <EWebKit2.h>
26 #include <FBaseSysLog.h>
27 #include <FGrpPoint.h>
28 #include <FUi_CoordinateSystemUtils.h>
29 #include <FUi_Control.h>
30 #include <FUi_TouchManager.h>
31 #include <FUi_UiTouchEvent.h>
32 #include "FWebCtrl_GestureState.h"
33 #include "FWebCtrl_Web.h"
34 #include "FWebCtrl_WebImpl.h"
35 #include "FWebCtrl_WebSettingImpl.h"
36
37
38 using namespace Tizen::Base;
39 using namespace Tizen::Graphics;
40 using namespace Tizen::Ui;
41 using namespace Tizen::Web::Controls;
42
43
44 namespace Tizen { namespace Web { namespace Controls
45 {
46
47
48 static const int  FLICK_SCROLL_WEIGHT = 3000;
49 static const double PINCH_ZOOM_FINGER_FACTOR = 1.0;
50 static const double PINCH_ZOOM_DISTANCE_TOLERANCE = 40.0;
51
52
53 void
54 SetGestureEvent(Ewk_Event_Gesture& gestureEvent, Ewk_Gesture_Type gestureType, const Point& absPoint, const Point& velocity, double scale, int count)
55 {
56         gestureEvent.type = gestureType;
57         gestureEvent.position.x = absPoint.x;
58         gestureEvent.position.y = absPoint.y;
59         gestureEvent.velocity.x = velocity.x;
60         gestureEvent.velocity.y = velocity.y;
61         gestureEvent.scale = scale;
62         gestureEvent.count = count;
63         gestureEvent.timestamp = ecore_time_get() * 1000;
64 }
65
66
67 _TapGestureState::_TapGestureState(_Web* pWeb)
68         : __pWebCore(pWeb)
69         , __longPressed(false)
70         , __doubleTapped(false)
71         , __pressedPosition(0.0f, 0.0f)
72 {
73 }
74
75
76 _TapGestureState::~_TapGestureState(void)
77 {
78 }
79         
80
81 bool
82 _TapGestureState::OnLongPressGestureDetected(_TouchLongPressGestureDetector& gesture)
83 {
84         //To disable focus ring
85         Ewk_Event_Gesture gestureEvent;
86
87         SetGestureEvent(gestureEvent, EWK_GESTURE_LONG_PRESS, Point(0, 0), Point(0, 0), 0.0, 0);
88
89         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
90         SysAssertf(pSmartData, "Failed to get webkit smart data.");
91         pSmartData->api->gesture_move(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
92
93         //To delete magnifier
94         _TouchManager* pTouchManager = _TouchManager::GetInstance();
95         SysAssertf(pTouchManager, "Failed to get touch manager.");
96
97         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(pTouchManager->GetPosition(pTouchManager->GetCurrentPointId())));
98
99         Ewk_Touch_Point* pPoint = static_cast< Ewk_Touch_Point* >(calloc(1, sizeof(Ewk_Touch_Point)));
100         pPoint->id = 0;
101         pPoint->x = absPoint.x;
102         pPoint->y = absPoint.y;
103         pPoint->state = EVAS_TOUCH_POINT_CANCEL;
104
105         Eina_List* pPointList = null;
106         pPointList = eina_list_append(pPointList, pPoint);
107
108         ewk_view_feed_touch_event(__pWebCore->GetWebNativeNode(), EWK_TOUCH_CANCEL, pPointList, null);
109
110         void* pData = null;
111         EINA_LIST_FREE(pPointList, pData)
112         free(pData);
113
114         __longPressed = true;
115
116         return true;
117 }
118
119
120 bool
121 _TapGestureState::OnTapGestureDetected(_TouchTapGestureDetector& gesture)
122 {
123         __doubleTapped = true;
124
125         return true;
126 }
127
128
129 bool
130 _TapGestureState::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
131 {
132         Ewk_Event_Gesture gestureEvent;
133         __pressedPosition = touchInfo.GetCurrentPosition();
134         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(__pressedPosition)));
135
136         SetGestureEvent(gestureEvent, EWK_GESTURE_TAP, absPoint, Point(0, 0), 0.0, 1);
137
138         const Ewk_View_Smart_Data* pSmartData = static_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
139         SysAssertf(pSmartData, "Failed to get webkit smart data.");
140         pSmartData->api->gesture_start(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
141
142         __longPressed = false;
143         __doubleTapped = false;
144
145         return true;
146 }
147
148
149 bool
150 _TapGestureState::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
151 {
152         Ewk_Event_Gesture gestureEvent;
153         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(touchInfo.GetCurrentPosition())));
154
155         SetGestureEvent(gestureEvent, EWK_GESTURE_PAN, absPoint, Point(0, 0), 0.0, 0);
156
157         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
158         SysAssertf(pSmartData, "Failed to get webkit smart data.");
159         pSmartData->api->gesture_start(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
160
161         __pWebCore->ChangeGesture(WEB_GESTURE_TYPE_PANNING);
162
163         if (!_WebSettingImpl::GetInstance(__pWebCore->GetSetting())->IsScrollEnabled())
164         {
165                 return false;
166         }
167
168         return true;
169 }
170
171
172 bool
173 _TapGestureState::OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
174 {
175         if (!__pWebCore->Contains(__pressedPosition))
176         {
177                 return OnTouchCanceled(source, touchInfo);
178         }
179         
180         Evas_Object* pView = __pWebCore->GetWebNativeNode();
181         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(__pressedPosition)));
182
183         if (__longPressed)
184         {
185                 Ewk_Hit_Test* pEwkHitTest = ewk_view_hit_test_new(pView, absPoint.x, absPoint.y, EWK_HIT_TEST_MODE_ALL);
186                 SysTryReturn(NID_WEB_CTRL, pEwkHitTest, true, E_SYSTEM, "Failed to get hit test.");
187
188                 String tagName(ewk_hit_test_tag_name_get(pEwkHitTest));
189
190                 Eina_Hash* pAttrHash = ewk_hit_test_attribute_hash_get(pEwkHitTest);
191                 char* pValue = reinterpret_cast< char* >(eina_hash_find(pAttrHash, "contenteditable"));
192                 if (tagName.Equals(L"INPUT", false) || tagName.Equals(L"TEXTAREA", false) || pValue)
193                 {
194                         Eina_Rectangle leftHandle;
195                         Eina_Rectangle rightHandle;
196
197                         ewk_view_text_selection_range_get(pView, &leftHandle, &rightHandle);
198                         if (((rightHandle.x + rightHandle.w) == 0) && ((rightHandle.y + rightHandle.h) == 0))
199                         {
200                                 Ewk_Event_Gesture gestureEvent;
201
202                                 SetGestureEvent(gestureEvent, EWK_GESTURE_LONG_PRESS, absPoint, Point(0, 0), 0.0, 1);
203
204                                 const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(pView));
205                                 SysAssertf(pSmartData, "Failed to get webkit smart data.");
206                                 pSmartData->api->gesture_end(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
207                         }
208                 }
209         }
210         else
211         {
212                 Ewk_Event_Gesture gestureEvent;
213                 int touchCount = 1;
214                 if (__doubleTapped)
215                 {
216                         touchCount = 2;
217                 }
218
219                 SetGestureEvent(gestureEvent, EWK_GESTURE_TAP, absPoint, Point(0, 0), 0.0, touchCount);
220
221                 const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(pView));
222                 SysAssertf(pSmartData, "Failed to get webkit smart data.");
223                 pSmartData->api->gesture_end(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
224         }
225
226         return true;
227 }
228
229
230 bool
231 _TapGestureState::OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
232 {
233         Ewk_Event_Gesture gestureEvent;
234
235         SetGestureEvent(gestureEvent, EWK_GESTURE_LONG_PRESS, Point(0, 0), Point(0, 0), 0.0, 0);
236
237         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
238         SysAssertf(pSmartData, "Failed to get webkit smart data.");
239         pSmartData->api->gesture_move(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
240
241         return true;
242 }
243
244
245 _PanningGestureState::_PanningGestureState(_Web* pWeb)
246         : __pWebCore(pWeb)
247 {
248 }
249
250
251 _PanningGestureState::~_PanningGestureState(void)
252 {
253 }
254
255
256 bool
257 _PanningGestureState::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
258 {
259         return true;
260 }
261
262
263 bool
264 _PanningGestureState::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
265 {
266         if (!_WebSettingImpl::GetInstance(__pWebCore->GetSetting())->IsScrollEnabled())
267         {
268                 return false;
269         }
270
271         Ewk_Event_Gesture gestureEvent;
272         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(touchInfo.GetCurrentPosition())));
273
274         SetGestureEvent(gestureEvent, EWK_GESTURE_PAN, absPoint, Point(0, 0), 0.0, 0);
275
276         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
277         SysAssertf(pSmartData, "Failed to get webkit smart data.");
278         pSmartData->api->gesture_move(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
279
280         return true;
281 }
282
283
284 bool
285 _PanningGestureState::OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
286 {
287         Ewk_Event_Gesture gestureEvent;
288         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(touchInfo.GetCurrentPosition())));
289
290         SetGestureEvent(gestureEvent, EWK_GESTURE_PAN, absPoint, Point(0, 0), 0.0, 0);
291
292         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
293         SysAssertf(pSmartData, "Failed to get webkit smart data.");
294         pSmartData->api->gesture_end(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
295
296         __pWebCore->ChangeGesture(WEB_GESTURE_TYPE_TAP);
297
298         return true;
299 }
300
301
302 bool
303 _PanningGestureState::OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
304 {
305         return OnTouchReleased(source, touchInfo);
306 }
307
308
309 _FlickGestureState::_FlickGestureState(_Web* pWeb)
310         : __pWebCore(pWeb)
311         , __velocity(0, 0)
312 {
313 }
314
315
316 _FlickGestureState::~_FlickGestureState(void)
317 {
318 }
319
320
321 bool
322 _FlickGestureState::OnFlickGestureDetected(_TouchFlickGestureDetector& gesture)
323 {
324         __pWebCore->ChangeGesture(WEB_GESTURE_TYPE_FLICK);
325
326         if (_WebSettingImpl::GetInstance(__pWebCore->GetSetting())->IsScrollEnabled())
327         {
328                 int duration = gesture.GetDuration();
329                 gesture.GetDistance(__velocity.x, __velocity.y);
330
331                 __velocity.x = (__velocity.x * FLICK_SCROLL_WEIGHT) / duration;
332                 __velocity.y = (__velocity.y * FLICK_SCROLL_WEIGHT) / duration;
333         }
334
335         return true;
336 }
337
338
339 bool
340 _FlickGestureState::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
341 {
342         return true;
343 }
344
345
346 bool
347 _FlickGestureState::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
348 {
349         return true;
350 }
351
352
353 bool
354 _FlickGestureState::OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
355 {
356         Ewk_Event_Gesture gestureEvent;
357         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(touchInfo.GetCurrentPosition())));
358
359         SetGestureEvent(gestureEvent, EWK_GESTURE_PAN, absPoint, Point(0, 0), 0.0, 0);
360
361         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
362         SysAssertf(pSmartData, "Failed to get webkit smart data.");
363         pSmartData->api->gesture_end(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
364
365         if (_WebSettingImpl::GetInstance(__pWebCore->GetSetting())->IsScrollEnabled())
366         {
367                 SetGestureEvent(gestureEvent, EWK_GESTURE_FLICK, absPoint, __velocity, 0.0, 0);
368
369                 pSmartData->api->gesture_start(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
370         }
371
372         __pWebCore->ChangeGesture(WEB_GESTURE_TYPE_TAP);
373
374         return true;
375 }
376
377
378 bool
379 _FlickGestureState::OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
380 {
381         return OnTouchPressed(source, touchInfo);
382 }
383
384
385 _PinchGestureState::_PinchGestureState(_Web* pWeb)
386         : __pWebCore(pWeb)
387         , __standardScale(0.0)
388 {
389 }
390
391
392 _PinchGestureState::~_PinchGestureState(void)
393 {
394 }
395
396
397 bool
398 _PinchGestureState::OnPinchGestureStarted(_TouchPinchGestureDetector& gesture)
399 {
400         __pWebCore->ChangeGesture(WEB_GESTURE_TYPE_PINCH);
401
402         Ewk_Event_Gesture gestureEvent;
403         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(gesture.GetCenterPointF())));
404         __standardScale = static_cast< double >(gesture.GetScaleF());
405
406         SetGestureEvent(gestureEvent, EWK_GESTURE_PINCH, absPoint, Point(0, 0), 1.0, 0);
407
408         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
409         SysAssertf(pSmartData, "Failed to get webkit smart data.");
410         pSmartData->api->gesture_start(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
411
412         return true;
413 }
414
415
416 bool
417 _PinchGestureState::OnPinchGestureChanged(_TouchPinchGestureDetector& gesture)
418 {
419         Ewk_Event_Gesture gestureEvent;
420         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(gesture.GetCenterPointF())));
421         double relScale = static_cast< double >(gesture.GetScaleF()) /__standardScale;
422
423         SetGestureEvent(gestureEvent, EWK_GESTURE_PINCH, absPoint, Point(0, 0), relScale, 0);
424
425         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
426         SysAssertf(pSmartData, "Failed to get webkit smart data.");
427         pSmartData->api->gesture_move(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
428
429         return true;
430 }
431
432
433 bool
434 _PinchGestureState::OnPinchGestureFinished(_TouchPinchGestureDetector& gesture)
435 {
436         Ewk_Event_Gesture gestureEvent;
437
438         SetGestureEvent(gestureEvent, EWK_GESTURE_PINCH, Point(0, 0), Point(0, 0), 0.0, 0);
439
440         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
441         SysAssertf(pSmartData, "Failed to get webkit smart data.");
442         pSmartData->api->gesture_end(const_cast<Ewk_View_Smart_Data*>(pSmartData), &gestureEvent);
443
444         return true;
445 }
446
447
448 bool
449 _PinchGestureState::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
450 {
451         return true;
452 }
453
454
455 bool
456 _PinchGestureState::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
457 {
458         return true;
459 }
460
461
462 bool
463 _PinchGestureState::OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
464 {
465         _TouchManager* pTouchManager = _TouchManager::GetInstance();
466         SysAssertf(pTouchManager, "Failed to get touch manager.");
467         if(pTouchManager->GetPointCount() == 0)
468         {
469                 __pWebCore->ChangeGesture(WEB_GESTURE_TYPE_TAP);
470         }
471
472         return true;
473 }
474
475
476 bool
477 _PinchGestureState::OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
478 {
479         Ewk_Event_Gesture gestureEvent;
480
481         SetGestureEvent(gestureEvent, EWK_GESTURE_PINCH, Point(0, 0), Point(0, 0), 0.0, 0);
482
483         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
484         SysAssertf(pSmartData, "Failed to get webkit smart data.");
485         pSmartData->api->gesture_end(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
486
487         __pWebCore->ChangeGesture(WEB_GESTURE_TYPE_TAP);
488
489         return true;
490 }
491
492
493 }}}