Add support to unselect text And Get_SelectedText 24/231224/4
authorAli <ali198724@gmail.com>
Mon, 20 Apr 2020 07:51:54 +0000 (10:51 +0300)
committerjoogab yun <joogab.yun@samsung.com>
Tue, 28 Apr 2020 01:58:00 +0000 (01:58 +0000)
This patch add two kind of support for TextField
1- SelectNone function: this will unselect text in textfield Programmatically by user.
2- Selected_Text property: this is readonly to return string for selected text.

After this patch approve, I will create other one for dali-csharp-bindings

Change-Id: If93ed6df44a41ff00f772a0abcfc9e2401c41480

automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
dali-toolkit/devel-api/controls/text-controls/text-field-devel.cpp
dali-toolkit/devel-api/controls/text-controls/text-field-devel.h
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.h
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
dali-toolkit/public-api/controls/text-controls/text-field.h

index 3e53b67..0e8a597 100755 (executable)
@@ -1124,7 +1124,7 @@ int UtcDaliTextControllerSelectEvent(void)
   controller->SetText( text );
 
   // Select the whole text.
-  controller->SelectEvent( 0.f, 0.f, false );
+  controller->SelectEvent( 0.f, 0.f, SelectionType::INTERACTIVE );
 
   // Perform a relayout
   const Size size( Dali::Stage::GetCurrent().GetSize() );
@@ -1139,7 +1139,7 @@ int UtcDaliTextControllerSelectEvent(void)
   DALI_TEST_EQUALS( "Hello", retrieved_text, TEST_LOCATION );
 
   // Select the whole text.
-  controller->SelectEvent( 0.f, 0.f, true );
+  controller->SelectEvent( 0.f, 0.f, SelectionType::ALL );
 
   // Perform a relayout
   controller->Relayout( size );
index 7e050ff..e58ab4d 100755 (executable)
@@ -2872,3 +2872,52 @@ int UtcDaliTextFieldSelectWholeText(void)
 
   END_TEST;
 }
+
+int UtcDaliTextFieldSelectNone(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextFieldSelectWholeText ");
+
+  TextField textField = TextField::New();
+
+  Stage::GetCurrent().Add( textField );
+
+  textField.SetSize( 300.f, 50.f );
+  textField.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  textField.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  application.SendNotification();
+  application.Render();
+
+  textField.SetProperty( TextField::Property::TEXT, "Hello world" );
+
+  application.SendNotification();
+  application.Render();
+
+  // Nothing is selected
+  std::string selectedText = textField.GetProperty( DevelTextField::Property::SELECTED_TEXT ).Get<std::string>();
+  DALI_TEST_EQUALS( "", selectedText, TEST_LOCATION );
+
+  DevelTextField::SelectWholeText( textField );
+
+  application.SendNotification();
+  application.Render();
+
+  // whole text is selected
+  selectedText = textField.GetProperty( DevelTextField::Property::SELECTED_TEXT ).Get<std::string>();
+  DALI_TEST_EQUALS( "Hello world", selectedText, TEST_LOCATION );
+
+  DevelTextField::SelectNone( textField );
+
+  application.SendNotification();
+  application.Render();
+
+  // Nothing is selected
+  selectedText = textField.GetProperty( DevelTextField::Property::SELECTED_TEXT ).Get<std::string>();
+  DALI_TEST_EQUALS( "", selectedText, TEST_LOCATION );
+
+  END_TEST;
+}
index a53ef4a..e926401 100755 (executable)
@@ -38,6 +38,11 @@ void SelectWholeText( TextField textField )
   GetImpl( textField ).SelectWholeText();
 }
 
+void SelectNone( TextField textField )
+{
+  GetImpl( textField ).SelectNone();
+}
+
 } // namespace DevelText
 
 } // namespace Toolkit
index 3a4864c..0d10779 100755 (executable)
@@ -122,7 +122,15 @@ namespace Property
        * @note Use "textBackground" as property name to avoid conflict with Control's "background" property.
        * @note The default value is Color::TRANSPARENT.
        */
-      BACKGROUND = ELLIPSIS + 5
+      BACKGROUND = ELLIPSIS + 5,
+
+
+      /**
+       * @brief The selected text in UTF-8 format.
+       * @details Name "selectedText", type Property::STRING.
+       * @note This property is read-only.
+       */
+      SELECTED_TEXT = ELLIPSIS + 6
 
   };
 } // namespace Property
@@ -139,10 +147,24 @@ DALI_TOOLKIT_API InputMethodContext GetInputMethodContext( TextField textField )
  * @brief Select the whole text of TextField.
  *
  * @param[in] textField The instance of TextField.
- * @return InputMethodContext instance.
  */
 DALI_TOOLKIT_API void SelectWholeText( TextField textField );
 
+/**
+ * @brief Unselect the whole text of TextField.
+ *
+ * @param[in] textField The instance of TextField.
+ */
+DALI_TOOLKIT_API void SelectNone( TextField textField );
+
+/**
+ * @brief Get the selected text of TextField.
+ *
+ * @param[in] textField The instance of TextField.
+ * @return Selected text in the TextField.
+ */
+DALI_TOOLKIT_API std::string SelectedText( TextField textField );
+
 } // namespace DevelText
 
 } // namespace Toolkit
index e9d1fe4..f9b4b70 100755 (executable)
@@ -135,6 +135,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableGrabHandle",
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "matchSystemLanguageDirection",   BOOLEAN,   MATCH_SYSTEM_LANGUAGE_DIRECTION      )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableGrabHandlePopup",          BOOLEAN,   ENABLE_GRAB_HANDLE_POPUP             )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "textBackground",                 VECTOR4,   BACKGROUND                           )
+DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextField, "selectedText",         STRING,    SELECTED_TEXT                        )
 
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged",        SIGNAL_TEXT_CHANGED )
 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached",   SIGNAL_MAX_LENGTH_REACHED )
@@ -1212,6 +1213,14 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
         }
         break;
       }
+      case Toolkit::DevelTextField::Property::SELECTED_TEXT:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetSelectedText( );
+        }
+        break;
+      }
     } //switch
   }
 
@@ -1222,7 +1231,16 @@ void TextField::SelectWholeText()
 {
   if( mController && mController->IsShowingRealText() )
   {
-    mController->SelectEvent( 0.f, 0.f, true );
+    mController->SelectEvent( 0.f, 0.f, SelectionType::ALL );
+    SetKeyInputFocus();
+  }
+}
+
+void TextField::SelectNone()
+{
+  if( mController && mController->IsShowingRealText() )
+  {
+    mController->SelectEvent( 0.f, 0.f, SelectionType::NONE );
     SetKeyInputFocus();
   }
 }
index 25bd4bd..3fd32a0 100755 (executable)
@@ -107,6 +107,17 @@ public:
    */
   void SelectWholeText();
 
+    /**
+   * @brief Called to unselect the whole texts.
+   */
+  void SelectNone();
+
+    /**
+   * @brief Called to get selected text.
+   * @return Selected text in the TextField.
+   */
+  std::string SelectedText();
+
 private: // From Control
 
   /**
index 8f4de65..4df4d38 100755 (executable)
@@ -221,6 +221,11 @@ bool Controller::Impl::ProcessInputEvents()
           OnSelectAllEvent();
           break;
         }
+        case Event::SELECT_NONE:
+        {
+          OnSelectNoneEvent();
+          break;
+        }
       }
     }
   }
@@ -2015,6 +2020,27 @@ void Controller::Impl::OnSelectAllEvent()
   }
 }
 
+void Controller::Impl::OnSelectNoneEvent()
+{
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "OnSelectNoneEvent mEventData->mSelectionEnabled%s \n", mEventData->mSelectionEnabled?"true":"false");
+
+  if( NULL == mEventData )
+  {
+    // Nothing to do if there is no text.
+    return;
+  }
+
+  if( mEventData->mSelectionEnabled && mEventData->mState == EventData::SELECTING)
+  {
+    mEventData->mPrimaryCursorPosition = 0u;
+    mEventData->mLeftSelectionPosition = mEventData->mRightSelectionPosition = mEventData->mPrimaryCursorPosition;
+    ChangeState( EventData::INACTIVE );
+    mEventData->mUpdateCursorPosition = true;
+    mEventData->mUpdateInputStyle = true;
+    mEventData->mScrollAfterUpdatePosition = true;
+  }
+}
+
 void Controller::Impl::RetrieveSelection( std::string& selectedText, bool deleteAfterRetrieval )
 {
   if( mEventData->mLeftSelectionPosition == mEventData->mRightSelectionPosition )
index 064d644..981e498 100755 (executable)
@@ -61,7 +61,8 @@ struct Event
     LEFT_SELECTION_HANDLE_EVENT,
     RIGHT_SELECTION_HANDLE_EVENT,
     SELECT,
-    SELECT_ALL
+    SELECT_ALL,
+    SELECT_NONE,
   };
 
   union Param
@@ -619,6 +620,8 @@ struct Controller::Impl
 
   void OnSelectAllEvent();
 
+  void OnSelectNoneEvent();
+
   /**
    * @brief Retrieves the selected text. It removes the text if the @p deleteAfterRetrieval parameter is @e true.
    *
index 8aaefae..b4624dc 100755 (executable)
@@ -3033,17 +3033,22 @@ void Controller::LongPressEvent( Gesture::State state, float x, float y  )
   }
 }
 
-void Controller::SelectEvent( float x, float y, bool selectAll )
+void Controller::SelectEvent( float x, float y, SelectionType selectType )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::SelectEvent\n" );
 
   if( NULL != mImpl->mEventData )
   {
-    if( selectAll )
+    if( selectType == SelectionType::ALL )
     {
       Event event( Event::SELECT_ALL );
       mImpl->mEventData->mEventQueue.push_back( event );
     }
+    else if( selectType == SelectionType::NONE )
+    {
+      Event event( Event::SELECT_NONE );
+      mImpl->mEventData->mEventQueue.push_back( event );
+    }
     else
     {
       Event event( Event::SELECT );
@@ -3326,14 +3331,14 @@ void Controller::TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Butt
       if( mImpl->mEventData->mSelectionEnabled )
       {
         // Creates a SELECT event.
-        SelectEvent( currentCursorPosition.x, currentCursorPosition.y, false );
+        SelectEvent( currentCursorPosition.x, currentCursorPosition.y, SelectionType::INTERACTIVE );
       }
       break;
     }
     case Toolkit::TextSelectionPopup::SELECT_ALL:
     {
       // Creates a SELECT_ALL event
-      SelectEvent( 0.f, 0.f, true );
+      SelectEvent( 0.f, 0.f, SelectionType::ALL );
       break;
     }
     case Toolkit::TextSelectionPopup::CLIPBOARD:
@@ -3755,6 +3760,16 @@ bool Controller::RemoveSelectedText()
   return textRemoved;
 }
 
+std::string Controller::GetSelectedText()
+{
+  std::string text;
+  if( EventData::SELECTING == mImpl->mEventData->mState )
+  {
+    mImpl->RetrieveSelection( text, false );
+  }
+  return text;
+}
+
 // private : Relayout.
 
 bool Controller::DoRelayout( const Size& size,
index 82a7a15..6a986f5 100755 (executable)
@@ -47,6 +47,16 @@ class EditableControlInterface;
 class View;
 class RenderingController;
 
+  /**
+   * @brief Text selection operations .
+   */
+  enum SelectionType
+  {
+    INTERACTIVE        = 0x0000,
+    ALL                = 0x0001,
+    NONE               = 0x0002
+  };
+
 typedef IntrusivePtr<Controller> ControllerPtr;
 
 /**
@@ -1462,9 +1472,9 @@ public: // Text-input Event Queuing.
    *
    * @param[in] x The x position relative to the top-left of the parent control.
    * @param[in] y The y position relative to the top-left of the parent control.
-   * @param[in] selectAll Whether the whole text is selected.
+   * @param[in] selection type like the whole text is selected or unselected.
    */
-  void SelectEvent( float x, float y, bool selectAll );
+  void SelectEvent( float x, float y, SelectionType selection );
 
   /**
    * @brief Event received from input method context
@@ -1494,6 +1504,13 @@ public: // Text-input Event Queuing.
    */
   Actor CreateBackgroundActor();
 
+  /**
+   * @brief Retrive Selected text.
+   *
+   * @return The seleced text.
+   */
+  std::string GetSelectedText();
+
 protected: // Inherit from Text::Decorator::ControllerInterface.
 
   /**
index 133b2c7..6ac1887 100644 (file)
@@ -472,7 +472,7 @@ public:
        * @SINCE_1_2.60
        * @note PLACEHOLDER map is used to add ellipsis to placeholder text.
        */
-      ELLIPSIS,
+      ELLIPSIS
     };
   };