[dali-toolkit] TextEditor/TextField add PrimaryCursorPosition property 40/246740/3
authorali198724 <ali198724@gmail.com>
Tue, 3 Nov 2020 20:31:24 +0000 (22:31 +0200)
committerali198724 <ali198724@gmail.com>
Wed, 11 Nov 2020 18:17:09 +0000 (20:17 +0200)
Add property to control primary cursor position

Change-Id: I77d4a7f375101dfe9e7afad4ca378ac8a5744c37

automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h
dali-toolkit/devel-api/controls/text-controls/text-field-devel.h
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h

index 8fb86da..66f8db3 100644 (file)
@@ -3170,3 +3170,36 @@ int UtcDaliToolkitTextEditorFontSizeScale(void)
 
   END_TEST;
 }
+
+int UtcDaliTextEditorPrimaryCursorPosition(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextPrimaryCursorPosition ");
+
+  TextEditor textEditor = TextEditor::New();
+
+  application.GetScene().Add( textEditor );
+
+  textEditor.SetProperty( TextEditor::Property::TEXT, "ABCEF");
+  textEditor.SetProperty( Actor::Property::SIZE, Vector2( 300.f, 50.f ) );
+  textEditor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+  textEditor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  textEditor.SetProperty( DevelTextEditor::Property::PRIMARY_CURSOR_POSITION, 3);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( textEditor.GetProperty( TextEditor::Property::TEXT ).Get<std::string>(), "ABCDEF", TEST_LOCATION );
+  DALI_TEST_EQUALS( textEditor.GetProperty( DevelTextEditor::Property::PRIMARY_CURSOR_POSITION ).Get<int>(), 4, TEST_LOCATION );
+
+  END_TEST;
+}
index b3b4412..93d8f7d 100644 (file)
@@ -3088,3 +3088,36 @@ int UtcDaliToolkitTextFieldFontSizeScale(void)
 
   END_TEST;
 }
+
+int UtcDaliTextFieldPrimaryCursorPosition(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextFieldPrimaryCursorPosition ");
+
+  TextField textField = TextField::New();
+
+  application.GetScene().Add( textField );
+
+  textField.SetProperty( TextField::Property::TEXT, "ABCEF");
+  textField.SetProperty( Actor::Property::SIZE, Vector2( 300.f, 50.f ) );
+  textField.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+  textField.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  textField.SetProperty( DevelTextField::Property::PRIMARY_CURSOR_POSITION, 3);
+  application.SendNotification();
+  application.Render();
+
+  application.ProcessEvent( GenerateKey( "D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( textField.GetProperty( TextField::Property::TEXT ).Get<std::string>(), "ABCDEF", TEST_LOCATION );
+  DALI_TEST_EQUALS( textField.GetProperty( DevelTextField::Property::PRIMARY_CURSOR_POSITION ).Get<int>(), 4, TEST_LOCATION );
+
+  END_TEST;
+}
index 9a5bff1..0b4334e 100644 (file)
@@ -175,6 +175,12 @@ enum Type
    *  - fontSize: 10pt, fontSizeScale: 1.5
    */
   FONT_SIZE_SCALE,
+
+  /**
+   * @brief The position for primary cursor.
+   * @details Name "primaryCursorPosition", type Property::INTEGER.
+   */
+  PRIMARY_CURSOR_POSITION,
 };
 
 } // namespace Property
index f13b2cb..8c8229d 100644 (file)
@@ -159,7 +159,13 @@ enum
    *  - fontSize: 15pt, fontSizeScale: 1.0
    *  - fontSize: 10pt, fontSizeScale: 1.5
    */
-  FONT_SIZE_SCALE
+  FONT_SIZE_SCALE,
+
+  /**
+   * @brief The position for primary cursor.
+   * @details Name "primaryCursorPosition", type Property::INTEGER.
+   */
+  PRIMARY_CURSOR_POSITION,
 
 };
 } // namespace Property
index 113a1f5..23799c3 100644 (file)
@@ -148,6 +148,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "verticalScrollPosition",
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableEditing",                  BOOLEAN,   ENABLE_EDITING                       )
 DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextEditor, "selectedText",         STRING,    SELECTED_TEXT                        )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "fontSizeScale",                  FLOAT,     FONT_SIZE_SCALE                      )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextEditor, "primaryCursorPosition",          INTEGER,   PRIMARY_CURSOR_POSITION              )
 
 DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "textChanged",        SIGNAL_TEXT_CHANGED )
 DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "inputStyleChanged",  SIGNAL_INPUT_STYLE_CHANGED )
@@ -756,6 +757,16 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
         }
         break;
       }
+      case Toolkit::DevelTextEditor::Property::PRIMARY_CURSOR_POSITION:
+      {
+        uint32_t position = static_cast<uint32_t>(value.Get< int >());
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p PRIMARY_CURSOR_POSITION %d\n", impl.mController.Get(), position );
+        if (impl.mController->SetPrimaryCursorPosition( position ))
+        {
+          impl.SetKeyInputFocus();
+        }
+        break;
+      }
     } // switch
   } // texteditor
 }
@@ -1107,6 +1118,11 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
         value = impl.mController->GetFontSizeScale();
         break;
       }
+      case Toolkit::DevelTextEditor::Property::PRIMARY_CURSOR_POSITION:
+      {
+        value = static_cast<int>(impl.mController->GetPrimaryCursorPosition());
+        break;
+      }
     } //switch
   }
 
index 1bf65ca..fc09fd8 100644 (file)
@@ -139,6 +139,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "selectedTextStart",
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "selectedTextEnd",                INTEGER,   SELECTED_TEXT_END                    )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableEditing",                  BOOLEAN,   ENABLE_EDITING                       )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "fontSizeScale",                  FLOAT,     FONT_SIZE_SCALE                      )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "primaryCursorPosition",          INTEGER,   PRIMARY_CURSOR_POSITION              )
 
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged",        SIGNAL_TEXT_CHANGED )
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached",   SIGNAL_MAX_LENGTH_REACHED )
@@ -745,6 +746,16 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         }
         break;
       }
+      case Toolkit::DevelTextField::Property::PRIMARY_CURSOR_POSITION:
+      {
+        uint32_t position = static_cast<uint32_t>(value.Get< int >());
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PRIMARY_CURSOR_POSITION %d\n", impl.mController.Get(), position );
+        if (impl.mController->SetPrimaryCursorPosition( position ))
+        {
+          impl.SetKeyInputFocus();
+        }
+        break;
+      }
     } // switch
   } // textfield
 }
@@ -1090,6 +1101,11 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
         value = impl.mController->GetFontSizeScale();
         break;
       }
+      case Toolkit::DevelTextField::Property::PRIMARY_CURSOR_POSITION:
+      {
+        value = static_cast<int>(impl.mController->GetPrimaryCursorPosition());
+        break;
+      }
     } //switch
   }
 
index 32bf7ab..d5edfc3 100644 (file)
@@ -1422,6 +1422,38 @@ void Controller::Impl::SetTextSelectionRange(const uint32_t *pStart, const uint3
   }
 }
 
+CharacterIndex Controller::Impl::GetPrimaryCursorPosition() const
+{
+  if( nullptr == mEventData )
+  {
+    return 0;
+  }
+  return mEventData->mPrimaryCursorPosition;
+}
+
+bool Controller::Impl::SetPrimaryCursorPosition( CharacterIndex index )
+{
+  if( nullptr == mEventData )
+  {
+    // Nothing to do if there is no text.
+    return false;
+  }
+
+  if( mEventData->mPrimaryCursorPosition == index )
+  {
+    // Nothing for same cursor position.
+    return false;
+  }
+
+  uint32_t length = static_cast<uint32_t>(mModel->mLogicalModel->mText.Count());
+  mEventData->mPrimaryCursorPosition = std::min(index, length);
+  ChangeState( EventData::EDITING );
+  mEventData->mLeftSelectionPosition = mEventData->mRightSelectionPosition = mEventData->mPrimaryCursorPosition;
+  mEventData->mUpdateCursorPosition = true;
+  ScrollTextToMatchCursor();
+  return true;
+}
+
 Uint32Pair Controller::Impl::GetTextSelectionRange() const
 {
   Uint32Pair range;
@@ -2675,6 +2707,13 @@ void Controller::Impl::ScrollTextToMatchCursor( const CursorInfo& cursorInfo )
   ScrollToMakePositionVisible( cursorInfo.primaryPosition, cursorInfo.lineHeight );
 }
 
+void Controller::Impl::ScrollTextToMatchCursor()
+{
+  CursorInfo cursorInfo;
+  GetCursorPosition( mEventData->mPrimaryCursorPosition, cursorInfo );
+  ScrollTextToMatchCursor(cursorInfo);
+}
+
 void Controller::Impl::RequestRelayout()
 {
   if( NULL != mControlInterface )
index 1c6702c..63a897c 100755 (executable)
@@ -631,6 +631,16 @@ struct Controller::Impl
   void OnSelectNoneEvent();
 
   /**
+   * @copydoc Text::Controller::GetPrimaryCursorPosition()
+   */
+  CharacterIndex GetPrimaryCursorPosition() const;
+
+  /**
+   * @copydoc Text::Controller::SetPrimaryCursorPosition()
+   */
+  bool SetPrimaryCursorPosition( CharacterIndex index );
+
+  /**
    * @copydoc Text::SelectableControlInterface::SetTextSelectionRange()
    */
   void SetTextSelectionRange(const uint32_t *pStart, const uint32_t *pEndf);
@@ -761,6 +771,11 @@ struct Controller::Impl
   void ScrollTextToMatchCursor( const CursorInfo& cursorInfo );
 
   /**
+   * @brief Scrolls the text to make primary cursor visible.
+   */
+  void ScrollTextToMatchCursor( );
+
+  /**
    * @brief Create an actor that renders the text background color
    *
    * @return the created actor or an empty handle if no background color needs to be rendered.
index d00330e..a1791bc 100644 (file)
@@ -2235,6 +2235,28 @@ Uint32Pair Controller::GetTextSelectionRange() const
   return mImpl->GetTextSelectionRange();
 }
 
+CharacterIndex Controller::GetPrimaryCursorPosition() const
+{
+  return mImpl->GetPrimaryCursorPosition();
+}
+
+bool Controller::SetPrimaryCursorPosition( CharacterIndex index )
+{
+  if( mImpl->mEventData )
+  {
+    mImpl->mEventData->mCheckScrollAmount = true;
+    mImpl->mEventData->mIsLeftHandleSelected = true;
+    mImpl->mEventData->mIsRightHandleSelected = true;
+    mImpl->mEventData->mCheckScrollAmount = true;
+    if( mImpl->SetPrimaryCursorPosition(index) )
+    {
+      KeyboardFocusGainEvent();
+      return true;
+    }
+  }
+  return false;
+}
+
 void Controller::SelectWholeText()
 {
   SelectEvent( 0.f, 0.f, SelectionType::ALL );
index 4e6f99b..06a08b2 100644 (file)
@@ -1531,6 +1531,21 @@ public: // Text-input Event Queuing.
   void LongPressEvent( GestureState state, float x, float y );
 
   /**
+   * @brief Used to get the Primary cursor position.
+   *
+   * @return Primary cursor position.
+   */
+  CharacterIndex GetPrimaryCursorPosition() const;
+
+  /**
+   * @brief Used to set the Primary cursor position.
+   *
+   * @param[in] index for the Primary cursor position.
+   * @return[in] true if cursor position changed, false otherwise.
+   */
+  bool SetPrimaryCursorPosition( CharacterIndex index );
+
+  /**
    * @brief Creates a selection event.
    *
    * It could be called from the TapEvent (double tap) or when the text selection popup's sellect all button is pressed.