Initialize Tizen 2.3
[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 <FBaseRtTimer.h>
27 #include <FBaseSysLog.h>
28 #include <FGrpPoint.h>
29 #include <FUi_CoordinateSystemUtils.h>
30 #include <FUi_Control.h>
31 #include <FUi_TouchManager.h>
32 #include <FUi_UiTouchEvent.h>
33 #include "FWebCtrl_GestureState.h"
34 #include "FWebCtrl_Web.h"
35 #include "FWebCtrl_WebImpl.h"
36 #include "FWebCtrl_WebSettingImpl.h"
37
38
39 using namespace Tizen::Base;
40 using namespace Tizen::Base::Runtime;
41 using namespace Tizen::Graphics;
42 using namespace Tizen::Ui;
43 using namespace Tizen::Web::Controls;
44
45
46 namespace Tizen { namespace Web { namespace Controls
47 {
48
49
50 static const int  FLICK_SCROLL_WEIGHT = 3000;
51 static const double PINCH_ZOOM_FINGER_FACTOR = 1.0;
52 static const double PINCH_ZOOM_DISTANCE_TOLERANCE = 40.0;
53
54
55 void
56 SetGestureEvent(Ewk_Event_Gesture& gestureEvent, Ewk_Gesture_Type gestureType, const Point& absPoint, const Point& velocity, double scale, int count)
57 {
58         gestureEvent.type = gestureType;
59         gestureEvent.position.x = absPoint.x;
60         gestureEvent.position.y = absPoint.y;
61         gestureEvent.velocity.x = velocity.x;
62         gestureEvent.velocity.y = velocity.y;
63         gestureEvent.scale = scale;
64         gestureEvent.count = count;
65         gestureEvent.timestamp = ecore_time_get() * 1000;
66 }
67
68
69 _TapGestureState::_TapGestureState(_Web* pWeb)
70         : __pWebCore(pWeb)
71         , __longPressed(false)
72         , __doubleTapped(false)
73         , __pressed(false)
74         , __released(false)
75         , __pressedPosition(0.0f, 0.0f)
76 {
77         __timer.Construct(*this);
78 }
79
80
81 _TapGestureState::~_TapGestureState(void)
82 {
83 }
84         
85
86 bool
87 _TapGestureState::OnLongPressGestureDetected(_TouchLongPressGestureDetector& gesture)
88 {
89         if (__pressed == false)
90         {
91                 LongPressTouch();
92         }
93
94         __longPressed = true;
95
96         return true;
97 }
98
99
100 bool
101 _TapGestureState::OnTapGestureDetected(_TouchTapGestureDetector& gesture)
102 {
103         __doubleTapped = true;
104
105         return true;
106 }
107
108
109 void
110 _TapGestureState::PressTouch(void)
111 {
112         Ewk_Event_Gesture gestureEvent;
113         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(__pressedPosition)));
114
115         SetGestureEvent(gestureEvent, EWK_GESTURE_TAP, absPoint, Point(0, 0), 0.0, 1);
116
117         const Ewk_View_Smart_Data* pSmartData = static_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
118         SysAssertf(pSmartData, "Failed to get webkit smart data.");
119         pSmartData->api->gesture_start(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
120 }
121
122
123 void
124 _TapGestureState::ReleaseTouch(void)
125 {
126         __released = false;
127
128         if (!__pWebCore->Contains(__pressedPosition))
129         {
130                 _TouchInfo dummyTouchInfo;
131                 OnTouchCanceled(*__pWebCore, dummyTouchInfo);
132                 return;
133         }
134
135         Evas_Object* pView = __pWebCore->GetWebNativeNode();
136         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(__pressedPosition)));
137
138         if (__longPressed)
139         {
140                 Ewk_Hit_Test* pEwkHitTest = ewk_view_hit_test_new(pView, absPoint.x, absPoint.y, EWK_HIT_TEST_MODE_ALL);
141                 SysTryReturnVoidResult(NID_WEB_CTRL, pEwkHitTest, E_SYSTEM, "Failed to get hit test.");
142
143                 String tagName(ewk_hit_test_tag_name_get(pEwkHitTest));
144
145                 Eina_Hash* pAttrHash = ewk_hit_test_attribute_hash_get(pEwkHitTest);
146                 char* pValue = reinterpret_cast< char* >(eina_hash_find(pAttrHash, "contenteditable"));
147                 if (tagName.Equals(L"INPUT", false) || tagName.Equals(L"TEXTAREA", false) || pValue)
148                 {
149                         Eina_Rectangle leftHandle;
150                         Eina_Rectangle rightHandle;
151
152                         ewk_view_text_selection_range_get(pView, &leftHandle, &rightHandle);
153                         if (((rightHandle.x + rightHandle.w) == 0) && ((rightHandle.y + rightHandle.h) == 0))
154                         {
155                                 Ewk_Event_Gesture gestureEvent;
156
157                                 SetGestureEvent(gestureEvent, EWK_GESTURE_LONG_PRESS, absPoint, Point(0, 0), 0.0, 1);
158
159                                 const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(pView));
160                                 SysAssertf(pSmartData, "Failed to get webkit smart data.");
161                                 pSmartData->api->gesture_end(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
162                         }
163                 }
164         }
165         else
166         {
167                 Ewk_Event_Gesture gestureEvent;
168                 int touchCount = 1;
169                 if (__doubleTapped)
170                 {
171                         touchCount = 2;
172                 }
173
174                 SetGestureEvent(gestureEvent, EWK_GESTURE_TAP, absPoint, Point(0, 0), 0.0, touchCount);
175
176                 const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(pView));
177                 SysAssertf(pSmartData, "Failed to get webkit smart data.");
178                 pSmartData->api->gesture_end(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
179         }
180 }
181
182
183 void
184 _TapGestureState::LongPressTouch(void)
185 {
186         //To disable focus ring
187         Ewk_Event_Gesture gestureEvent;
188
189         SetGestureEvent(gestureEvent, EWK_GESTURE_LONG_PRESS, Point(0, 0), Point(0, 0), 0.0, 0);
190
191         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
192         SysAssertf(pSmartData, "Failed to get webkit smart data.");
193         pSmartData->api->gesture_move(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
194 }
195
196
197 bool
198 _TapGestureState::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
199 {
200         __pressedPosition = touchInfo.GetCurrentPosition();
201
202         if (__pressed == false)
203         {
204                 __timer.Start(400);
205
206                 __longPressed = false;
207                 __doubleTapped = false;
208                 __pressed = true;
209
210                 PressTouch();
211         }
212         else
213         {
214                 __timer.Cancel();
215
216                 __pressed = false;
217         }
218
219         return true;
220 }
221
222
223 bool
224 _TapGestureState::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
225 {
226         Ewk_Event_Gesture gestureEvent;
227         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(touchInfo.GetCurrentPosition())));
228
229         SetGestureEvent(gestureEvent, EWK_GESTURE_PAN, absPoint, Point(0, 0), 0.0, 0);
230
231         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
232         SysAssertf(pSmartData, "Failed to get webkit smart data.");
233         pSmartData->api->gesture_start(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
234
235         __pWebCore->ChangeGesture(WEB_GESTURE_TYPE_PANNING);
236
237         if (!_WebSettingImpl::GetInstance(__pWebCore->GetSetting())->IsScrollEnabled())
238         {
239                 return false;
240         }
241
242         return true;
243 }
244
245
246 bool
247 _TapGestureState::OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
248 {
249         __released = true;
250
251         if (__pressed == true)
252         {
253                 return true;
254         }
255
256         ReleaseTouch();
257
258         return true;
259 }
260
261
262 bool
263 _TapGestureState::OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
264 {
265         Ewk_Event_Gesture gestureEvent;
266
267         SetGestureEvent(gestureEvent, EWK_GESTURE_LONG_PRESS, Point(0, 0), Point(0, 0), 0.0, 0);
268
269         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
270         SysAssertf(pSmartData, "Failed to get webkit smart data.");
271         pSmartData->api->gesture_move(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
272
273         return true;
274 }
275
276
277 void
278 _TapGestureState::OnTimerExpired(Timer& timer)
279 {
280         if (__longPressed == false)
281         {
282                 __pressed = false;
283
284                 if (__released == true)
285                 {
286                         ReleaseTouch();
287                 }
288         }
289 }
290
291
292 _PanningGestureState::_PanningGestureState(_Web* pWeb)
293         : __pWebCore(pWeb)
294 {
295 }
296
297
298 _PanningGestureState::~_PanningGestureState(void)
299 {
300 }
301
302
303 bool
304 _PanningGestureState::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
305 {
306         return true;
307 }
308
309
310 bool
311 _PanningGestureState::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
312 {
313         if (!_WebSettingImpl::GetInstance(__pWebCore->GetSetting())->IsScrollEnabled())
314         {
315                 return false;
316         }
317
318         Ewk_Event_Gesture gestureEvent;
319         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(touchInfo.GetCurrentPosition())));
320
321         SetGestureEvent(gestureEvent, EWK_GESTURE_PAN, absPoint, Point(0, 0), 0.0, 0);
322
323         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
324         SysAssertf(pSmartData, "Failed to get webkit smart data.");
325         pSmartData->api->gesture_move(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
326
327         return true;
328 }
329
330
331 bool
332 _PanningGestureState::OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
333 {
334         Ewk_Event_Gesture gestureEvent;
335         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(touchInfo.GetCurrentPosition())));
336
337         SetGestureEvent(gestureEvent, EWK_GESTURE_PAN, absPoint, Point(0, 0), 0.0, 0);
338
339         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
340         SysAssertf(pSmartData, "Failed to get webkit smart data.");
341         pSmartData->api->gesture_end(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
342
343         __pWebCore->ChangeGesture(WEB_GESTURE_TYPE_TAP);
344
345         return true;
346 }
347
348
349 bool
350 _PanningGestureState::OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
351 {
352         return OnTouchReleased(source, touchInfo);
353 }
354
355
356 _FlickGestureState::_FlickGestureState(_Web* pWeb)
357         : __pWebCore(pWeb)
358         , __velocity(0, 0)
359 {
360 }
361
362
363 _FlickGestureState::~_FlickGestureState(void)
364 {
365 }
366
367
368 bool
369 _FlickGestureState::OnFlickGestureDetected(_TouchFlickGestureDetector& gesture)
370 {
371         __pWebCore->ChangeGesture(WEB_GESTURE_TYPE_FLICK);
372
373         if (_WebSettingImpl::GetInstance(__pWebCore->GetSetting())->IsScrollEnabled())
374         {
375                 int duration = gesture.GetDuration();
376                 gesture.GetDistance(__velocity.x, __velocity.y);
377
378                 __velocity.x = (__velocity.x * FLICK_SCROLL_WEIGHT) / duration;
379                 __velocity.y = (__velocity.y * FLICK_SCROLL_WEIGHT) / duration;
380         }
381
382         return true;
383 }
384
385
386 bool
387 _FlickGestureState::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
388 {
389         return true;
390 }
391
392
393 bool
394 _FlickGestureState::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
395 {
396         return true;
397 }
398
399
400 bool
401 _FlickGestureState::OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
402 {
403         Ewk_Event_Gesture gestureEvent;
404         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(touchInfo.GetCurrentPosition())));
405
406         SetGestureEvent(gestureEvent, EWK_GESTURE_PAN, absPoint, Point(0, 0), 0.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_end(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
411
412         if (_WebSettingImpl::GetInstance(__pWebCore->GetSetting())->IsScrollEnabled())
413         {
414                 SetGestureEvent(gestureEvent, EWK_GESTURE_FLICK, absPoint, __velocity, 0.0, 0);
415
416                 pSmartData->api->gesture_start(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
417         }
418
419         __pWebCore->ChangeGesture(WEB_GESTURE_TYPE_TAP);
420
421         return true;
422 }
423
424
425 bool
426 _FlickGestureState::OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
427 {
428         return OnTouchPressed(source, touchInfo);
429 }
430
431
432 _PinchGestureState::_PinchGestureState(_Web* pWeb)
433         : __pWebCore(pWeb)
434         , __standardScale(0.0)
435 {
436 }
437
438
439 _PinchGestureState::~_PinchGestureState(void)
440 {
441 }
442
443
444 bool
445 _PinchGestureState::OnPinchGestureStarted(_TouchPinchGestureDetector& gesture)
446 {
447         __pWebCore->ChangeGesture(WEB_GESTURE_TYPE_PINCH);
448
449         Ewk_Event_Gesture gestureEvent;
450         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(gesture.GetCenterPointF())));
451         __standardScale = static_cast< double >(gesture.GetScaleF());
452
453         SetGestureEvent(gestureEvent, EWK_GESTURE_PINCH, absPoint, Point(0, 0), 1.0, 0);
454
455         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
456         SysAssertf(pSmartData, "Failed to get webkit smart data.");
457         pSmartData->api->gesture_start(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
458
459         return true;
460 }
461
462
463 bool
464 _PinchGestureState::OnPinchGestureChanged(_TouchPinchGestureDetector& gesture)
465 {
466         Ewk_Event_Gesture gestureEvent;
467         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(__pWebCore->GetAbsoluteCoordinate(gesture.GetCenterPointF())));
468         double relScale = static_cast< double >(gesture.GetScaleF()) /__standardScale;
469
470         SetGestureEvent(gestureEvent, EWK_GESTURE_PINCH, absPoint, Point(0, 0), relScale, 0);
471
472         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
473         SysAssertf(pSmartData, "Failed to get webkit smart data.");
474         pSmartData->api->gesture_move(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
475
476         return true;
477 }
478
479
480 bool
481 _PinchGestureState::OnPinchGestureFinished(_TouchPinchGestureDetector& gesture)
482 {
483         Ewk_Event_Gesture gestureEvent;
484
485         SetGestureEvent(gestureEvent, EWK_GESTURE_PINCH, Point(0, 0), Point(0, 0), 0.0, 0);
486
487         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
488         SysAssertf(pSmartData, "Failed to get webkit smart data.");
489         pSmartData->api->gesture_end(const_cast<Ewk_View_Smart_Data*>(pSmartData), &gestureEvent);
490
491         return true;
492 }
493
494
495 bool
496 _PinchGestureState::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
497 {
498         return true;
499 }
500
501
502 bool
503 _PinchGestureState::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
504 {
505         return true;
506 }
507
508
509 bool
510 _PinchGestureState::OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
511 {
512         _TouchManager* pTouchManager = _TouchManager::GetInstance();
513         SysAssertf(pTouchManager, "Failed to get touch manager.");
514         if(pTouchManager->GetPointCount() == 0)
515         {
516                 __pWebCore->ChangeGesture(WEB_GESTURE_TYPE_TAP);
517         }
518
519         return true;
520 }
521
522
523 bool
524 _PinchGestureState::OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
525 {
526         Ewk_Event_Gesture gestureEvent;
527
528         SetGestureEvent(gestureEvent, EWK_GESTURE_PINCH, Point(0, 0), Point(0, 0), 0.0, 0);
529
530         const Ewk_View_Smart_Data* pSmartData = reinterpret_cast< Ewk_View_Smart_Data* >(evas_object_smart_data_get(__pWebCore->GetWebNativeNode()));
531         SysAssertf(pSmartData, "Failed to get webkit smart data.");
532         pSmartData->api->gesture_end(const_cast< Ewk_View_Smart_Data* >(pSmartData), &gestureEvent);
533
534         __pWebCore->ChangeGesture(WEB_GESTURE_TYPE_TAP);
535
536         return true;
537 }
538
539
540 }}}