Fix cursor position issues.
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / decorator / text-decorator.cpp
index 441d179..8d55300 100644 (file)
@@ -273,6 +273,7 @@ struct Decorator::Impl : public ConnectionTracker
     mScrollDistance( SCROLL_DISTANCE ),
     mTextDepth( 0u ),
     mActiveCopyPastePopup( false ),
+    mPopupSetNewPosition( true ),
     mCursorBlinkStatus( true ),
     mDelayCursorBlink( false ),
     mPrimaryCursorVisible( false ),
@@ -307,13 +308,11 @@ struct Decorator::Impl : public ConnectionTracker
     if( mPrimaryCursor )
     {
       const CursorImpl& cursor = mCursor[PRIMARY_CURSOR];
-      mPrimaryCursorVisible = ( cursor.position.x <= size.width ) && ( cursor.position.x >= 0.f );
+      mPrimaryCursorVisible = ( cursor.position.x + mCursorWidth <= size.width ) && ( cursor.position.x >= 0.f );
       if( mPrimaryCursorVisible )
       {
-        const Vector2& position = cursor.position;
-
-        mPrimaryCursor.SetPosition( position.x,
-                                    position.y );
+        mPrimaryCursor.SetPosition( cursor.position.x,
+                                    cursor.position.y );
         mPrimaryCursor.SetSize( Size( mCursorWidth, cursor.cursorHeight ) );
       }
       mPrimaryCursor.SetVisible( mPrimaryCursorVisible && mCursorBlinkStatus );
@@ -321,7 +320,7 @@ struct Decorator::Impl : public ConnectionTracker
     if( mSecondaryCursor )
     {
       const CursorImpl& cursor = mCursor[SECONDARY_CURSOR];
-      mSecondaryCursorVisible = ( cursor.position.x <= size.width ) && ( cursor.position.x >= 0.f );
+      mSecondaryCursorVisible = ( cursor.position.x + mCursorWidth <= size.width ) && ( cursor.position.x >= 0.f );
       if( mSecondaryCursorVisible )
       {
         mSecondaryCursor.SetPosition( cursor.position.x,
@@ -335,9 +334,7 @@ struct Decorator::Impl : public ConnectionTracker
     HandleImpl& grabHandle = mHandle[GRAB_HANDLE];
     if( grabHandle.active )
     {
-      const Vector2& position = grabHandle.position;
-
-      const bool isVisible = ( position.x <= size.width ) && ( position.x >= 0.f );
+      const bool isVisible = ( grabHandle.position.x + floor( 0.5f * mCursorWidth ) <= size.width ) && ( grabHandle.position.x >= 0.f );
 
       if( isVisible )
       {
@@ -349,7 +346,11 @@ struct Decorator::Impl : public ConnectionTracker
         // Sets the grab handle image according if it's pressed, flipped, etc.
         SetHandleImage( GRAB_HANDLE );
       }
-      grabHandle.actor.SetVisible( isVisible );
+
+      if( grabHandle.actor )
+      {
+        grabHandle.actor.SetVisible( isVisible );
+      }
     }
     else if( grabHandle.actor )
     {
@@ -361,11 +362,8 @@ struct Decorator::Impl : public ConnectionTracker
     HandleImpl& secondary = mHandle[ RIGHT_SELECTION_HANDLE ];
     if( primary.active || secondary.active )
     {
-      const Vector2& primaryPosition = primary.position;
-      const Vector2& secondaryPosition = secondary.position;
-
-      const bool isPrimaryVisible = ( primaryPosition.x <= size.width ) && ( primaryPosition.x >= 0.f );
-      const bool isSecondaryVisible = ( secondaryPosition.x <= size.width ) && ( secondaryPosition.x >= 0.f );
+      const bool isPrimaryVisible = ( primary.position.x <= size.width ) && ( primary.position.x >= 0.f );
+      const bool isSecondaryVisible = ( secondary.position.x <= size.width ) && ( secondary.position.x >= 0.f );
 
       if( isPrimaryVisible || isSecondaryVisible )
       {
@@ -391,8 +389,15 @@ struct Decorator::Impl : public ConnectionTracker
           SetSelectionHandleMarkerSize( secondary );
         }
       }
-      primary.actor.SetVisible( isPrimaryVisible );
-      secondary.actor.SetVisible( isSecondaryVisible );
+
+      if( primary.actor )
+      {
+        primary.actor.SetVisible( isPrimaryVisible );
+      }
+      if( secondary.actor )
+      {
+        secondary.actor.SetVisible( isSecondaryVisible );
+      }
 
       CreateHighlight();
       UpdateHighlight();
@@ -422,6 +427,7 @@ struct Decorator::Impl : public ConnectionTracker
       if( mCopyPastePopup.actor )
       {
         mCopyPastePopup.actor.HidePopup();
+        mPopupSetNewPosition = true;
       }
     }
   }
@@ -459,19 +465,22 @@ struct Decorator::Impl : public ConnectionTracker
       return;
     }
 
-    if ( mHandle[LEFT_SELECTION_HANDLE].active || mHandle[RIGHT_SELECTION_HANDLE].active )
+    if( mPopupSetNewPosition )
     {
-      float minHandleXPosition = std::min (  mHandle[LEFT_SELECTION_HANDLE].position.x, mHandle[RIGHT_SELECTION_HANDLE].position.x );
-      float maxHandleXPosition = std::max (  mHandle[LEFT_SELECTION_HANDLE].position.x, mHandle[RIGHT_SELECTION_HANDLE].position.x );
+      if ( mHandle[LEFT_SELECTION_HANDLE].active || mHandle[RIGHT_SELECTION_HANDLE].active )
+      {
+        float minHandleXPosition = std::min (  mHandle[LEFT_SELECTION_HANDLE].position.x, mHandle[RIGHT_SELECTION_HANDLE].position.x );
+        float maxHandleXPosition = std::max (  mHandle[LEFT_SELECTION_HANDLE].position.x, mHandle[RIGHT_SELECTION_HANDLE].position.x );
 
-      float minHandleYPosition = std::min (  mHandle[LEFT_SELECTION_HANDLE].position.y, mHandle[RIGHT_SELECTION_HANDLE].position.y );
+        float minHandleYPosition = std::min (  mHandle[LEFT_SELECTION_HANDLE].position.y, mHandle[RIGHT_SELECTION_HANDLE].position.y );
 
-      mCopyPastePopup.position.x = minHandleXPosition + ( ( maxHandleXPosition - minHandleXPosition ) *0.5f );
-      mCopyPastePopup.position.y = minHandleYPosition + mCopyPastePopup.offset;
-    }
-    else
-    {
-      mCopyPastePopup.position = Vector3( mCursor[PRIMARY_CURSOR].position.x, mCursor[PRIMARY_CURSOR].position.y -100.0f , 0.0f ); //todo 100 to be an offset Property
+        mCopyPastePopup.position.x = minHandleXPosition + ( ( maxHandleXPosition - minHandleXPosition ) *0.5f );
+        mCopyPastePopup.position.y = minHandleYPosition + mCopyPastePopup.offset;
+      }
+      else
+      {
+        mCopyPastePopup.position = Vector3( mCursor[PRIMARY_CURSOR].position.x, mCursor[PRIMARY_CURSOR].position.y -100.0f , 0.0f ); //todo 100 to be an offset Property
+      }
     }
 
     Vector3 popupSize = Vector3( mCopyPastePopup.actor.GetRelayoutSize( Dimension::WIDTH ), mCopyPastePopup.actor.GetRelayoutSize( Dimension::HEIGHT ), 0.0f );
@@ -481,6 +490,7 @@ struct Decorator::Impl : public ConnectionTracker
     SetUpPopupPositionNotifications();
 
     mCopyPastePopup.actor.SetPosition( mCopyPastePopup.position );
+    mPopupSetNewPosition = false;
   }
 
   void PopupRelayoutComplete( Actor actor )
@@ -495,7 +505,7 @@ struct Decorator::Impl : public ConnectionTracker
     cursor = CreateSolidColorActor( color );
     cursor.SetSortModifier( DECORATION_DEPTH_INDEX );
     cursor.SetParentOrigin( ParentOrigin::TOP_LEFT ); // Need to set the default parent origin as CreateSolidColorActor() sets a different one.
-    cursor.SetAnchorPoint( AnchorPoint::TOP_RIGHT );
+    cursor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
   }
 
   // Add or Remove cursor(s) from parent
@@ -796,7 +806,7 @@ struct Decorator::Impl : public ConnectionTracker
     // The SetGrabHandleImage() method will change the orientation.
     const float yLocalPosition = grabHandle.verticallyFlipped ? grabHandle.position.y : grabHandle.position.y + grabHandle.lineHeight;
 
-    grabHandle.actor.SetPosition( grabHandle.position.x - floor( 0.5f * mCursorWidth ),
+    grabHandle.actor.SetPosition( grabHandle.position.x + floor( 0.5f * mCursorWidth ),
                                   yLocalPosition ); // TODO : Fix for multiline.
   }
 
@@ -1405,6 +1415,7 @@ struct Decorator::Impl : public ConnectionTracker
   int                 mTextDepth;               ///< The depth used to render the text.
 
   bool                mActiveCopyPastePopup              : 1;
+  bool                mPopupSetNewPosition               : 1;
   bool                mCursorBlinkStatus                 : 1; ///< Flag to switch between blink on and blink off.
   bool                mDelayCursorBlink                  : 1; ///< Used to avoid cursor blinking when entering text.
   bool                mPrimaryCursorVisible              : 1; ///< Whether the primary cursor is visible.
@@ -1677,19 +1688,19 @@ bool Decorator::IsPopupActive() const
 
 void Decorator::SetEnabledPopupButtons( TextSelectionPopup::Buttons& enabledButtonsBitMask )
 {
-   mImpl->mEnabledPopupButtons = enabledButtonsBitMask;
+  mImpl->mEnabledPopupButtons = enabledButtonsBitMask;
 
-   if ( !mImpl->mCopyPastePopup.actor )
-   {
-     mImpl->mCopyPastePopup.actor = TextSelectionPopup::New( &mImpl->mTextSelectionPopupCallbackInterface );
+  if ( !mImpl->mCopyPastePopup.actor )
+  {
+    mImpl->mCopyPastePopup.actor = TextSelectionPopup::New( &mImpl->mTextSelectionPopupCallbackInterface );
 #ifdef DECORATOR_DEBUG
-     mImpl->mCopyPastePopup.actor.SetName("mCopyPastePopup");
+    mImpl->mCopyPastePopup.actor.SetName("mCopyPastePopup");
 #endif
-     mImpl->mCopyPastePopup.actor.SetAnchorPoint( AnchorPoint::CENTER );
-     mImpl->mCopyPastePopup.actor.OnRelayoutSignal().Connect( mImpl,  &Decorator::Impl::PopupRelayoutComplete  ); // Position popup after size negotiation
-   }
+    mImpl->mCopyPastePopup.actor.SetAnchorPoint( AnchorPoint::CENTER );
+    mImpl->mCopyPastePopup.actor.OnRelayoutSignal().Connect( mImpl,  &Decorator::Impl::PopupRelayoutComplete  ); // Position popup after size negotiation
+  }
 
-   mImpl->mCopyPastePopup.actor.EnableButtons( mImpl->mEnabledPopupButtons );
+  mImpl->mCopyPastePopup.actor.EnableButtons( mImpl->mEnabledPopupButtons );
 }
 
 TextSelectionPopup::Buttons& Decorator::GetEnabledPopupButtons()