Fix for text cursor.
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller-impl.cpp
index 7a51b86..5dc17a4 100644 (file)
@@ -136,7 +136,8 @@ EventData::EventData( DecoratorPtr decorator )
   mUpdateLeftSelectionPosition( false ),
   mUpdateRightSelectionPosition( false ),
   mScrollAfterUpdatePosition( false ),
-  mScrollAfterDelete( false )
+  mScrollAfterDelete( false ),
+  mAllTextSelected( false )
 {}
 
 EventData::~EventData()
@@ -237,6 +238,7 @@ bool Controller::Impl::ProcessInputEvents()
         leftScroll = true;
       }
 
+      SetPopupButtons();
       mEventData->mDecoratorUpdated = true;
       mEventData->mUpdateLeftSelectionPosition = false;
     }
@@ -253,6 +255,7 @@ bool Controller::Impl::ProcessInputEvents()
         rightScroll = true;
       }
 
+      SetPopupButtons();
       mEventData->mDecoratorUpdated = true;
       mEventData->mUpdateRightSelectionPosition = false;
     }
@@ -823,6 +826,22 @@ void Controller::Impl::RetrieveSelection( std::string& selectedText, bool delete
   }
 }
 
+void Controller::Impl::ShowClipboard()
+{
+  if ( mClipboard )
+  {
+    mClipboard.ShowClipboard();
+  }
+}
+
+void Controller::Impl::HideClipboard()
+{
+  if ( mClipboard )
+  {
+    mClipboard.HideClipboard();
+  }
+}
+
 bool Controller::Impl::CopyStringToClipboard( std::string& source )
 {
   //Send string to clipboard
@@ -950,6 +969,47 @@ void Controller::Impl::RepositionSelectionHandles( float visualX, float visualY
   RepositionSelectionHandles( selectionStart, selectionEnd );
 }
 
+void Controller::Impl::SetPopupButtons()
+{
+  /**
+   *  Sets the Popup buttons to be shown depending on State.
+   *
+   *  If SELECTING :  CUT & COPY + ( PASTE & CLIPBOARD if content available to paste )
+   *
+   *  If EDITING_WITH_POPUP : SELECT & SELECT_ALL
+   */
+
+  TextSelectionPopup::Buttons buttonsToShow = TextSelectionPopup::NONE;
+
+  if ( ( EventData::SELECTING == mEventData->mState ) || ( EventData::SELECTION_CHANGED == mEventData->mState ) )
+  {
+    buttonsToShow = TextSelectionPopup::Buttons(  TextSelectionPopup::CUT | TextSelectionPopup::COPY );
+
+    if ( !IsClipboardEmpty() )
+    {
+      buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::PASTE ) );
+      buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::CLIPBOARD ) );
+    }
+
+    if ( !mEventData->mAllTextSelected )
+    {
+      buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::SELECT_ALL ) );
+    }
+  }
+  else if  ( EventData::EDITING_WITH_POPUP == mEventData->mState )
+  {
+    buttonsToShow = TextSelectionPopup::Buttons( TextSelectionPopup::SELECT | TextSelectionPopup::SELECT_ALL );
+
+    if ( !IsClipboardEmpty() )
+    {
+      buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::PASTE ) );
+      buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::CLIPBOARD ) );
+    }
+  }
+
+  mEventData->mDecorator->SetEnabledPopupButtons( buttonsToShow );
+}
+
 void Controller::Impl::ChangeState( EventData::State newState )
 {
   if( NULL == mEventData )
@@ -971,6 +1031,7 @@ void Controller::Impl::ChangeState( EventData::State newState )
       mEventData->mDecorator->SetHandleActive( RIGHT_SELECTION_HANDLE, false );
       mEventData->mDecorator->SetPopupActive( false );
       mEventData->mDecoratorUpdated = true;
+      HideClipboard();
     }
     else if ( EventData::SELECTING == mEventData->mState )
     {
@@ -981,13 +1042,7 @@ void Controller::Impl::ChangeState( EventData::State newState )
       mEventData->mDecorator->SetHandleActive( RIGHT_SELECTION_HANDLE, true );
       if( mEventData->mGrabHandlePopupEnabled )
       {
-        TextSelectionPopup::Buttons buttonsToShow = TextSelectionPopup::Buttons(  TextSelectionPopup::CUT | TextSelectionPopup::COPY );
-        if ( !IsClipboardEmpty() )
-        {
-          buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::PASTE ) );
-        }
-
-        mEventData->mDecorator->SetEnabledPopupButtons( buttonsToShow );
+        SetPopupButtons();
         mEventData->mDecorator->SetPopupActive( true );
       }
       mEventData->mDecoratorUpdated = true;
@@ -996,13 +1051,8 @@ void Controller::Impl::ChangeState( EventData::State newState )
     {
       if( mEventData->mGrabHandlePopupEnabled )
       {
-        TextSelectionPopup::Buttons buttonsToShow = TextSelectionPopup::Buttons(  TextSelectionPopup::CUT | TextSelectionPopup::COPY );
-        if (  !IsClipboardEmpty() )
-        {
-          buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::PASTE ) );
-        }
+        SetPopupButtons();
         mEventData->mDecorator->SetActiveCursor( ACTIVE_CURSOR_NONE );
-        mEventData->mDecorator->SetEnabledPopupButtons( buttonsToShow );
         mEventData->mDecorator->SetPopupActive( true );
       }
       mEventData->mDecoratorUpdated = true;
@@ -1023,6 +1073,7 @@ void Controller::Impl::ChangeState( EventData::State newState )
         mEventData->mDecorator->SetPopupActive( false );
       }
       mEventData->mDecoratorUpdated = true;
+      HideClipboard();
     }
     else if( EventData::EDITING_WITH_POPUP == mEventData->mState )
     {
@@ -1042,16 +1093,10 @@ void Controller::Impl::ChangeState( EventData::State newState )
       }
       if( mEventData->mGrabHandlePopupEnabled )
       {
-        TextSelectionPopup::Buttons buttonsToShow = TextSelectionPopup::Buttons( TextSelectionPopup::SELECT | TextSelectionPopup::SELECT_ALL );
-
-        if ( !IsClipboardEmpty() )
-        {
-          buttonsToShow = TextSelectionPopup::Buttons ( ( buttonsToShow | TextSelectionPopup::PASTE ) );
-        }
-
-        mEventData->mDecorator->SetEnabledPopupButtons( buttonsToShow );
+        SetPopupButtons();
         mEventData->mDecorator->SetPopupActive( true );
       }
+      HideClipboard();
       mEventData->mDecoratorUpdated = true;
     }
     else if ( EventData::SELECTION_HANDLE_PANNING == mEventData->mState )
@@ -1269,7 +1314,7 @@ void Controller::Impl::GetCursorPosition( CharacterIndex logical,
     cursorInfo.lineHeight = fontMetrics.ascender - fontMetrics.descender;
     cursorInfo.primaryCursorHeight = cursorInfo.lineHeight;
 
-    cursorInfo.primaryPosition.x = 0.f;
+    cursorInfo.primaryPosition.x = 1.f;
     cursorInfo.primaryPosition.y = 0.f;
 
     // Nothing else to do.
@@ -1618,6 +1663,11 @@ void Controller::Impl::UpdateSelectionHandle( HandleType handleType )
                                        cursorPosition.x,
                                        cursorPosition.y,
                                        cursorInfo.lineHeight );
+
+  // If selection handle at start of the text and other at end of the text then all text is selected.
+  const CharacterIndex startOfSelection = std::min( mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition );
+  const CharacterIndex endOfSelection = std::max ( mEventData->mLeftSelectionPosition, mEventData->mRightSelectionPosition );
+  mEventData->mAllTextSelected = ( startOfSelection == 0 ) && ( endOfSelection == mLogicalModel->mText.Count() );
 }
 
 void Controller::Impl::ClampHorizontalScroll( const Vector2& actualSize )
@@ -1693,41 +1743,51 @@ void Controller::Impl::ScrollTextToMatchCursor()
   mEventData->mScrollPosition.x = currentCursorPosition.x - cursorInfo.primaryPosition.x - mAlignmentOffset.x;
 
   ClampHorizontalScroll( mVisualModel->GetActualSize() );
-  bool updateCursorPosition = true;
 
   const Vector2 offset = mEventData->mScrollPosition + mAlignmentOffset;
   const Vector2 cursorPosition = cursorInfo.primaryPosition + offset;
 
-  if( updateCursorPosition )
-  {
-    // Sets the cursor position.
-    mEventData->mDecorator->SetPosition( PRIMARY_CURSOR,
-                                         cursorPosition.x,
-                                         cursorPosition.y,
-                                         cursorInfo.primaryCursorHeight,
-                                         cursorInfo.lineHeight );
+  // Sets the cursor position.
+  mEventData->mDecorator->SetPosition( PRIMARY_CURSOR,
+                                       cursorPosition.x,
+                                       cursorPosition.y,
+                                       cursorInfo.primaryCursorHeight,
+                                       cursorInfo.lineHeight );
 
-    // Sets the grab handle position.
-    mEventData->mDecorator->SetPosition( GRAB_HANDLE,
-                                         cursorPosition.x,
-                                         cursorPosition.y,
+  // Sets the grab handle position.
+  mEventData->mDecorator->SetPosition( GRAB_HANDLE,
+                                       cursorPosition.x,
+                                       cursorPosition.y,
+                                       cursorInfo.lineHeight );
+
+  if( cursorInfo.isSecondaryCursor )
+  {
+    mEventData->mDecorator->SetPosition( SECONDARY_CURSOR,
+                                         cursorInfo.secondaryPosition.x + offset.x,
+                                         cursorInfo.secondaryPosition.y + offset.y,
+                                         cursorInfo.secondaryCursorHeight,
                                          cursorInfo.lineHeight );
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Secondary cursor position: %f,%f\n", cursorInfo.secondaryPosition.x + offset.x, cursorInfo.secondaryPosition.y + offset.y );
+  }
 
+  // Set which cursors are active according the state.
+  if( ( EventData::EDITING == mEventData->mState ) ||
+      ( EventData::EDITING_WITH_POPUP == mEventData->mState ) ||
+      ( EventData::GRAB_HANDLE_PANNING == mEventData->mState ) )
+  {
     if( cursorInfo.isSecondaryCursor )
     {
       mEventData->mDecorator->SetActiveCursor( ACTIVE_CURSOR_BOTH );
-      mEventData->mDecorator->SetPosition( SECONDARY_CURSOR,
-                                           cursorInfo.secondaryPosition.x + offset.x,
-                                           cursorInfo.secondaryPosition.y + offset.y,
-                                           cursorInfo.secondaryCursorHeight,
-                                           cursorInfo.lineHeight );
-      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Secondary cursor position: %f,%f\n", cursorInfo.secondaryPosition.x + offset.x, cursorInfo.secondaryPosition.y + offset.y );
     }
     else
     {
       mEventData->mDecorator->SetActiveCursor( ACTIVE_CURSOR_PRIMARY );
     }
   }
+  else
+  {
+    mEventData->mDecorator->SetActiveCursor( ACTIVE_CURSOR_NONE );
+  }
 }
 
 void Controller::Impl::RequestRelayout()