TextContoller Copy and Cut buttons functional
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller.cpp
index 3b36ed3..55ece1c 100644 (file)
@@ -47,6 +47,12 @@ const float MAX_FLOAT = std::numeric_limits<float>::max();
 
 const std::string EMPTY_STRING("");
 
+float ConvertToEven( float value )
+{
+  int intValue(static_cast<int>( value ));
+  return static_cast<float>(intValue % 2 == 0) ? intValue : (intValue + 1);
+}
+
 } // namespace
 
 namespace Dali
@@ -533,6 +539,9 @@ Vector3 Controller::GetNaturalSize()
     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::GetNaturalSize cached %f,%f,%f\n", naturalSize.x, naturalSize.y, naturalSize.z );
   }
 
+  naturalSize.x = ConvertToEven( naturalSize.x );
+  naturalSize.y = ConvertToEven( naturalSize.y );
+
   return naturalSize;
 }
 
@@ -590,9 +599,9 @@ bool Controller::Relayout( const Size& size )
   if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
   {
     bool glyphsRemoved( false );
-    if( 0u != mImpl->mVisualModel->GetNumberOfGlyphPositions() )
+    if( 0u != mImpl->mVisualModel->mGlyphPositions.Count() )
     {
-      mImpl->mVisualModel->SetGlyphPositions( NULL, 0u );
+      mImpl->mVisualModel->mGlyphPositions.Clear();
       glyphsRemoved = true;
     }
     // Not worth to relayout if width or height is equal to zero.
@@ -790,7 +799,7 @@ bool Controller::DoRelayout( const Size& size,
     // after the first time the text has been laid out.
     // Fill the vectors again.
 
-    Length numberOfGlyphs = mImpl->mVisualModel->GetNumberOfGlyphs();
+    Length numberOfGlyphs = mImpl->mVisualModel->mGlyphs.Count();
 
     if( 0u == numberOfGlyphs )
     {
@@ -850,7 +859,7 @@ bool Controller::DoRelayout( const Size& size,
         if( 0u != bidirectionalInfo.Count() )
         {
           // Get the lines
-          const Length numberOfLines = mImpl->mVisualModel->GetNumberOfLines();
+          const Length numberOfLines = mImpl->mVisualModel->mLines.Count();
 
           // Reorder the lines.
           Vector<BidirectionalLineInfoRun> lineBidirectionalInfoRuns;
@@ -1256,7 +1265,7 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
       }
     }
 
-    const Length numberOfCharactersInModel = mImpl->mLogicalModel->GetNumberOfCharacters();
+    const Length numberOfCharactersInModel = mImpl->mLogicalModel->mText.Count();
 
     // Restrict new text to fit within Maximum characters setting
     Length maxSizeOfNewText = std::min ( ( mImpl->mMaximumNumberOfCharacters - numberOfCharactersInModel ), characterCount );
@@ -1312,36 +1321,32 @@ void Controller::TapEvent( unsigned int tapCount, float x, float y )
 
       if( !isShowingPlaceholderText && tapDuringEditMode )
       {
-        // Grab handle is not shown until a tap is received whilst EDITING
-        if( tapDuringEditMode )
-        {
-          mImpl->mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, true );
-        }
+        mImpl->mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, true );
         mImpl->mEventData->mDecorator->SetPopupActive( false );
       }
 
       mImpl->ChangeState( EventData::EDITING );
+
+      // Handles & cursors must be repositioned after Relayout() i.e. after the Model has been updated
+      if( mImpl->mEventData )
+      {
+        Event event( Event::TAP_EVENT );
+        event.p1.mUint = tapCount;
+        event.p2.mFloat = x;
+        event.p3.mFloat = y;
+        mImpl->mEventData->mEventQueue.push_back( event );
+
+        mImpl->RequestRelayout();
+      }
     }
     else if( !isShowingPlaceholderText &&
              mImpl->mEventData->mSelectionEnabled &&
              ( 2u == tapCount ) )
     {
-      mImpl->ChangeState( EventData::SELECTING );
+      SelectEvent( x, y, false );
     }
   }
 
-  // Handles & cursors must be repositioned after Relayout() i.e. after the Model has been updated
-  if( mImpl->mEventData )
-  {
-    Event event( Event::TAP_EVENT );
-    event.p1.mUint = tapCount;
-    event.p2.mFloat = x;
-    event.p3.mFloat = y;
-    mImpl->mEventData->mEventQueue.push_back( event );
-
-    mImpl->RequestRelayout();
-  }
-
   // Reset keyboard as tap event has occurred.
   mImpl->ResetImfManager();
 }
@@ -1362,6 +1367,36 @@ void Controller::PanEvent( Gesture::State state, const Vector2& displacement )
   }
 }
 
+void Controller::SelectEvent( float x, float y, bool selectAll )
+{
+  if( mImpl->mEventData )
+  {
+    if ( mImpl->mEventData->mState == EventData::SELECTING )
+    {
+      mImpl->ChangeState( EventData::SELECTION_CHANGED );
+    }
+    else
+    {
+      mImpl->ChangeState( EventData::SELECTING );
+    }
+
+    if( selectAll )
+    {
+      Event event( Event::SELECT_ALL );
+      mImpl->mEventData->mEventQueue.push_back( event );
+    }
+    else
+    {
+      Event event( Event::SELECT );
+      event.p2.mFloat = x;
+      event.p3.mFloat = y;
+      mImpl->mEventData->mEventQueue.push_back( event );
+    }
+
+    mImpl->RequestRelayout();
+  }
+}
+
 void Controller::GetTargetSize( Vector2& targetSize )
 {
   targetSize = mImpl->mControlSize;
@@ -1420,6 +1455,73 @@ void Controller::DecorationEvent( HandleType handleType, HandleState state, floa
   }
 }
 
+void Controller::TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Buttons button )
+{
+  if( NULL == mImpl->mEventData )
+  {
+    return;
+  }
+
+  switch( button )
+  {
+    case Toolkit::TextSelectionPopup::CUT:
+    {
+      mImpl->SendSelectionToClipboard( true ); // Synchronous call to modify text
+      mImpl->mOperationsPending = ALL_OPERATIONS;
+      if( 0u != mImpl->mLogicalModel->mText.Count() ||
+          !mImpl->IsPlaceholderAvailable() )
+      {
+        mImpl->QueueModifyEvent( ModifyEvent::TEXT_DELETED );
+      }
+      else
+      {
+        ShowPlaceholderText();
+        mImpl->mEventData->mUpdateCursorPosition = true;
+      }
+      mImpl->RequestRelayout();
+      mImpl->mControlInterface.TextChanged();
+      break;
+    }
+    case Toolkit::TextSelectionPopup::COPY:
+    {
+      mImpl->SendSelectionToClipboard( false ); // Text not modified
+      mImpl->RequestRelayout(); // Handles, Selection Highlight, Popup
+      break;
+    }
+    case Toolkit::TextSelectionPopup::PASTE:
+    {
+      mImpl->PasteTextFromClipboard();
+      break;
+    }
+    case Toolkit::TextSelectionPopup::SELECT:
+    {
+      const Vector2& currentCursorPosition = mImpl->mEventData->mDecorator->GetPosition( PRIMARY_CURSOR );
+
+      if( mImpl->mEventData->mSelectionEnabled  )
+      {
+        // Creates a SELECT event.
+        SelectEvent( currentCursorPosition.x, currentCursorPosition.y, false );
+      }
+      break;
+    }
+    case Toolkit::TextSelectionPopup::SELECT_ALL:
+    {
+      // Creates a SELECT_ALL event
+      SelectEvent( 0.f, 0.f, true );
+      break;
+    }
+    case Toolkit::TextSelectionPopup::CLIPBOARD:
+    {
+      break;
+    }
+    case Toolkit::TextSelectionPopup::NONE:
+    {
+      // Nothing to do.
+      break;
+    }
+  }
+}
+
 ImfManager::ImfCallbackData Controller::OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
 {
   bool update( false );