Init Tizen 2.2.1
[framework/osp/web.git] / src / controls / FWebCtrl_Web.cpp
index 74782d2..0e8c70c 100755 (executable)
@@ -21,6 +21,7 @@
  *
  * The file contains the definition of _Web class.
  */
+#include <Ecore_X.h>
 #include <Elementary.h>
 #include <memory>
 #include <FBaseByteBuffer.h>
@@ -42,6 +43,7 @@
 #include <FUi_CoordinateSystemUtils.h>
 #include <FUi_AccessibilityContainer.h>
 #include <FUi_AccessibilityElement.h>
+#include <FUi_UiEventManager.h>
 #include <FUi_IAccessibilityFocusHandler.h>
 #include <FUi_IAccessibilityListener.h>
 #include <FUi_Math.h>
@@ -60,7 +62,7 @@ using namespace Tizen::Ui;
 using namespace Tizen::Ui::Animations;
 
 
-namespace
+namespace Tizen { namespace Web { namespace Controls
 {
 
 
@@ -278,13 +280,6 @@ _WebAccessibilityFocusHandler::OnMoveFocus(const Tizen::Graphics::Point& point)
 }
 
 
-}
-
-
-namespace Tizen { namespace Web { namespace Controls
-{
-
-
 void
 OnEdgeLeft(void* pUserData, Evas_Object* pView, void* pEventInfo)
 {
@@ -338,10 +333,16 @@ _Web::_Web(void)
        , __pPanningGestureHandler(null)
        , __pFlickGestureHandler(null)
        , __pPinchGestureHandler(null)
+       , __pWebAccessibilityListener(null)
+       , __pWebAccessibilityFocusHandler(null)
        , __gestureType(WEB_GESTURE_TYPE_TAP)
        , __edgeType(WEB_EDGE_NONE)
+       , __focus(false)
        , __pTextElement(null)
        , __previousTouchedPosition(0.0f, 0.0f)
+       , __isFullScreenEntered(false)
+       , __isRotated(false)
+       , __touchPressed(false)
 {
        SetBackgroundColor(Color(0, 0, 0, 0));
 }
@@ -350,6 +351,13 @@ _Web::_Web(void)
 _Web::~_Web(void)
 {
        RemoveGestureListener();
+
+       _AccessibilityContainer* pContainer = GetAccessibilityContainer();
+       if (pContainer)
+       {
+               pContainer->RemoveListener(*dynamic_cast<_IAccessibilityListener*>(__pWebAccessibilityListener.get()));
+               pContainer->SetFocusHandler(null);
+       }
 }
 
 
@@ -539,15 +547,19 @@ _Web::InitializeWebNativeNode(void)
        pContainer->AddElement(*__pTextElement);
        pContainer->Activate(true);
 
-       _WebAccessibilityListener* pListener = new (std::nothrow) _WebAccessibilityListener(GetWebNativeNode());
+       std::unique_ptr<_WebAccessibilityListener> pListener(new (std::nothrow) _WebAccessibilityListener(GetWebNativeNode()));
        SysTryReturn(NID_WEB_CTRL, pListener, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
 
-       pContainer->AddListener(*dynamic_cast<_IAccessibilityListener*>(pListener));
+       __pWebAccessibilityListener = std::move(pListener);
+
+       pContainer->AddListener(*dynamic_cast<_IAccessibilityListener*>(__pWebAccessibilityListener.get()));
 
-       _WebAccessibilityFocusHandler* pFocusHandler = new (std::nothrow) _WebAccessibilityFocusHandler(GetWebNativeNode());
+       std::unique_ptr<_WebAccessibilityFocusHandler> pFocusHandler(new (std::nothrow) _WebAccessibilityFocusHandler(GetWebNativeNode()));
        SysTryReturn(NID_WEB_CTRL, pFocusHandler, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[%s] Memory Allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
 
-       pContainer->SetFocusHandler(dynamic_cast<_IAccessibilityFocusHandler*>(pFocusHandler));
+       __pWebAccessibilityFocusHandler = std::move(pFocusHandler);
+
+       pContainer->SetFocusHandler(dynamic_cast<_IAccessibilityFocusHandler*>(__pWebAccessibilityFocusHandler.get()));
 
        return E_SUCCESS;
 }
@@ -600,6 +612,20 @@ _Web::GetSetting(void) const
 }
 
 
+_EflWebkit*
+_Web::GetEflWebkit(void) const
+{
+       return __pEflWebkit.get();
+}
+
+
+FloatPoint
+_Web::GetTouchPosition(void) const
+{
+       return __previousTouchedPosition;
+}
+
+
 result
 _Web::OnAttaching(const _Control* pParent)
 {
@@ -621,7 +647,7 @@ _Web::OnBoundsChanging(const Rectangle& bounds)
        _ICoordinateSystemTransformer* pXformer = _CoordinateSystem::GetInstance()->GetTransformer();
        SysTryReturnResult(NID_WEB_CTRL, pXformer, E_SYSTEM, "[%s] A system error has been occurred. Failed to get coordinate transformer.", GetErrorMessage(E_SYSTEM));
 
-       if (__pEflWebkit.get())
+       if (__pEflWebkit.get() && __isRotated == false)
        {
                evas_object_move(__pEflWebkit->GetWebEvasObject(), pXformer->TransformHorizontal(absoluteBounds.x - webBounds.x + bounds.x), pXformer->TransformVertical(absoluteBounds.y - webBounds.y + bounds.y));
                evas_object_resize(__pEflWebkit->GetWebEvasObject(), pXformer->TransformHorizontal(bounds.width), pXformer->TransformVertical(bounds.height));
@@ -632,6 +658,20 @@ _Web::OnBoundsChanging(const Rectangle& bounds)
 
 
 void
+_Web::OnBoundsChanged(void)
+{
+       __isRotated = false;
+}
+
+
+void
+_Web::OnChangeLayout(_ControlOrientation orientation)
+{
+       __isRotated = true;
+}
+
+
+void
 _Web::ChangeGesture(_WebGestureType type)
 {
        switch (type)
@@ -694,6 +734,8 @@ _Web::SetEdgeReachedEvent(_WebEdgeType type)
 bool
 _Web::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
 {
+       __touchPressed = true;
+
        if (__pEflWebkit.get())
        {
                __edgeType = WEB_EDGE_NONE;
@@ -709,86 +751,182 @@ _Web::OnTouchPressed(const _Control& source, const _TouchInfo& touchInfo)
 
 
 bool
-_Web::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
+_Web::CanOutOfEdgeLeft(float scrollDistanceX, int pageDistance)
 {
-       if (__pEflWebkit.get())
+       if (scrollDistanceX < 0.0f)
        {
-               if (__gestureType == WEB_GESTURE_TYPE_TAP)
-               {
-                       __pPanningGestureHandler->InitializeTextSelectionStatus();
-               }
+               __edgeType &= ~WEB_EDGE_RIGHT;
 
-               SendTouchEventForJavaScript(touchInfo);
+               return false;
+       }
+       else if (scrollDistanceX > 0.0f && pageDistance != 0)
+       {
+               __edgeType &= ~WEB_EDGE_LEFT;
+       }
 
-               __pGestureHandler->OnTouchMoved(source, touchInfo);
+       return true;
+}
 
-               float scrollDistanceX = __previousTouchedPosition.x - touchInfo.GetCurrentPosition().x;
-               float scrollDistanceY = __previousTouchedPosition.y - touchInfo.GetCurrentPosition().y;
-               __previousTouchedPosition = touchInfo.GetCurrentPosition();
 
-               if (__edgeType !=  WEB_EDGE_NONE && __gestureType == WEB_GESTURE_TYPE_PANNING)
+bool
+_Web::CanOutOfEdgeRight(float scrollDistanceX, int pageDistance)
+{
+       if (scrollDistanceX > 0.0f)
+       {
+               __edgeType &= ~WEB_EDGE_LEFT;
+
+               return false;
+       }
+       else if (scrollDistanceX < 0.0f &&  pageDistance != 0)
+       {
+               __edgeType &= ~WEB_EDGE_RIGHT;
+       }
+
+       return true;
+}
+
+
+bool
+_Web::CanOutOfEdgeTop(float scrollDistanceY, int pageDistance)
+{
+       if (scrollDistanceY < 0.0f)
+       {
+               __edgeType &= ~WEB_EDGE_BOTTOM;
+
+               return false;
+       }
+       else if (scrollDistanceY > 0.0f && pageDistance != 0)
+       {
+               __edgeType &= ~WEB_EDGE_TOP;
+       }
+
+       return true;
+}
+
+
+bool
+_Web::CanOutOfEdgeBottom(float scrollDistanceY, int pageDistance)
+{
+       if (scrollDistanceY > 0.0f)
+       {
+               __edgeType &= ~WEB_EDGE_TOP;
+
+               return false;
+       }
+       else if (scrollDistanceY < 0.0f && pageDistance != 0)
+       {
+               __edgeType &= ~WEB_EDGE_BOTTOM;
+       }
+
+       return true;
+}
+
+
+bool
+_Web::CanConsumeTouchMoved(float scrollDistanceX, float scrollDistanceY)
+{
+       if (__edgeType ==  WEB_EDGE_NONE)
+       {
+               return true;
+       }
+
+       bool ret = true;
+
+       int scrollWidth = 0;
+       int scrollHeight = 0;
+       ewk_view_scroll_size_get(GetWebNativeNode(), &scrollWidth, &scrollHeight);
+
+       int scrollX = 0;
+       int scrollY = 0;
+       ewk_view_scroll_pos_get(GetWebNativeNode(), &scrollX, &scrollY);
+
+       if (scrollWidth == 0)
+       {
+               if (__edgeType & WEB_EDGE_TOP)
                {
-                       if (_Abs(scrollDistanceY) < _Abs(scrollDistanceX))
+                       if (!CanOutOfEdgeTop(scrollDistanceY, scrollY - 0))
                        {
-                               if  (__edgeType & WEB_EDGE_LEFT)
-                               {
-                                       if (scrollDistanceX < 0)
-                                       {
-                                               __edgeType &= ~WEB_EDGE_RIGHT;
-
-                                               return false;
-                                       }
-                                       else
-                                       {
-                                               __edgeType &= ~WEB_EDGE_LEFT;
-                                       }
-                               }
-                               else if  (__edgeType & WEB_EDGE_RIGHT)
-                               {
-                                       if (scrollDistanceX > 0)
-                                       {
-                                               __edgeType &= ~WEB_EDGE_LEFT;
-
-                                               return false;
-                                       }
-                                       else
-                                       {
-                                               __edgeType &= ~WEB_EDGE_RIGHT;
-                                       }
-                               }
+                               return false;
                        }
-                       else if (_Abs(scrollDistanceY) > _Abs(scrollDistanceX))
+               }
+               else if (__edgeType & WEB_EDGE_BOTTOM)
+               {
+                       if (!CanOutOfEdgeBottom(scrollDistanceY, scrollY - scrollHeight))
                        {
-                               if  (__edgeType & WEB_EDGE_TOP)
-                               {
-                                       if (scrollDistanceY < 0)
-                                       {
-                                               __edgeType &= ~WEB_EDGE_BOTTOM;
-
-                                               return false;
-                                       }
-                                       else
-                                       {
-                                               __edgeType &= ~WEB_EDGE_TOP;
-                                       }
-                               }
-                               else if  (__edgeType & WEB_EDGE_BOTTOM)
-                               {
-                                       if (scrollDistanceY > 0)
-                                       {
-                                               __edgeType &= ~WEB_EDGE_TOP;
-
-                                               return false;
-                                       }
-                                       else
-                                       {
-                                               __edgeType &= ~WEB_EDGE_BOTTOM;
-                                       }
-                               }
+                               return false;
                        }
                }
+       }
 
-               return true;
+       if (scrollHeight == 0)
+       {
+               if (__edgeType & WEB_EDGE_LEFT)
+               {
+                       if (!CanOutOfEdgeLeft(scrollDistanceX, scrollX - 0))
+                       {
+                               return false;
+                       }
+               }
+               else if  (__edgeType & WEB_EDGE_RIGHT)
+               {
+                       if (!CanOutOfEdgeRight(scrollDistanceX, scrollX - scrollWidth))
+                       {
+                               return false;
+                       }
+               }
+       }
+
+       if (scrollWidth > 0 && scrollHeight > 0)
+       {
+               if  ((__edgeType & WEB_EDGE_LEFT) && (__edgeType & WEB_EDGE_TOP))
+               {
+                       if (!CanOutOfEdgeLeft(scrollDistanceX, scrollX - 0) || !CanOutOfEdgeTop(scrollDistanceY, scrollY - 0))
+                       {
+                               return false;
+                       }
+               }
+               else if  ((__edgeType & WEB_EDGE_LEFT) && (__edgeType & WEB_EDGE_BOTTOM))
+               {
+                       if (!CanOutOfEdgeLeft(scrollDistanceX, scrollX - 0) || !CanOutOfEdgeBottom(scrollDistanceY, scrollY - scrollHeight))
+                       {
+                               return false;
+                       }
+               }
+               else if  ((__edgeType & WEB_EDGE_RIGHT) && (__edgeType & WEB_EDGE_TOP))
+               {
+                       if (!CanOutOfEdgeRight(scrollDistanceX, scrollX - scrollWidth) || !CanOutOfEdgeTop(scrollDistanceY, scrollY - 0))
+                       {
+                               return false;
+                       }
+               }
+               else if  ((__edgeType & WEB_EDGE_RIGHT) && (__edgeType & WEB_EDGE_BOTTOM))
+               {
+                       if (!CanOutOfEdgeRight(scrollDistanceX, scrollX - scrollWidth) || !CanOutOfEdgeBottom(scrollDistanceY, scrollY - scrollHeight))
+                       {
+                               return false;
+                       }
+               }
+       }
+
+       return true;
+}
+
+
+bool
+_Web::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
+{
+       if (__pEflWebkit.get())
+       {
+               SendTouchEventForJavaScript(touchInfo);
+
+               float scrollDistanceX = __previousTouchedPosition.x - touchInfo.GetCurrentPosition().x;
+               float scrollDistanceY = __previousTouchedPosition.y - touchInfo.GetCurrentPosition().y;
+               __previousTouchedPosition = touchInfo.GetCurrentPosition();
+
+               if (CanConsumeTouchMoved(scrollDistanceX, scrollDistanceY))
+               {
+                       return __pGestureHandler->OnTouchMoved(source, touchInfo);
+               }
        }
 
        return false;
@@ -798,6 +936,8 @@ _Web::OnTouchMoved(const _Control& source, const _TouchInfo& touchInfo)
 bool
 _Web::OnTouchReleased(const _Control& source, const _TouchInfo& touchInfo)
 {
+       __touchPressed = false;
+
        SetFocused();
 
        if (__pEflWebkit.get())
@@ -825,30 +965,6 @@ _Web::OnTouchCanceled(const _Control& source, const _TouchInfo& touchInfo)
 }
 
 
-void
-_Web::OnTouchPressHandled(const _Control& control)
-{
-}
-
-
-void
-_Web::OnTouchReleaseHandled(const _Control& control)
-{
-}
-
-
-void
-_Web::OnTouchMoveHandled(const _Control& control)
-{
-}
-
-
-void
-_Web::OnTouchCancelHandled(const _Control& control)
-{
-}
-
-
 bool
 _Web::OnLongPressGestureDetected(_TouchLongPressGestureDetector& gesture)
 {
@@ -857,14 +973,14 @@ _Web::OnLongPressGestureDetected(_TouchLongPressGestureDetector& gesture)
                return __pTapGestureHandler->OnLongPressGestureDetected(gesture);
        }
 
-       return true;
+       return false;
 }
 
 
 bool
 _Web::OnLongPressGestureCanceled(_TouchLongPressGestureDetector& gesture)
 {
-       return true;
+       return false;
 }
 
 
@@ -876,33 +992,33 @@ _Web::OnTapGestureDetected(_TouchTapGestureDetector& gesture)
                return __pTapGestureHandler->OnTapGestureDetected(gesture);
        }
 
-       return true;
+       return false;
 }
 
 
 bool
 _Web::OnTapGestureCanceled(_TouchTapGestureDetector& gesture)
 {
-       return true;
+       return false;
 }
 
 
 bool
 _Web::OnFlickGestureDetected(_TouchFlickGestureDetector& gesture)
 {
-       if (__pEflWebkit.get() && _WebSettingImpl::GetInstance(__pWebSetting.get())->IsScrollEnabled())
+       if (__pEflWebkit.get())
        {
                return __pFlickGestureHandler->OnFlickGestureDetected(gesture);
        }
 
-       return true;
+       return false;
 }
 
 
 bool
 _Web::OnFlickGestureCanceled(_TouchFlickGestureDetector& gesture)
 {
-       return true;
+       return false;
 }
 
 
@@ -914,7 +1030,7 @@ _Web::OnPinchGestureStarted(Tizen::Ui::_TouchPinchGestureDetector& gesture)
                return __pPinchGestureHandler->OnPinchGestureStarted(gesture);
        }
 
-       return true;
+       return false;
 }
 
 
@@ -926,7 +1042,7 @@ _Web::OnPinchGestureChanged(Tizen::Ui::_TouchPinchGestureDetector& gesture)
                return __pPinchGestureHandler->OnPinchGestureChanged(gesture);
        }
 
-       return true;
+       return false;
 }
 
 
@@ -938,14 +1054,14 @@ _Web::OnPinchGestureFinished(Tizen::Ui::_TouchPinchGestureDetector& gesture)
                return __pPinchGestureHandler->OnPinchGestureFinished(gesture);
        }
 
-       return true;
+       return false;
 }
 
 
 bool
 _Web::OnPinchGestureCanceled(Tizen::Ui::_TouchPinchGestureDetector& gesture)
 {
-       return true;
+       return false;
 }
 
 
@@ -1142,4 +1258,122 @@ _Web::GetEvasTouchState(TouchStatus touchStatus)
 }
 
 
+void
+_Web::SetFullScreenEntered(bool isFullScreenEntered)
+{
+       __isFullScreenEntered = isFullScreenEntered;
+}
+
+
+void
+_Web::SetFocusEnd(bool focus)
+{
+       __focus = focus;
+}
+
+
+bool
+_Web::IsFocusEnd(void) const
+{
+       return __focus;
+}
+
+
+bool
+_Web::OnKeyPressed(const _Control& source, const _KeyInfo& keyInfo)
+{
+       Ecore_X_Window rootWindow = ecore_x_window_root_first_get();
+       Ecore_X_Atom keyboardExist = ecore_x_atom_get("X External Keyboard Exist");
+       unsigned int keyboardNumber = 0;
+       int ret = ecore_x_window_prop_card32_get(rootWindow, keyboardExist, &keyboardNumber, 1);
+       if (keyboardNumber == 0)
+       {
+               return false;
+       }
+
+       _KeyCode keyCode = keyInfo.GetKeyCode();
+
+       if (IsFocusEnd() == true)
+       {
+               SetFocusEnd(false);
+               evas_object_focus_set(GetWebNativeNode(), EINA_FALSE);
+               return false;
+       }
+
+       switch(keyCode)
+       {
+       case _KEY_UP:
+       case _KEY_DOWN:
+               evas_object_focus_set(GetWebNativeNode(), EINA_FALSE);
+               return false;
+               break;
+       default:
+               break;
+       }
+
+       evas_object_focus_set(GetWebNativeNode(), EINA_TRUE);
+
+       return true;
+}
+
+
+bool
+_Web::OnKeyReleased(const _Control& source, const _KeyInfo& keyInfo)
+{
+       if (__isFullScreenEntered)
+       {
+               if (keyInfo.GetKeyCode() == _KEY_ESC || keyInfo.GetKeyCode() == _KEY_BACK)
+               {
+                       __isFullScreenEntered = false;
+
+                       ewk_view_fullscreen_exit(GetWebNativeNode());
+
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+
+void
+_Web::OnDrawFocus(void)
+{
+}
+
+
+bool
+_Web::OnFocusLost(const _Control& source)
+{
+       _Control::OnFocusLost(*this);
+
+       if (__touchPressed == true)
+       {
+               _TouchManager* pTouchManager = _TouchManager::GetInstance();
+               SysAssertf(pTouchManager, "Failed to get touch manager.");
+
+               Point absPoint(_CoordinateSystemUtils::ConvertToInteger(pTouchManager->GetPosition(pTouchManager->GetCurrentPointId())));
+
+               Ewk_Touch_Point* pPoint = static_cast< Ewk_Touch_Point* >(calloc(1, sizeof(Ewk_Touch_Point)));
+               pPoint->id = 0;
+               pPoint->x = absPoint.x;
+               pPoint->y = absPoint.y;
+               pPoint->state = EVAS_TOUCH_POINT_CANCEL;
+
+               Eina_List* pPointList = null;
+               pPointList = eina_list_append(pPointList, pPoint);
+
+               ewk_view_feed_touch_event(GetWebNativeNode(), EWK_TOUCH_CANCEL, pPointList, null);
+
+               void* pData = null;
+               EINA_LIST_FREE(pPointList, pData)
+               free(pData);
+
+               __touchPressed = false;
+       }
+
+       return false;
+}
+
+
 }}} // Tizen::Web::Controls