Make cursor invisible when exceeds the boundaries of the Text Control.
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / decorator / text-decorator.cpp
index c324edc..32e3bec 100644 (file)
@@ -200,7 +200,9 @@ struct Decorator::Impl : public ConnectionTracker
     mActiveGrabHandle( false ),
     mActiveSelection( false ),
     mActiveCopyPastePopup( false ),
-    mCursorBlinkStatus( true )
+    mCursorBlinkStatus( true ),
+    mPrimaryCursorVisible( false ),
+    mSecondaryCursorVisible( false )
   {
   }
 
@@ -208,7 +210,7 @@ struct Decorator::Impl : public ConnectionTracker
    * Relayout of the decorations owned by the decorator.
    * @param[in] size The Size of the UI control the decorator is adding it's decorations to.
    */
-  void Relayout( const Vector2& size, const Vector2& scrollPosition )
+  void Relayout( const Vector2& size )
   {
     // TODO - Remove this if nothing is active
     CreateActiveLayer();
@@ -217,26 +219,42 @@ struct Decorator::Impl : public ConnectionTracker
     CreateCursors();
     if( mPrimaryCursor )
     {
-      mPrimaryCursor.SetPosition( mCursor[PRIMARY_CURSOR].position.x + scrollPosition.x,
-                                  mCursor[PRIMARY_CURSOR].position.y + scrollPosition.y );
-      mPrimaryCursor.SetSize( Size( 1.0f, mCursor[PRIMARY_CURSOR].cursorHeight ) );
+      mPrimaryCursorVisible = ( mCursor[PRIMARY_CURSOR].position.x <= size.width ) && ( mCursor[PRIMARY_CURSOR].position.x >= 0.f );
+      if( mPrimaryCursorVisible )
+      {
+        mPrimaryCursor.SetPosition( mCursor[PRIMARY_CURSOR].position.x,
+                                    mCursor[PRIMARY_CURSOR].position.y );
+        mPrimaryCursor.SetSize( Size( 1.0f, mCursor[PRIMARY_CURSOR].cursorHeight ) );
+      }
+      mPrimaryCursor.SetVisible( mPrimaryCursorVisible );
     }
     if( mSecondaryCursor )
     {
-      mSecondaryCursor.SetPosition( mCursor[SECONDARY_CURSOR].position.x + scrollPosition.x,
-                                    mCursor[SECONDARY_CURSOR].position.y + scrollPosition.y );
-      mSecondaryCursor.SetSize( Size( 1.0f, mCursor[SECONDARY_CURSOR].cursorHeight ) );
+      mSecondaryCursorVisible = ( mCursor[SECONDARY_CURSOR].position.x <= size.width ) && ( mCursor[SECONDARY_CURSOR].position.x >= 0.f );
+      if( mSecondaryCursorVisible )
+      {
+        mSecondaryCursor.SetPosition( mCursor[SECONDARY_CURSOR].position.x,
+                                      mCursor[SECONDARY_CURSOR].position.y );
+        mSecondaryCursor.SetSize( Size( 1.0f, mCursor[SECONDARY_CURSOR].cursorHeight ) );
+      }
+      mSecondaryCursor.SetVisible( mSecondaryCursorVisible );
     }
 
     // Show or hide the grab handle
     if( mActiveGrabHandle )
     {
-      SetupTouchEvents();
+      const bool isVisible = ( mCursor[PRIMARY_CURSOR].position.x <= size.width ) && ( mCursor[PRIMARY_CURSOR].position.x >= 0.f );
 
-      CreateGrabHandle();
+      if( isVisible )
+      {
+        SetupTouchEvents();
+
+        CreateGrabHandle();
 
-      mGrabHandle.SetPosition( mCursor[PRIMARY_CURSOR].position.x + scrollPosition.x,
-                               mCursor[PRIMARY_CURSOR].position.y + mCursor[PRIMARY_CURSOR].lineHeight + scrollPosition.y );
+        mGrabHandle.SetPosition( mCursor[PRIMARY_CURSOR].position.x,
+                                 mCursor[PRIMARY_CURSOR].position.y + mCursor[PRIMARY_CURSOR].lineHeight );
+      }
+      mGrabHandle.SetVisible( isVisible );
     }
     else if( mGrabHandle )
     {
@@ -251,12 +269,12 @@ struct Decorator::Impl : public ConnectionTracker
       CreateSelectionHandles();
 
       SelectionHandleImpl& primary = mSelectionHandle[ PRIMARY_SELECTION_HANDLE ];
-      primary.actor.SetPosition( primary.position.x + scrollPosition.x,
-                                 primary.position.y + primary.lineHeight + scrollPosition.y );
+      primary.actor.SetPosition( primary.position.x,
+                                 primary.position.y + primary.lineHeight );
 
       SelectionHandleImpl& secondary = mSelectionHandle[ SECONDARY_SELECTION_HANDLE ];
-      secondary.actor.SetPosition( secondary.position.x + scrollPosition.x,
-                                   secondary.position.y + secondary.lineHeight + scrollPosition.y );
+      secondary.actor.SetPosition( secondary.position.x,
+                                   secondary.position.y + secondary.lineHeight );
 
       CreateHighlight();
       UpdateHighlight();
@@ -290,6 +308,16 @@ struct Decorator::Impl : public ConnectionTracker
     }
   }
 
+  void UpdatePositions( const Vector2& scrollOffset )
+  {
+    mCursor[PRIMARY_CURSOR].position += scrollOffset;
+    mCursor[SECONDARY_CURSOR].position += scrollOffset;
+    mSelectionHandle[ PRIMARY_SELECTION_HANDLE ].position += scrollOffset;
+    mSelectionHandle[ SECONDARY_SELECTION_HANDLE ].position += scrollOffset;
+
+    // TODO Highlight box??
+  }
+
   void PopUpRelayoutComplete( Actor actor )
   {
     // Size negotiation for CopyPastePopup complete so can get the size and constrain position within bounding box.
@@ -361,11 +389,11 @@ struct Decorator::Impl : public ConnectionTracker
     // Cursor blinking
     if ( mPrimaryCursor )
     {
-      mPrimaryCursor.SetVisible( mCursorBlinkStatus );
+      mPrimaryCursor.SetVisible( mPrimaryCursorVisible && mCursorBlinkStatus );
     }
     if ( mSecondaryCursor )
     {
-      mSecondaryCursor.SetVisible( mCursorBlinkStatus );
+      mSecondaryCursor.SetVisible( mSecondaryCursorVisible && mCursorBlinkStatus );
     }
 
     mCursorBlinkStatus = !mCursorBlinkStatus;
@@ -816,10 +844,12 @@ struct Decorator::Impl : public ConnectionTracker
   float               mGrabDisplacementX;
   float               mGrabDisplacementY;
 
-  bool                mActiveGrabHandle:1;
-  bool                mActiveSelection:1;
-  bool                mActiveCopyPastePopup:1;
-  bool                mCursorBlinkStatus:1;       ///< Flag to switch between blink on and blink off
+  bool                mActiveGrabHandle       : 1;
+  bool                mActiveSelection        : 1;
+  bool                mActiveCopyPastePopup   : 1;
+  bool                mCursorBlinkStatus      : 1; ///< Flag to switch between blink on and blink off.
+  bool                mPrimaryCursorVisible   : 1; ///< Whether the primary cursor is visible.
+  bool                mSecondaryCursorVisible : 1; ///< Whether the secondary cursor is visible.
 };
 
 DecoratorPtr Decorator::New( Internal::Control& parent, Observer& observer )
@@ -837,9 +867,14 @@ const Rect<int>& Decorator::GetBoundingBox() const
   return mImpl->mBoundingBox;
 }
 
-void Decorator::Relayout( const Vector2& size, const Vector2& scrollPosition )
+void Decorator::Relayout( const Vector2& size )
+{
+  mImpl->Relayout( size );
+}
+
+void Decorator::UpdatePositions( const Vector2& scrollOffset )
 {
-  mImpl->Relayout( size, scrollPosition );
+  mImpl->UpdatePositions( scrollOffset );
 }
 
 /** Cursor **/
@@ -857,8 +892,11 @@ unsigned int Decorator::GetActiveCursor() const
 void Decorator::SetPosition( Cursor cursor, float x, float y, float cursorHeight, float lineHeight )
 {
   // Adjust grab handle displacement
-  mImpl->mGrabDisplacementX -= x - mImpl->mCursor[cursor].position.x;
-  mImpl->mGrabDisplacementY -= y - mImpl->mCursor[cursor].position.y;
+  if( PRIMARY_CURSOR == cursor )
+  {
+    mImpl->mGrabDisplacementX -= x - mImpl->mCursor[cursor].position.x;
+    mImpl->mGrabDisplacementY -= y - mImpl->mCursor[cursor].position.y;
+  }
 
   mImpl->mCursor[cursor].position.x = x;
   mImpl->mCursor[cursor].position.y = y;
@@ -874,6 +912,11 @@ void Decorator::GetPosition( Cursor cursor, float& x, float& y, float& cursorHei
   lineHeight = mImpl->mCursor[cursor].lineHeight;
 }
 
+const Vector2& Decorator::GetPosition( Cursor cursor ) const
+{
+  return mImpl->mCursor[cursor].position;
+}
+
 void Decorator::SetColor( Cursor cursor, const Dali::Vector4& color )
 {
   mImpl->mCursor[cursor].color = color;