[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 8fb86da25e4f64cf96b5f007097dc6191beacdd1..66f8db325692b9c05eb1e527b80846658565adfc 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 b3b44129f4da1dea8d56106e34b134695913230e..93d8f7d47eaaeedd1bc31f7d2ad218cf53292c98 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 9a5bff1f7b68f13c7aa68869dacb3798f8f0c60f..0b4334ea3e81ff16d2892e0bb480e46336f5eb60 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 f13b2cb30f55ae636c6ae30aae116b9800a86bb6..8c8229d302ef335824d06161bf87d3757e69fcfd 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 113a1f5ce97cd427a1a28efa6502880871375940..23799c3095da3aa9c72e9fa988c3b10e3fd94b1d 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 1bf65cad8fe9b970dec1bf6fa76d0253ede1c2be..fc09fd88f34a05b54c8dbe77f63be4bcb69ce19d 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 32bf7abc97009ab877d2a4e83824b13f8cb65744..d5edfc3e44652acaf2c7b64ed832a82c736ca803 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 1c6702c5b46c246ff1c524cc2755a8e0a5cea396..63a897c6c755c281301d3dba400e9a99d745caed 100755 (executable)
@@ -630,6 +630,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()
    */
@@ -760,6 +770,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
    *
index d00330e25c8a2384b9154fb3cf960e6c6fa3e535..a1791bcb969eef3efa20ffd020befe66bd5cedd5 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 4e6f99b09829170624d622ef2cdfd531cc9a76bc..06a08b239c2cbabef35067934e08085e801c5a12 100644 (file)
@@ -1530,6 +1530,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.
    *