Text logical and visual models. Remove unused/unwanted code.
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / text-controller.cpp
index d584c73..de3aa91 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
@@ -337,8 +343,7 @@ bool Controller::RemoveText( int cursorOffset, int numberOfChars )
       numberOfChars = currentText.Count() - cursorIndex;
     }
 
-    if( cursorIndex >= 0 &&
-        (cursorIndex + numberOfChars) <= currentText.Count() )
+    if( (cursorIndex + numberOfChars) <= currentText.Count() )
     {
       Vector<Character>::Iterator first = currentText.Begin() + cursorIndex;
       Vector<Character>::Iterator last  = first + numberOfChars;
@@ -534,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;
 }
 
@@ -591,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.
@@ -709,7 +717,7 @@ void Controller::ResetScrollPosition()
   {
     // Reset the scroll position.
     mImpl->mEventData->mScrollPosition = Vector2::ZERO;
-    mImpl->mEventData->mScrollAfterUpdateCursorPosition = true;
+    mImpl->mEventData->mScrollAfterUpdatePosition = true;
   }
 }
 
@@ -750,7 +758,7 @@ void Controller::TextInsertedEvent()
 
   // Queue a cursor reposition event; this must wait until after DoRelayout()
   mImpl->mEventData->mUpdateCursorPosition = true;
-  mImpl->mEventData->mScrollAfterUpdateCursorPosition = true;
+  mImpl->mEventData->mScrollAfterUpdatePosition = true;
 }
 
 void Controller::TextDeletedEvent()
@@ -772,8 +780,7 @@ void Controller::TextDeletedEvent()
                                                            REORDER );
 
   // Queue a cursor reposition event; this must wait until after DoRelayout()
-  mImpl->mEventData->mUpdateCursorPosition = true;
-  mImpl->mEventData->mScrollAfterUpdateCursorPosition = true;
+  mImpl->mEventData->mScrollAfterDelete = true;
 }
 
 bool Controller::DoRelayout( const Size& size,
@@ -792,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 )
     {
@@ -852,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;
@@ -1114,6 +1121,9 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
     int keyCode = keyEvent.keyCode;
     const std::string& keyString = keyEvent.keyPressed;
 
+    // Hide the grab handle.
+    mImpl->mEventData->mDecorator->SetHandleActive( GRAB_HANDLE, false );
+
     // Pre-process to separate modifying events from non-modifying input events.
     if( Dali::DALI_KEY_ESCAPE == keyCode )
     {
@@ -1141,14 +1151,15 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
 
       if( removed )
       {
-        if( 0u == mImpl->mLogicalModel->mText.Count() )
+        if( 0u != mImpl->mLogicalModel->mText.Count() ||
+            !mImpl->IsPlaceholderAvailable() )
         {
-          ShowPlaceholderText();
-          mImpl->mEventData->mUpdateCursorPosition = true;
+          mImpl->QueueModifyEvent( ModifyEvent::TEXT_DELETED );
         }
         else
         {
-          mImpl->QueueModifyEvent( ModifyEvent::TEXT_DELETED );
+          ShowPlaceholderText();
+          mImpl->mEventData->mUpdateCursorPosition = true;
         }
 
         textChanged = true;
@@ -1254,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 );
@@ -1303,42 +1314,39 @@ void Controller::TapEvent( unsigned int tapCount, float x, float y )
 
   if( NULL != mImpl->mEventData )
   {
+    const bool isShowingPlaceholderText = mImpl->IsShowingPlaceholderText();
     if( 1u == tapCount )
     {
       bool tapDuringEditMode( EventData::EDITING == mImpl->mEventData->mState );
 
-      if( ! mImpl->IsShowingPlaceholderText() &&
-          EventData::EDITING == mImpl->mEventData->mState )
+      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( mImpl->mEventData->mSelectionEnabled &&
+    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();
 }
@@ -1359,14 +1367,44 @@ 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;
 }
 
-void Controller::AddDecoration( Actor& actor )
+void Controller::AddDecoration( Actor& actor, bool needsClipping )
 {
-  mImpl->mControlInterface.AddDecoration( actor );
+  mImpl->mControlInterface.AddDecoration( actor, needsClipping );
 }
 
 void Controller::DecorationEvent( HandleType handleType, HandleState state, float x, float y )
@@ -1417,6 +1455,56 @@ 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:
+    {
+      break;
+    }
+    case Toolkit::TextSelectionPopup::COPY:
+    {
+      break;
+    }
+    case Toolkit::TextSelectionPopup::PASTE:
+    {
+      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 );