Fix for cursor position.
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / decorator / text-decorator.cpp
index 43ccb78..cc76691 100644 (file)
@@ -24,7 +24,7 @@
 #include <dali/public-api/adaptor-framework/timer.h>
 #include <dali/public-api/actors/layer.h>
 #include <dali/public-api/common/stage.h>
-#include <dali/public-api/events/touch-event.h>
+#include <dali/public-api/events/touch-data.h>
 #include <dali/public-api/events/pan-gesture.h>
 #include <dali/public-api/images/resource-image.h>
 #include <dali/public-api/object/property-notification.h>
@@ -283,10 +283,8 @@ struct Decorator::Impl : public ConnectionTracker
     mNotifyEndOfScroll( false )
   {
     mQuadVertexFormat[ "aPosition" ] = Property::VECTOR2;
-    mQuadIndexFormat[ "indices" ] = Property::INTEGER;
-    mHighlightMaterial = Material::New( Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ) );
-
-    SetupTouchEvents();
+    mHighlightShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
+    SetupGestures();
   }
 
   /**
@@ -488,7 +486,6 @@ struct Decorator::Impl : public ConnectionTracker
     {
       const HandleImpl& primaryHandle = mHandle[LEFT_SELECTION_HANDLE];
       const HandleImpl& secondaryHandle = mHandle[RIGHT_SELECTION_HANDLE];
-      const HandleImpl& grabHandle = mHandle[GRAB_HANDLE];
       const CursorImpl& cursor = mCursor[PRIMARY_CURSOR];
 
       if( primaryHandle.active || secondaryHandle.active )
@@ -504,7 +501,15 @@ struct Decorator::Impl : public ConnectionTracker
       else
       {
         // Calculates the popup's position if the grab handle is active.
-        mCopyPastePopup.position = Vector3( cursor.position.x, -0.5f * popupSize.height - grabHandle.size.height + cursor.position.y, 0.0f );
+        const HandleImpl& grabHandle = mHandle[GRAB_HANDLE];
+        if( grabHandle.verticallyFlipped )
+        {
+          mCopyPastePopup.position = Vector3( cursor.position.x, -0.5f * popupSize.height - grabHandle.size.height + cursor.position.y, 0.0f );
+        }
+        else
+        {
+          mCopyPastePopup.position = Vector3( cursor.position.x, -0.5f * popupSize.height + cursor.position.y, 0.0f );
+        }
       }
     }
 
@@ -616,13 +621,20 @@ struct Decorator::Impl : public ConnectionTracker
     return true;
   }
 
-  void SetupTouchEvents()
+  void SetupGestures()
   {
+    // Will consume tap gestures on handles.
     mTapDetector = TapGestureDetector::New();
-    mTapDetector.DetectedSignal().Connect( this, &Decorator::Impl::OnTap );
 
-    mPanGestureDetector = PanGestureDetector::New();
-    mPanGestureDetector.DetectedSignal().Connect( this, &Decorator::Impl::OnPan );
+    // Will consume double tap gestures on handles.
+    mTapDetector.SetMaximumTapsRequired( 2u );
+
+    // Will consume long press gestures on handles.
+    mLongPressDetector = LongPressGestureDetector::New();
+
+    // Detects pan gestures on handles.
+    mPanDetector = PanGestureDetector::New();
+    mPanDetector.DetectedSignal().Connect( this, &Decorator::Impl::OnPan );
   }
 
   void CreateActiveLayer()
@@ -689,9 +701,16 @@ struct Decorator::Impl : public ConnectionTracker
         grabHandle.actor.Add( grabHandle.grabArea );
         grabHandle.actor.SetColor( mHandleColor );
 
-        grabHandle.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnGrabHandleTouched );
-        mTapDetector.Attach( grabHandle.grabArea );
-        mPanGestureDetector.Attach( grabHandle.grabArea );
+        grabHandle.grabArea.TouchSignal().Connect( this, &Decorator::Impl::OnGrabHandleTouched );
+
+        // The grab handle's actor is attached to the tap and long press detectors in order to consume these events.
+        // Note that no callbacks are connected to any signal emitted by the tap and long press detectors.
+        mTapDetector.Attach( grabHandle.actor );
+        mLongPressDetector.Attach( grabHandle.actor );
+
+        // The grab handle's area is attached to the pan detector.
+        // The OnPan() method is connected to the signals emitted by the pan detector.
+        mPanDetector.Attach( grabHandle.grabArea );
 
         mActiveLayer.Add( grabHandle.actor );
       }
@@ -750,9 +769,16 @@ struct Decorator::Impl : public ConnectionTracker
         primary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
         primary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
 
-        mTapDetector.Attach( primary.grabArea );
-        mPanGestureDetector.Attach( primary.grabArea );
-        primary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleOneTouched );
+        primary.grabArea.TouchSignal().Connect( this, &Decorator::Impl::OnHandleOneTouched );
+
+        // The handle's actor is attached to the tap and long press detectors in order to consume these events.
+        // Note that no callbacks are connected to any signal emitted by the tap and long press detectors.
+        mTapDetector.Attach( primary.actor );
+        mLongPressDetector.Attach( primary.actor );
+
+        // The handle's area is attached to the pan detector.
+        // The OnPan() method is connected to the signals emitted by the pan detector.
+        mPanDetector.Attach( primary.grabArea );
 
         primary.actor.Add( primary.grabArea );
 
@@ -787,9 +813,16 @@ struct Decorator::Impl : public ConnectionTracker
         secondary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
         secondary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
 
-        mTapDetector.Attach( secondary.grabArea );
-        mPanGestureDetector.Attach( secondary.grabArea );
-        secondary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleTwoTouched );
+        secondary.grabArea.TouchSignal().Connect( this, &Decorator::Impl::OnHandleTwoTouched );
+
+        // The handle's actor is attached to the tap and long press detectors in order to consume these events.
+        // Note that no callbacks are connected to any signal emitted by the tap and long press detectors.
+        mTapDetector.Attach( secondary.actor );
+        mLongPressDetector.Attach( secondary.actor );
+
+        // The handle's area is attached to the pan detector.
+        // The OnPan() method is connected to the signals emitted by the pan detector.
+        mPanDetector.Attach( secondary.grabArea );
 
         secondary.actor.Add( secondary.grabArea );
 
@@ -1006,7 +1039,7 @@ struct Decorator::Impl : public ConnectionTracker
       if( !mHighlightQuadList.empty() )
       {
         Vector< Vector2 > vertices;
-        Vector< unsigned int> indices;
+        Vector< unsigned short> indices;
         Vector2 vertex;
 
         std::vector<QuadCoordinates>::iterator iter = mHighlightQuadList.begin();
@@ -1052,24 +1085,18 @@ struct Decorator::Impl : public ConnectionTracker
           mQuadVertices = PropertyBuffer::New( mQuadVertexFormat );
         }
 
-        if( ! mQuadIndices )
-        {
-          mQuadIndices = PropertyBuffer::New( mQuadIndexFormat );
-        }
-
         mQuadVertices.SetData( &vertices[ 0 ], vertices.Size() );
-        mQuadIndices.SetData( &indices[ 0 ], indices.Size() );
 
         if( !mQuadGeometry )
         {
           mQuadGeometry = Geometry::New();
           mQuadGeometry.AddVertexBuffer( mQuadVertices );
         }
-        mQuadGeometry.SetIndexBuffer( mQuadIndices );
+        mQuadGeometry.SetIndexBuffer( &indices[ 0 ], indices.Size() );
 
         if( !mHighlightRenderer )
         {
-          mHighlightRenderer = Dali::Renderer::New( mQuadGeometry, mHighlightMaterial );
+          mHighlightRenderer = Dali::Renderer::New( mQuadGeometry, mHighlightShader );
           mHighlightActor.AddRenderer( mHighlightRenderer );
         }
       }
@@ -1086,23 +1113,15 @@ struct Decorator::Impl : public ConnectionTracker
     }
   }
 
-  void OnTap( Actor actor, const TapGesture& tap )
-  {
-    if( actor == mHandle[GRAB_HANDLE].actor )
-    {
-      // TODO
-    }
-  }
-
   void DoPan( HandleImpl& handle, HandleType type, const PanGesture& gesture )
   {
     if( Gesture::Started == gesture.state )
     {
-      handle.grabDisplacementX = handle.grabDisplacementY = 0;
+      handle.grabDisplacementX = handle.grabDisplacementY = 0.f;
     }
 
     handle.grabDisplacementX += gesture.displacement.x;
-    handle.grabDisplacementY += gesture.displacement.y;
+    handle.grabDisplacementY += ( handle.verticallyFlipped ? -gesture.displacement.y : gesture.displacement.y );
 
     const float x = handle.position.x + handle.grabDisplacementX;
     const float y = handle.position.y + handle.lineHeight*0.5f + handle.grabDisplacementY;
@@ -1180,20 +1199,20 @@ struct Decorator::Impl : public ConnectionTracker
     }
   }
 
-  bool OnGrabHandleTouched( Actor actor, const TouchEvent& event )
+  bool OnGrabHandleTouched( Actor actor, const TouchData& touch )
   {
     // Switch between pressed/release grab-handle images
-    if( event.GetPointCount() > 0 &&
+    if( touch.GetPointCount() > 0 &&
         mHandle[GRAB_HANDLE].actor )
     {
-      const TouchPoint& point = event.GetPoint(0);
+      const PointState::Type state = touch.GetState( 0 );
 
-      if( TouchPoint::Down == point.state )
+      if( PointState::DOWN == state )
       {
         mHandle[GRAB_HANDLE].pressed = true;
       }
-      else if( ( TouchPoint::Up == point.state ) ||
-               ( TouchPoint::Interrupted == point.state ) )
+      else if( ( PointState::UP == state ) ||
+               ( PointState::INTERRUPTED == state ) )
       {
         mHandle[GRAB_HANDLE].pressed = false;
       }
@@ -1205,20 +1224,20 @@ struct Decorator::Impl : public ConnectionTracker
     return true;
   }
 
-  bool OnHandleOneTouched( Actor actor, const TouchEvent& event )
+  bool OnHandleOneTouched( Actor actor, const TouchData& touch )
   {
     // Switch between pressed/release selection handle images
-    if( event.GetPointCount() > 0 &&
+    if( touch.GetPointCount() > 0 &&
         mHandle[LEFT_SELECTION_HANDLE].actor )
     {
-      const TouchPoint& point = event.GetPoint(0);
+      const PointState::Type state = touch.GetState( 0 );
 
-      if( TouchPoint::Down == point.state )
+      if( PointState::DOWN == state )
       {
         mHandle[LEFT_SELECTION_HANDLE].pressed = true;
       }
-      else if( ( TouchPoint::Up == point.state ) ||
-               ( TouchPoint::Interrupted == point.state ) )
+      else if( ( PointState::UP == state ) ||
+               ( PointState::INTERRUPTED == state ) )
       {
         mHandle[LEFT_SELECTION_HANDLE].pressed = false;
         mHandlePreviousCrossed = mHandleCurrentCrossed;
@@ -1232,20 +1251,20 @@ struct Decorator::Impl : public ConnectionTracker
     return true;
   }
 
-  bool OnHandleTwoTouched( Actor actor, const TouchEvent& event )
+  bool OnHandleTwoTouched( Actor actor, const TouchData& touch )
   {
     // Switch between pressed/release selection handle images
-    if( event.GetPointCount() > 0 &&
+    if( touch.GetPointCount() > 0 &&
         mHandle[RIGHT_SELECTION_HANDLE].actor )
     {
-      const TouchPoint& point = event.GetPoint(0);
+      const PointState::Type state = touch.GetState( 0 );
 
-      if( TouchPoint::Down == point.state )
+      if( PointState::DOWN == state )
       {
         mHandle[RIGHT_SELECTION_HANDLE].pressed = true;
       }
-      else if( ( TouchPoint::Up == point.state ) ||
-               ( TouchPoint::Interrupted == point.state ) )
+      else if( ( PointState::UP == state ) ||
+               ( PointState::INTERRUPTED == state ) )
       {
         mHandle[RIGHT_SELECTION_HANDLE].pressed = false;
         mHandlePreviousCrossed = mHandleCurrentCrossed;
@@ -1638,8 +1657,10 @@ struct Decorator::Impl : public ConnectionTracker
 
   ControllerInterface& mController;
 
-  TapGestureDetector  mTapDetector;
-  PanGestureDetector  mPanGestureDetector;
+  TapGestureDetector       mTapDetector;
+  PanGestureDetector       mPanDetector;
+  LongPressGestureDetector mLongPressDetector;
+
   Timer               mCursorBlinkTimer;          ///< Timer to signal cursor to blink
   Timer               mScrollTimer;               ///< Timer used to scroll the text when the grab handle is moved close to the edges.
 
@@ -1653,9 +1674,8 @@ struct Decorator::Impl : public ConnectionTracker
 
   Actor               mHighlightActor;            ///< Actor to display highlight
   Renderer            mHighlightRenderer;
-  Material            mHighlightMaterial;         ///< Material used for highlight
+  Shader              mHighlightShader;           ///< Shader used for highlight
   Property::Map       mQuadVertexFormat;
-  Property::Map       mQuadIndexFormat;
   PopupImpl           mCopyPastePopup;
   TextSelectionPopup::Buttons mEnabledPopupButtons; /// Bit mask of currently enabled Popup buttons
   TextSelectionPopupCallbackInterface& mTextSelectionPopupCallbackInterface;
@@ -1667,7 +1687,6 @@ struct Decorator::Impl : public ConnectionTracker
   HandleImpl          mHandle[HANDLE_TYPE_COUNT];
 
   PropertyBuffer      mQuadVertices;
-  PropertyBuffer      mQuadIndices;
   Geometry            mQuadGeometry;
   QuadContainer       mHighlightQuadList;         ///< Sub-selections that combine to create the complete selection highlight