Fix for text selection issue
[framework/osp/web.git] / src / controls / FWebCtrl_Web.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_Web.cpp
20  * @brief               The file contains the definition of _Web class.
21  *
22  * The file contains the definition of _Web class.
23  */
24 #include <Elementary.h>
25 #include <memory>
26 #include <FBaseByteBuffer.h>
27 #include <FBaseColLinkedListT.h>
28 #include <FBaseSysLog.h>
29 #include <FBaseColIListT.h>
30 #include <FGrpFloatPoint.h>
31 #include <FGrpPoint.h>
32 #include <FGrpBitmap.h>
33 #include <FGrpCanvas.h>
34 #include <FGrpFloatRectangle.h>
35 #include <FSysVibrator.h>
36 #include <FWebCtrlWebSetting.h>
37 #include <FGrp_CoordinateSystem.h>
38 #include <FSys_VibratorImpl.h>
39 #include <FUiAnim_EflNode.h>
40 #include <FUiAnim_VisualElement.h>
41 #include <FUi_CoordinateSystemUtils.h>
42 #include <FUi_AccessibilityContainer.h>
43 #include <FUi_AccessibilityElement.h>
44 #include <FUi_IAccessibilityFocusHandler.h>
45 #include <FUi_IAccessibilityListener.h>
46 #include <FUi_Math.h>
47 #include <FUi_TouchManager.h>
48 #include "FWebCtrl_EflWebkit.h"
49 #include "FWebCtrl_GestureState.h"
50 #include "FWebCtrl_Web.h"
51 #include "FWebCtrl_WebImpl.h"
52 #include "FWebCtrl_WebSettingImpl.h"
53 #include "FWebCtrl_Utility.h"
54
55
56 using namespace Tizen::Base;
57 using namespace Tizen::Base::Collection;
58 using namespace Tizen::Graphics;
59 using namespace Tizen::Ui;
60 using namespace Tizen::Ui::Animations;
61
62
63 namespace
64 {
65
66
67 class _WebAccessibilityListener
68         : public Tizen::Ui::_IAccessibilityListener
69 {
70 public:
71         _WebAccessibilityListener(Evas_Object* pView);
72
73         virtual ~_WebAccessibilityListener(void);
74
75         virtual bool OnAccessibilityFocusMovedNext(const _AccessibilityContainer& control, const _AccessibilityElement& element);
76
77         virtual bool OnAccessibilityFocusMovedPrevious(const _AccessibilityContainer& control, const _AccessibilityElement& element);
78
79         virtual bool OnAccessibilityReadingElement(const _AccessibilityContainer& control, const _AccessibilityElement& element);
80
81         virtual bool OnAccessibilityReadElement(const _AccessibilityContainer& control, const _AccessibilityElement& element);
82
83         virtual bool OnAccessibilityFocusIn(const _AccessibilityContainer& control, const _AccessibilityElement& element);
84
85         virtual bool OnAccessibilityFocusOut(const _AccessibilityContainer& control, const _AccessibilityElement& element);
86
87         virtual bool OnAccessibilityActionPerformed(const _AccessibilityContainer& control, const _AccessibilityElement& element);
88
89         virtual bool OnAccessibilityValueIncreased(const _AccessibilityContainer& control, const _AccessibilityElement& element);
90
91         virtual bool OnAccessibilityValueDecreased(const _AccessibilityContainer& control, const _AccessibilityElement& element);
92
93 private:
94         Evas_Object* __pView;
95 };
96
97
98 _WebAccessibilityListener::_WebAccessibilityListener(Evas_Object* pView)
99         : __pView(pView)
100 {
101 }
102
103
104 _WebAccessibilityListener::~_WebAccessibilityListener(void)
105 {
106 }
107
108
109 bool
110 _WebAccessibilityListener::OnAccessibilityFocusMovedNext(const _AccessibilityContainer& control, const _AccessibilityElement& element)
111 {
112         return true;
113 }
114
115
116 bool
117 _WebAccessibilityListener::OnAccessibilityFocusMovedPrevious(const _AccessibilityContainer& control, const _AccessibilityElement& element)
118 {
119         return true;
120 }
121
122
123 bool
124 _WebAccessibilityListener::OnAccessibilityReadingElement(const _AccessibilityContainer& control, const _AccessibilityElement& element)
125 {
126         return true;
127 }
128
129
130 bool
131 _WebAccessibilityListener::OnAccessibilityReadElement(const _AccessibilityContainer& control, const _AccessibilityElement& element)
132 {
133         return true;
134 }
135
136
137 bool
138 _WebAccessibilityListener::OnAccessibilityFocusIn(const _AccessibilityContainer& control, const _AccessibilityElement& element)
139 {
140         return true;
141 }
142
143
144 bool
145 _WebAccessibilityListener::OnAccessibilityFocusOut(const _AccessibilityContainer& control, const _AccessibilityElement& element)
146 {
147         return true;
148 }
149
150
151 bool
152 _WebAccessibilityListener::OnAccessibilityActionPerformed(const _AccessibilityContainer& control, const _AccessibilityElement& element)
153 {
154         const Ewk_View_Smart_Data* pSmartData = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(__pView));
155         SysAssertf(pSmartData, "Failed to get webkit smart data.");
156
157         Elm_Access_Action_Info* pActionInfo = new Elm_Access_Action_Info();
158         SysTryReturn(NID_WEB_CTRL, pActionInfo, false, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
159
160         bool result = false;
161
162         pActionInfo->action_type = ELM_ACCESS_ACTION_ACTIVATE;
163
164         result = pSmartData->api->screen_reader_action_execute(const_cast<Ewk_View_Smart_Data*>(pSmartData), pActionInfo);
165         delete pActionInfo;
166
167         return result;
168 }
169
170
171 bool
172 _WebAccessibilityListener::OnAccessibilityValueIncreased(const _AccessibilityContainer& control, const _AccessibilityElement& element)
173 {
174         return true;
175 }
176
177
178 bool
179 _WebAccessibilityListener::OnAccessibilityValueDecreased(const _AccessibilityContainer& control, const _AccessibilityElement& element)
180 {
181         return true;
182 }
183
184
185 class _WebAccessibilityFocusHandler
186         : public Tizen::Ui::_IAccessibilityFocusHandler
187 {
188 public:
189         _WebAccessibilityFocusHandler(Evas_Object* pView);
190
191         virtual ~_WebAccessibilityFocusHandler(void);
192
193         virtual bool OnMoveFocus(Tizen::Ui::_AccessibilityFocusDirection direction);
194
195         virtual bool OnMoveFocus(const Tizen::Graphics::Point& point);
196
197 private:
198         Evas_Object* __pView;
199 };
200
201
202 _WebAccessibilityFocusHandler::_WebAccessibilityFocusHandler(Evas_Object* pView)
203         : __pView(pView)
204 {
205 }
206
207
208 _WebAccessibilityFocusHandler::~_WebAccessibilityFocusHandler(void)
209 {
210 }
211
212
213 bool
214 _WebAccessibilityFocusHandler::OnMoveFocus(Tizen::Ui::_AccessibilityFocusDirection direction)
215 {
216         const Ewk_View_Smart_Data* pSmartData = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(__pView));
217         SysAssertf(pSmartData, "Failed to get webkit smart data.");
218
219         Elm_Access_Action_Info* pActionInfo = new Elm_Access_Action_Info();
220         SysTryReturn(NID_WEB_CTRL, pActionInfo, false, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
221
222         bool result = false;
223
224         if (direction == Tizen::Ui::_ACCESSIBILITY_FOCUS_DIRECTION_PREVIOUS)
225         {
226                 pActionInfo->action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
227
228                 result = pSmartData->api->screen_reader_action_execute(const_cast<Ewk_View_Smart_Data*>(pSmartData), pActionInfo);
229         }
230         else if (direction == Tizen::Ui::_ACCESSIBILITY_FOCUS_DIRECTION_NEXT)
231         {
232                 pActionInfo->action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
233
234                 result = pSmartData->api->screen_reader_action_execute(const_cast<Ewk_View_Smart_Data*>(pSmartData), pActionInfo);
235         }
236         delete pActionInfo;
237
238         return result;
239 }
240
241
242 bool
243 _WebAccessibilityFocusHandler::OnMoveFocus(const Tizen::Graphics::Point& point)
244 {
245         const Ewk_View_Smart_Data* pSmartData = static_cast<Ewk_View_Smart_Data*>(evas_object_smart_data_get(__pView));
246         SysAssertf(pSmartData, "Failed to get webkit smart data.");
247
248         Elm_Access_Action_Info* pActionInfo = new Elm_Access_Action_Info();
249         SysTryReturn(NID_WEB_CTRL, pActionInfo, false, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
250
251         bool result = false;
252
253         pActionInfo->action_type = ELM_ACCESS_ACTION_READ;
254         pActionInfo->x = point.x;
255         pActionInfo->y = point.y;
256
257         result = pSmartData->api->screen_reader_action_execute(const_cast<Ewk_View_Smart_Data*>(pSmartData), pActionInfo);
258         delete pActionInfo;
259
260         return result;
261 }
262
263
264 }
265
266
267 namespace Tizen { namespace Web { namespace Controls
268 {
269
270
271 static const char WEB_CTRL[] = "webcontrol";
272
273
274 void
275 OnEdgeLeft(void* pUserData, Evas_Object* pView, void* pEventInfo)
276 {
277         _Web* pCore = reinterpret_cast< _Web* >(pUserData);
278         SysAssertf(pCore, "Failed to request");
279
280         pCore->SetEdgeReachedEvent(WEB_EDGE_LEFT);
281 }
282
283
284 void
285 OnEdgeRight(void* pUserData, Evas_Object* pView, void* pEventInfo)
286 {
287         _Web* pCore = reinterpret_cast< _Web* >(pUserData);
288         SysAssertf(pCore, "Failed to request");
289
290         pCore->SetEdgeReachedEvent(WEB_EDGE_RIGHT);
291 }
292
293
294 void
295 OnEdgeTop(void* pUserData, Evas_Object* pView, void* pEventInfo)
296 {
297         _Web* pCore = reinterpret_cast< _Web* >(pUserData);
298         SysAssertf(pCore, "Failed to request");
299
300         pCore->SetEdgeReachedEvent(WEB_EDGE_TOP);
301 }
302
303
304 void
305 OnEdgeBottom(void* pUserData, Evas_Object* pView, void* pEventInfo)
306 {
307         _Web* pCore = reinterpret_cast< _Web* >(pUserData);
308         SysAssertf(pCore, "Failed to request");
309
310         pCore->SetEdgeReachedEvent(WEB_EDGE_BOTTOM);
311 }
312
313
314 _Web::_Web(void)
315         : __pGestureHandler(null)
316         , __pEflWebkit(null)
317         , __pWebSetting(null)
318         , __pGestureFlick(null)
319         , __pGestureLongPress(null)
320         , __pGesturePinch(null)
321         , __pGestureDoubleTap(null)
322         , __pTouchEventInfoList(null)
323         , __pTapGestureHandler(null)
324         , __pPanningGestureHandler(null)
325         , __pFlickGestureHandler(null)
326         , __pPinchGestureHandler(null)
327         , __gestureType(WEB_GESTURE_TYPE_TAP)
328         , __edgeType(WEB_EDGE_NONE)
329         , __pTextElement(null)
330         , __previousTouchedPosition(0.0f, 0.0f)
331 {
332         SetBackgroundColor(Color(0, 0, 0, 0));
333 }
334
335
336 _Web::~_Web(void)
337 {
338         RemoveGestureListener();
339 }
340
341
342 _Web*
343 _Web::CreateWebN(void)
344 {
345         result r = E_SUCCESS;
346
347         std::unique_ptr<_Web> pWeb(new (std::nothrow) _Web());
348         SysTryReturn(NID_WEB_CTRL, pWeb.get(), null, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
349
350         pWeb->__pWebSetting = std::unique_ptr<WebSetting>(new (std::nothrow) WebSetting());
351         SysTryReturn(NID_WEB_CTRL, pWeb->__pWebSetting.get(), null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
352
353         pWeb->AcquireHandle();
354         pWeb->SetMultiTouchEnabled(true);
355         pWeb->SetTouchPressThreshold(0.08);
356
357         r = pWeb->AddGestureListeners();
358         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
359
360         r = pWeb->InitializeGestureStates();
361         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
362
363         return pWeb.release();
364 }
365
366
367 result
368 _Web::CreateWebkitEvasObject(void)
369 {
370         result r = E_SUCCESS;
371
372         std::unique_ptr<_EflWebkit> pEflWebkit(new (std::nothrow) _EflWebkit());
373         SysTryReturnResult(NID_WEB_CTRL, pEflWebkit.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
374
375         r = pEflWebkit->Construct(GetAbsoluteBounds(), *GetVisualElement(), this);
376         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
377
378         __pEflWebkit = std::move(pEflWebkit);
379
380         Evas_Object* pView = GetWebNativeNode();
381         evas_object_smart_callback_add(pView, "edge,left", OnEdgeLeft, this);
382         evas_object_smart_callback_add(pView, "edge,right", OnEdgeRight, this);
383         evas_object_smart_callback_add(pView, "edge,top", OnEdgeTop, this);
384         evas_object_smart_callback_add(pView, "edge,bottom", OnEdgeBottom, this);
385
386         return E_SUCCESS;
387 }
388
389
390 result
391 _Web::InitializeGestureStates(void)
392 {
393         __pPinchGestureHandler = std::unique_ptr<_PinchGestureState>(new (std::nothrow) _PinchGestureState(this));
394         SysTryReturnResult(NID_WEB_CTRL, __pPinchGestureHandler.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
395
396         __pTapGestureHandler = std::unique_ptr<_TapGestureState>(new (std::nothrow) _TapGestureState(this));
397         SysTryReturnResult(NID_WEB_CTRL, __pTapGestureHandler.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
398
399         __pPanningGestureHandler = std::unique_ptr<_PanningGestureState>(new (std::nothrow) _PanningGestureState(this));
400         SysTryReturnResult(NID_WEB_CTRL, __pPanningGestureHandler.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
401
402         __pFlickGestureHandler = std::unique_ptr<_FlickGestureState>(new (std::nothrow) _FlickGestureState(this));
403         SysTryReturnResult(NID_WEB_CTRL, __pFlickGestureHandler.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
404
405         __pGestureHandler = __pTapGestureHandler.get();
406
407         return E_SUCCESS;
408 }
409
410
411 result
412 _Web::AddGestureListeners(void)
413 {
414         result r = E_SUCCESS;
415
416         std::unique_ptr<_TouchFlickGestureDetector> pGestureFlick(new (std::nothrow) _TouchFlickGestureDetector());
417         SysTryReturnResult(NID_WEB_CTRL, pGestureFlick.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
418
419         r = pGestureFlick->AddGestureListener(*this);
420         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
421
422         r = AddGestureDetector(*pGestureFlick.get());
423         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
424
425         __pGestureFlick = std::move(pGestureFlick);
426
427         std::unique_ptr<_TouchLongPressGestureDetector> pGestureLongPress(new (std::nothrow) _TouchLongPressGestureDetector());
428         SysTryReturnResult(NID_WEB_CTRL, pGestureLongPress.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
429
430         r = pGestureLongPress->AddGestureListener(*this);
431         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
432
433         r = AddGestureDetector(*pGestureLongPress.get());
434         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
435
436         __pGestureLongPress = std::move(pGestureLongPress);
437
438         std::unique_ptr<_TouchTapGestureDetector> pGestureDoubleTap(new (std::nothrow) _TouchTapGestureDetector());
439         SysTryReturnResult(NID_WEB_CTRL, pGestureDoubleTap.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
440
441         r = pGestureDoubleTap->AddGestureListener(*this);
442         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
443
444         r = AddGestureDetector(*pGestureDoubleTap.get());
445         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
446
447         __pGestureDoubleTap = std::move(pGestureDoubleTap);
448
449         std::unique_ptr<_TouchPinchGestureDetector> pGesturePinch(new (std::nothrow) _TouchPinchGestureDetector());
450         SysTryReturnResult(NID_WEB_CTRL, pGesturePinch.get(), E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
451
452         r = pGesturePinch->AddGestureListener(*this);
453         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
454
455         r = AddGestureDetector(*pGesturePinch.get());
456         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
457
458         __pGesturePinch = std::move(pGesturePinch);
459
460         return E_SUCCESS;
461 }
462
463
464 void
465 _Web::RemoveGestureListener(void)
466 {
467         if (__pGestureFlick.get())
468         {
469                 __pGestureFlick->RemoveGestureListener(*this);
470                 RemoveGestureDetector(*__pGestureFlick);
471         }
472
473         if (__pGestureLongPress.get())
474         {
475                 __pGestureLongPress->RemoveGestureListener(*this);
476                 RemoveGestureDetector(*__pGestureLongPress);
477         }
478
479         if (__pGestureDoubleTap.get())
480         {
481                 __pGestureDoubleTap->RemoveGestureListener(*this);
482                 RemoveGestureDetector(*__pGestureDoubleTap);
483         }
484
485         if (__pGesturePinch.get())
486         {
487                 __pGesturePinch->RemoveGestureListener(*this);
488                 RemoveGestureDetector(*__pGesturePinch);
489         }
490
491         Evas_Object* pView = GetWebNativeNode();
492         if (pView)
493         {
494                 evas_object_smart_callback_del(pView, "edge,left", OnEdgeLeft);
495                 evas_object_smart_callback_del(pView, "edge,right", OnEdgeRight);
496                 evas_object_smart_callback_del(pView, "edge,top", OnEdgeTop);
497                 evas_object_smart_callback_del(pView, "edge,bottom", OnEdgeBottom);
498         }
499 }
500
501
502 result
503 _Web::InitializeWebNativeNode(void)
504 {
505         result r = E_SUCCESS;
506
507         r = CreateWebkitEvasObject();
508         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
509
510         SetNativeObjectFocusable(false);
511
512         _AccessibilityContainer* pContainer = GetAccessibilityContainer();
513         SysTryReturn(NID_WEB_CTRL, pContainer, E_SYSTEM, E_SYSTEM, "[%s] Propagating.", GetErrorMessage(E_SYSTEM));
514
515         __pTextElement = new (std::nothrow) _AccessibilityElement(true);
516         SysTryReturn(NID_WEB_CTRL, __pTextElement, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
517
518         __pTextElement->SetBounds(FloatRectangle(0.0f, 0.0f, GetBoundsF().width, GetBoundsF().height));
519         __pTextElement->SetLabel(L"Web control");
520
521         pContainer->AddElement(*__pTextElement);
522         pContainer->Activate(true);
523
524         _WebAccessibilityListener* pListener = new (std::nothrow) _WebAccessibilityListener(GetWebNativeNode());
525         SysTryReturn(NID_WEB_CTRL, pListener, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
526
527         pContainer->AddListener(*dynamic_cast<_IAccessibilityListener*>(pListener));
528
529         _WebAccessibilityFocusHandler* pFocusHandler = new (std::nothrow) _WebAccessibilityFocusHandler(GetWebNativeNode());
530         SysTryReturn(NID_WEB_CTRL, pFocusHandler, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
531
532         pContainer->SetFocusHandler(dynamic_cast<_IAccessibilityFocusHandler*>(pFocusHandler));
533
534         return E_SUCCESS;
535 }
536
537
538 Point
539 _Web::GetAbsoluteCoordinate(Point relativePoint)
540 {
541         return _CoordinateSystemUtils::Transform(ConvertToScreenPosition(relativePoint));
542 }
543
544
545 FloatPoint
546 _Web::GetAbsoluteCoordinate(FloatPoint relativePoint)
547 {
548         return _CoordinateSystemUtils::Transform(ConvertToScreenPosition(relativePoint));
549 }
550
551
552 Point
553 _Web::GetRelativeCoordinate(Point absolutePoint)
554 {
555         return ConvertToControlPosition(_CoordinateSystemUtils::InverseTransform(absolutePoint));
556 }
557
558
559 FloatPoint
560 _Web::GetRelativeCoordinate(FloatPoint absolutePoint)
561 {
562         return ConvertToControlPosition(_CoordinateSystemUtils::InverseTransform(absolutePoint));
563 }
564
565
566 Evas_Object*
567 _Web::GetWebNativeNode(void)
568 {
569         if (__pEflWebkit.get())
570         {
571                 return __pEflWebkit->GetWebEvasObject();
572         }
573
574         return null;
575 }
576
577
578 WebSetting*
579 _Web::GetSetting(void) const
580 {
581         return __pWebSetting.get();
582 }
583
584
585 result
586 _Web::OnAttaching(const _Control* pParent)
587 {
588         if (__pEflWebkit.get())
589         {
590                 evas_object_show(__pEflWebkit->GetWebEvasObject());
591                 evas_object_focus_set(__pEflWebkit->GetWebEvasObject(), EINA_TRUE);
592         }
593
594         return E_SUCCESS;
595 }
596
597
598 result
599 _Web::OnBoundsChanging(const Rectangle& bounds)
600 {
601         Rectangle absoluteBounds = GetAbsoluteBounds();
602         Rectangle webBounds = GetBounds();
603         _ICoordinateSystemTransformer* pXformer = _CoordinateSystem::GetInstance()->GetTransformer();
604         SysTryReturnResult(NID_WEB_CTRL, pXformer, E_SYSTEM, "[%s] A system error has been occurred. Failed to get coordinate transformer.", GetErrorMessage(E_SYSTEM));
605
606         if (__pEflWebkit.get())
607         {
608                 evas_object_move(__pEflWebkit->GetWebEvasObject(), pXformer->TransformHorizontal(absoluteBounds.x - webBounds.x + bounds.x), pXformer->TransformVertical(absoluteBounds.y - webBounds.y + bounds.y));
609                 evas_object_resize(__pEflWebkit->GetWebEvasObject(), pXformer->TransformHorizontal(bounds.width), pXformer->TransformVertical(bounds.height));
610         }
611
612         return E_SUCCESS;
613 }
614
615
616 void
617 _Web::ChangeGesture(_WebGestureType type)
618 {
619         switch (type)
620         {
621         case WEB_GESTURE_TYPE_TAP:
622                 __pGestureHandler = __pTapGestureHandler.get();
623                 __gestureType = WEB_GESTURE_TYPE_TAP;
624                 break;
625
626         case WEB_GESTURE_TYPE_PANNING:
627                 __pGestureHandler = __pPanningGestureHandler.get();
628                 __gestureType = WEB_GESTURE_TYPE_PANNING;
629                 break;
630
631         case WEB_GESTURE_TYPE_FLICK:
632                 __pGestureHandler = __pFlickGestureHandler.get();
633                 __gestureType = WEB_GESTURE_TYPE_FLICK;
634                 break;
635
636         case WEB_GESTURE_TYPE_PINCH:
637                 __pGestureHandler = __pPinchGestureHandler.get();
638                 __gestureType = WEB_GESTURE_TYPE_PINCH;
639                 break;
640
641         default:
642                 SysAssert(false);
643         }
644 }
645
646
647 void
648 _Web::SetEdgeReachedEvent(_WebEdgeType type)
649 {
650         __edgeType |= type;
651
652         switch(type)
653         {
654         case WEB_EDGE_LEFT:
655                 __edgeType &= ~WEB_EDGE_RIGHT;
656                 break;
657
658         case WEB_EDGE_RIGHT:
659                 __edgeType &= ~WEB_EDGE_LEFT;
660                 break;
661
662         case WEB_EDGE_TOP:
663                 __edgeType &= ~WEB_EDGE_BOTTOM;
664                 break;
665
666         case WEB_EDGE_BOTTOM:
667                 __edgeType &= ~WEB_EDGE_TOP;
668                 break;
669
670         default:
671                 SysAssert(false);
672         }
673 }
674
675
676 bool
677 _Web::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
678 {
679         if (__pEflWebkit.get())
680         {
681                 __edgeType = WEB_EDGE_NONE;
682                 __previousTouchedPosition = touchInfo.GetCurrentPosition();
683
684                 SendTouchEventForJavaScript(touchInfo);
685
686                 return __pGestureHandler->OnTouchPressed(source, touchInfo);
687         }
688
689         return false;
690 }
691
692
693 bool
694 _Web::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
695 {
696         if (__pEflWebkit.get())
697         {
698                 SendTouchEventForJavaScript(touchInfo);
699
700                 __pGestureHandler->OnTouchMoved(source, touchInfo);
701
702                 float scrollDistanceX = __previousTouchedPosition.x - touchInfo.GetCurrentPosition().x;
703                 float scrollDistanceY = __previousTouchedPosition.y - touchInfo.GetCurrentPosition().y;
704                 __previousTouchedPosition = touchInfo.GetCurrentPosition();
705
706                 if (__edgeType !=  WEB_EDGE_NONE && __gestureType == WEB_GESTURE_TYPE_PANNING)
707                 {
708                         if (_Abs(scrollDistanceY) < _Abs(scrollDistanceX))
709                         {
710                                 if  (__edgeType & WEB_EDGE_LEFT)
711                                 {
712                                         if (scrollDistanceX < 0)
713                                         {
714                                                 __edgeType &= ~WEB_EDGE_RIGHT;
715
716                                                 return false;
717                                         }
718                                         else
719                                         {
720                                                 __edgeType &= ~WEB_EDGE_LEFT;
721                                         }
722                                 }
723                                 else if  (__edgeType & WEB_EDGE_RIGHT)
724                                 {
725                                         if (scrollDistanceX > 0)
726                                         {
727                                                 __edgeType &= ~WEB_EDGE_LEFT;
728
729                                                 return false;
730                                         }
731                                         else
732                                         {
733                                                 __edgeType &= ~WEB_EDGE_RIGHT;
734                                         }
735                                 }
736                         }
737                         else if (_Abs(scrollDistanceY) > _Abs(scrollDistanceX))
738                         {
739                                 if  (__edgeType & WEB_EDGE_TOP)
740                                 {
741                                         if (scrollDistanceY < 0)
742                                         {
743                                                 __edgeType &= ~WEB_EDGE_BOTTOM;
744
745                                                 return false;
746                                         }
747                                         else
748                                         {
749                                                 __edgeType &= ~WEB_EDGE_TOP;
750                                         }
751                                 }
752                                 else if  (__edgeType & WEB_EDGE_BOTTOM)
753                                 {
754                                         if (scrollDistanceY > 0)
755                                         {
756                                                 __edgeType &= ~WEB_EDGE_TOP;
757
758                                                 return false;
759                                         }
760                                         else
761                                         {
762                                                 __edgeType &= ~WEB_EDGE_BOTTOM;
763                                         }
764                                 }
765                         }
766                 }
767
768                 return true;
769         }
770
771         return false;
772 }
773
774
775 bool
776 _Web::OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
777 {
778         SetFocused();
779
780         if (__pEflWebkit.get())
781         {
782                 SendTouchEventForJavaScript(touchInfo);
783
784                 Evas_Object* pView = GetWebNativeNode();
785                 _WebImpl* pImpl = reinterpret_cast< _WebImpl* >(evas_object_data_get(pView, WEB_CTRL));
786
787                 if (pImpl && pImpl->GetTextFromBlock().GetLength() > 0)
788                 {
789                         evas_object_smart_callback_call(pView, "text,selected", NULL);
790                 }
791
792                 return __pGestureHandler->OnTouchReleased(source, touchInfo);
793         }
794
795         return false;
796 }
797
798
799 bool
800 _Web::OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
801 {
802         if (__pEflWebkit.get())
803         {
804                 SendTouchEventForJavaScript(touchInfo);
805
806                 return __pGestureHandler->OnTouchCanceled(source, touchInfo);
807         }
808
809         return false;
810 }
811
812
813 void
814 _Web::OnTouchPressHandled(const _Control& control)
815 {
816 }
817
818
819 void
820 _Web::OnTouchReleaseHandled(const _Control& control)
821 {
822 }
823
824
825 void
826 _Web::OnTouchMoveHandled(const _Control& control)
827 {
828 }
829
830
831 void
832 _Web::OnTouchCancelHandled(const _Control& control)
833 {
834 }
835
836
837 bool
838 _Web::OnLongPressGestureDetected(_TouchLongPressGestureDetector& gesture)
839 {
840         if (__pEflWebkit.get() && __gestureType == WEB_GESTURE_TYPE_TAP)
841         {
842                 return __pTapGestureHandler->OnLongPressGestureDetected(gesture);
843         }
844
845         return true;
846 }
847
848
849 bool
850 _Web::OnLongPressGestureCanceled(_TouchLongPressGestureDetector& gesture)
851 {
852         return true;
853 }
854
855
856 bool
857 _Web::OnTapGestureDetected(_TouchTapGestureDetector& gesture)
858 {
859         if (__pEflWebkit.get())
860         {
861                 return __pTapGestureHandler->OnTapGestureDetected(gesture);
862         }
863
864         return true;
865 }
866
867
868 bool
869 _Web::OnTapGestureCanceled(_TouchTapGestureDetector& gesture)
870 {
871         return true;
872 }
873
874
875 bool
876 _Web::OnFlickGestureDetected(_TouchFlickGestureDetector& gesture)
877 {
878         if (__pEflWebkit.get() && _WebSettingImpl::GetInstance(__pWebSetting.get())->IsScrollEnabled())
879         {
880                 return __pFlickGestureHandler->OnFlickGestureDetected(gesture);
881         }
882
883         return true;
884 }
885
886
887 bool
888 _Web::OnFlickGestureCanceled(_TouchFlickGestureDetector& gesture)
889 {
890         return true;
891 }
892
893
894 bool
895 _Web::OnPinchGestureStarted(Tizen::Ui::_TouchPinchGestureDetector& gesture)
896 {
897         if (__pEflWebkit.get())
898         {
899                 return __pPinchGestureHandler->OnPinchGestureStarted(gesture);
900         }
901
902         return true;
903 }
904
905
906 bool
907 _Web::OnPinchGestureChanged(Tizen::Ui::_TouchPinchGestureDetector& gesture)
908 {
909         if (__pEflWebkit.get() && __gestureType == WEB_GESTURE_TYPE_PINCH)
910         {
911                 return __pPinchGestureHandler->OnPinchGestureChanged(gesture);
912         }
913
914         return true;
915 }
916
917
918 bool
919 _Web::OnPinchGestureFinished(Tizen::Ui::_TouchPinchGestureDetector& gesture)
920 {
921         if (__pEflWebkit.get() && __gestureType == WEB_GESTURE_TYPE_PINCH)
922         {
923                 return __pPinchGestureHandler->OnPinchGestureFinished(gesture);
924         }
925
926         return true;
927 }
928
929
930 bool
931 _Web::OnPinchGestureCanceled(Tizen::Ui::_TouchPinchGestureDetector& gesture)
932 {
933         return true;
934 }
935
936
937 Canvas*
938 _Web::OnCanvasRequestedN(const FloatRectangle& bounds)
939 {
940         result r = E_SUCCESS;
941
942         Evas_Object* pWebFrame = GetWebNativeNode();
943         Eina_Rectangle rect;
944         BufferInfo bufferInfo;
945
946         Point absPoint(_CoordinateSystemUtils::ConvertToInteger(GetAbsoluteCoordinate(FloatPoint(bounds.x, bounds.y))));
947         Dimension absSize(_CoordinateSystemUtils::ConvertToInteger(_CoordinateSystemUtils::HorizontalTransform(bounds.width)),
948                 _CoordinateSystemUtils::ConvertToInteger(_CoordinateSystemUtils::VerticalTransform(bounds.height)));
949
950         EINA_RECTANGLE_SET(&rect, absPoint.x, absPoint.y, absSize.width, absSize.height);
951
952         Evas_Object* pScreenShot = ewk_view_screenshot_contents_get(pWebFrame, rect, 1.0f, evas_object_evas_get(pWebFrame));
953
954         std::unique_ptr<Canvas> pCanvas(new (std::nothrow) Canvas());
955         SysTryReturn(NID_WEB_CTRL, pCanvas.get(), null, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
956
957         if (pScreenShot)
958         {
959                 r = _Utility::GetPixelBufferFromEvasObject(pScreenShot, bufferInfo);
960                 evas_object_del(pScreenShot);
961                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] propagating", GetErrorMessage(r));
962
963                 r = pCanvas->Construct(bufferInfo);
964                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] propagating", GetErrorMessage(r));
965         }
966         else
967         {
968                 r = pCanvas->Construct(bounds);
969                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] propagating", GetErrorMessage(r));
970         }
971
972         return pCanvas.release();
973 }
974
975
976 Bitmap*
977 _Web::OnCapturedBitmapRequestedN(void)
978 {
979         result r = E_SUCCESS;
980
981         Evas_Object* pWebFrame = GetWebNativeNode();
982         Eina_Rectangle rect;
983         ByteBuffer buffer;
984         BufferInfo bufferInfo;
985
986         Dimension size(GetSize());
987         Point absSize(GetAbsoluteCoordinate(Point(size.width, size.height)));
988
989         EINA_RECTANGLE_SET(&rect, 0, 0, absSize.x, absSize.y);
990
991         Evas_Object* pScreenShot = ewk_view_screenshot_contents_get(pWebFrame, rect, 1.0f, evas_object_evas_get(pWebFrame));
992         SysTryReturn(NID_WEB_CTRL, pScreenShot, null, E_SYSTEM, "[%s] A system error has been occurred. Failed to get snapshot of Web control", GetErrorMessage(E_SYSTEM));
993
994         r = _Utility::GetPixelBufferFromEvasObject(pScreenShot, bufferInfo);
995         evas_object_del(pScreenShot);
996         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] propagating", GetErrorMessage(r));
997
998         int bufferSize = bufferInfo.bitsPerPixel * bufferInfo.width * bufferInfo.height;
999         r = buffer.Construct(reinterpret_cast < byte* >(bufferInfo.pPixels), 0, bufferSize, bufferSize);
1000         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] propagating", GetErrorMessage(r));
1001
1002         std::unique_ptr<Bitmap> pBitmap(new (std::nothrow) Bitmap());
1003         SysTryReturn(NID_WEB_CTRL, pBitmap.get(), null, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
1004
1005         r = pBitmap->Construct(buffer, Dimension(bufferInfo.width, bufferInfo.height), BITMAP_PIXEL_FORMAT_ARGB8888);
1006         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, null, r, "[%s] propagating", GetErrorMessage(r));
1007
1008         return pBitmap.release();
1009 }
1010
1011
1012 void
1013 _Web::DumpPointList(void* pData)
1014 {
1015         Eina_List* pList = reinterpret_cast< Eina_List* >(pData);
1016
1017         for(; pList; pList = eina_list_next(pList))
1018         {
1019                 Ewk_Touch_Point* pPointDump = static_cast<Ewk_Touch_Point*>(eina_list_data_get(pList));
1020                 SysSecureLog(NID_WEB_CTRL, "The current value of id is %lu, x is %d, y is %d, state is %d", pPointDump->id, pPointDump->x, pPointDump->y, pPointDump->state);
1021         }
1022 }
1023
1024
1025 void
1026 _Web::SendTouchEventForJavaScript(const _TouchInfo& touchInfo)
1027 {
1028         result r = E_SUCCESS;
1029
1030         Eina_List* pPointList = null;
1031         Ewk_Touch_Point* pPoint = null;
1032
1033         _TouchManager* pTouchManager = _TouchManager::GetInstance();
1034         SysAssertf(pTouchManager, "Failed to get touch manager.");
1035
1036         std::unique_ptr<IListT<_FingerInfo*> > pTouchList(pTouchManager->GetMultiFingerInfoListN());
1037         SysTryReturnVoidResult(NID_WEB_CTRL, pTouchList.get(), GetLastResult(), "[%s] Failed to get touch list.", GetErrorMessage(GetLastResult()));
1038
1039         std::unique_ptr<IBidirectionalEnumeratorT<_FingerInfo*> > pTouchListEnum(pTouchList->GetBidirectionalEnumeratorN());
1040         SysAssertf(pTouchListEnum.get() != null, "Failed to get enumerator of touch list.");
1041
1042         FloatPoint currentPoint;
1043         _FingerInfo* pFingerInfo = null;
1044         while(pTouchListEnum->MoveNext() == E_SUCCESS)
1045         {
1046                 r = pTouchListEnum->GetCurrent(pFingerInfo);
1047                 SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
1048
1049                 _TouchStatus state = pFingerInfo->GetStatus();
1050                 if(state == _TOUCH_PRESSED || state == _TOUCH_MOVED || state == _TOUCH_RELEASED || state == _TOUCH_CANCELED)
1051                 {
1052                         currentPoint = GetAbsoluteCoordinate(pFingerInfo->GetPoint());
1053                         Point integerPoint(_CoordinateSystemUtils::ConvertToInteger(currentPoint));
1054
1055                         pPoint = static_cast<Ewk_Touch_Point*>(calloc(1, sizeof(Ewk_Touch_Point)));
1056
1057                         pPoint->id = pFingerInfo->GetPointId();
1058                         pPoint->x = integerPoint.x;
1059                         pPoint->y = integerPoint.y;
1060                         pPoint->state = GetEvasTouchState((TouchStatus)pFingerInfo->GetStatus());
1061
1062                         pPointList = eina_list_append(pPointList, pPoint);
1063                 }
1064         }
1065         DumpPointList(pPointList);
1066
1067         Eina_Bool ret = ewk_view_feed_touch_event(__pEflWebkit->GetWebEvasObject(), GetEwkTouchEvent(touchInfo.GetTouchStatus()), pPointList, null);
1068         SysTryReturnVoidResult(NID_WEB_CTRL, ret == EINA_TRUE, E_SYSTEM, "[%s] A system error has been occurred. Failed to deliver touch event to javascript.", GetErrorMessage(E_SYSTEM));
1069
1070         void* pData = null;
1071
1072         EINA_LIST_FREE(pPointList, pData)
1073         free(pData);
1074 }
1075
1076
1077 Ewk_Touch_Event_Type
1078 _Web::GetEwkTouchEvent(_TouchStatus touchStatus)
1079 {
1080         Ewk_Touch_Event_Type ewkTouchEvent = EWK_TOUCH_CANCEL;
1081
1082         switch (touchStatus)
1083         {
1084         case _TOUCH_PRESSED :
1085                 ewkTouchEvent = EWK_TOUCH_START;
1086                 break;
1087         case _TOUCH_MOVED :
1088                 ewkTouchEvent = EWK_TOUCH_MOVE;
1089                 break;
1090         case _TOUCH_RELEASED :
1091                 ewkTouchEvent = EWK_TOUCH_END;
1092                 break;
1093         case _TOUCH_CANCELED :
1094                 //fall through
1095         default :
1096                 ewkTouchEvent = EWK_TOUCH_CANCEL;
1097                 break;
1098         }
1099
1100         return ewkTouchEvent;
1101 }
1102
1103
1104 Evas_Touch_Point_State
1105 _Web::GetEvasTouchState(TouchStatus touchStatus)
1106 {
1107         Evas_Touch_Point_State evasTouchState = EVAS_TOUCH_POINT_CANCEL;
1108
1109         switch (touchStatus)
1110         {
1111         case TOUCH_PRESSED :
1112                 evasTouchState = EVAS_TOUCH_POINT_DOWN;
1113                 break;
1114         case TOUCH_MOVED :
1115                 evasTouchState = EVAS_TOUCH_POINT_MOVE;
1116                 break;
1117         case TOUCH_RELEASED :
1118                 evasTouchState = EVAS_TOUCH_POINT_UP;
1119                 break;
1120         case TOUCH_CANCELED :
1121                 //fall through
1122         default :
1123                 evasTouchState = EVAS_TOUCH_POINT_CANCEL;
1124                 //todo : mapping    EVAS_TOUCH_POINT_STILL, /**< Touch point is not moved af
1125                 break;
1126         }
1127
1128         return evasTouchState;
1129 }
1130
1131
1132 }}} // Tizen::Web::Controls