From 9b354691eaa778b98da70233ec7124d97e10ea34 Mon Sep 17 00:00:00 2001 From: Bowon Ryu Date: Wed, 30 Mar 2022 12:41:35 +0900 Subject: [PATCH] Supports USER_INTERACTION_ENABLED for text components Handles the behaviour of text components according to USER_INTERACTION_ENABLED. Fixed the following bug : If editable is false, all decorators should be disabled. The prev behaviour is that some decorators are not disabled. Change-Id: I7aeef2b2c238903723eec83e92b5945b06d0f6df Signed-off-by: Bowon Ryu --- .../src/dali-toolkit/utc-Dali-TextEditor.cpp | 23 +++++++++++++++++ .../src/dali-toolkit/utc-Dali-TextField.cpp | 22 ++++++++++++++++ .../controls/text-controls/text-editor-impl.cpp | 30 +++++++++++++++++++++- .../controls/text-controls/text-editor-impl.h | 5 ++++ .../controls/text-controls/text-field-impl.cpp | 30 +++++++++++++++++++++- .../controls/text-controls/text-field-impl.h | 5 ++++ .../internal/text/decorator/text-decorator.cpp | 21 +++++++++++++++ .../text/text-controller-event-handler.cpp | 7 ++--- .../internal/text/text-controller-impl.cpp | 14 +++++++++- dali-toolkit/internal/text/text-controller-impl.h | 12 ++++++++- dali-toolkit/internal/text/text-controller.cpp | 20 +++++++++++++++ dali-toolkit/internal/text/text-controller.h | 28 ++++++++++++++++++++ 12 files changed, 210 insertions(+), 7 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp index 19c3583..c21f9a3 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp @@ -20,6 +20,8 @@ #include #include #include + +#include #include #include #include @@ -3630,6 +3632,9 @@ int UtcDaliTextEditorEnableEditing(void) application.SendNotification(); application.Render(); + textEditor.SetProperty(DevelActor::Property::USER_INTERACTION_ENABLED, true); + DALI_TEST_EQUALS(textEditor.GetProperty(DevelActor::Property::USER_INTERACTION_ENABLED).Get(), true, TEST_LOCATION); + textEditor.SetKeyInputFocus(); textEditor.SetProperty(DevelTextEditor::Property::ENABLE_EDITING, false); application.ProcessEvent(GenerateKey("D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE)); @@ -3652,6 +3657,24 @@ int UtcDaliTextEditorEnableEditing(void) DALI_TEST_EQUALS(textEditor.GetProperty(TextEditor::Property::TEXT).Get(), "D", TEST_LOCATION); DALI_TEST_EQUALS(textEditor.GetProperty(DevelTextEditor::Property::ENABLE_EDITING).Get(), true, TEST_LOCATION); + // Check the user interaction enabled and for coverage + DevelTextEditor::SelectWholeText(textEditor); + + // Render and notify + application.SendNotification(); + application.Render(); + + textEditor.SetKeyInputFocus(); + textEditor.SetProperty(DevelActor::Property::USER_INTERACTION_ENABLED, false); + 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(), "D", TEST_LOCATION); + DALI_TEST_EQUALS(textEditor.GetProperty(DevelActor::Property::USER_INTERACTION_ENABLED).Get(), false, TEST_LOCATION); + END_TEST; } diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp index 48c2bcc..b86f96b 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -3836,6 +3837,9 @@ int UtcDaliTextFieldEnableEditing(void) application.SendNotification(); application.Render(); + textField.SetProperty(DevelActor::Property::USER_INTERACTION_ENABLED, true); + DALI_TEST_EQUALS(textField.GetProperty(DevelActor::Property::USER_INTERACTION_ENABLED).Get(), true, TEST_LOCATION); + textField.SetKeyInputFocus(); textField.SetProperty(DevelTextField::Property::ENABLE_EDITING, false); application.ProcessEvent(GenerateKey("D", "", "D", KEY_D_CODE, 0, 0, Integration::KeyEvent::DOWN, "D", DEFAULT_DEVICE_NAME, Device::Class::NONE, Device::Subclass::NONE)); @@ -3858,6 +3862,24 @@ int UtcDaliTextFieldEnableEditing(void) DALI_TEST_EQUALS(textField.GetProperty(TextField::Property::TEXT).Get(), "D", TEST_LOCATION); DALI_TEST_EQUALS(textField.GetProperty(DevelTextField::Property::ENABLE_EDITING).Get(), true, TEST_LOCATION); + // Check the user interaction enabled and for coverage + DevelTextField::SelectWholeText(textField); + + // Render and notify + application.SendNotification(); + application.Render(); + + textField.SetKeyInputFocus(); + textField.SetProperty(DevelActor::Property::USER_INTERACTION_ENABLED, false); + 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(), "D", TEST_LOCATION); + DALI_TEST_EQUALS(textField.GetProperty(DevelActor::Property::USER_INTERACTION_ENABLED).Get(), false, TEST_LOCATION); + END_TEST; } diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp index b1ff578..42153dc 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp @@ -673,6 +673,31 @@ void TextEditor::ResizeActor(Actor& actor, const Vector2& size) } } +void TextEditor::OnPropertySet(Property::Index index, const Property::Value& propertyValue) +{ + DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor::OnPropertySet index[%d]\n", index); + + switch(index) + { + case DevelActor::Property::USER_INTERACTION_ENABLED: + { + const bool enabled = propertyValue.Get(); + mController->SetUserInteractionEnabled(enabled); + if(mStencil) + { + float opacity = enabled ? 1.0f : mController->GetDisabledColorOpacity(); + mStencil.SetProperty(Actor::Property::OPACITY, opacity); + } + break; + } + default: + { + Control::OnPropertySet(index, propertyValue); // up call to control for non-handled properties + break; + } + } +} + void TextEditor::OnRelayout(const Vector2& size, RelayoutContainer& container) { DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor OnRelayout\n"); @@ -811,7 +836,10 @@ void TextEditor::OnKeyInputFocusGained() notifier.ContentSelectedSignal().Connect(this, &TextEditor::OnClipboardTextSelected); } - mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event + if(IsEditable() && mController->IsUserInteractionEnabled()) + { + mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event + } EmitKeyInputFocusSignal(true); // Calls back into the Control hence done last. } diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h index 5739ac2..c62988a 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.h @@ -221,6 +221,11 @@ private: // From Control void OnSceneConnection(int depth) override; /** + * @copydoc Control::OnPropertySet() + */ + void OnPropertySet(Property::Index index, const Property::Value& propertyValue) override; + + /** * @copydoc Dali::CustomActorImpl::OnKeyEvent(const KeyEvent&) */ bool OnKeyEvent(const KeyEvent& event) override; diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp index 6933832..b7a6eb4 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -608,6 +608,31 @@ void TextField::ResizeActor(Actor& actor, const Vector2& size) } } +void TextField::OnPropertySet(Property::Index index, const Property::Value& propertyValue) +{ + DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnPropertySet index[%d]\n", index); + + switch(index) + { + case DevelActor::Property::USER_INTERACTION_ENABLED: + { + const bool enabled = propertyValue.Get(); + mController->SetUserInteractionEnabled(enabled); + if(mStencil) + { + float opacity = enabled ? 1.0f : mController->GetDisabledColorOpacity(); + mStencil.SetProperty(Actor::Property::OPACITY, opacity); + } + break; + } + default: + { + Control::OnPropertySet(index, propertyValue); // up call to control for non-handled properties + break; + } + } +} + void TextField::OnRelayout(const Vector2& size, RelayoutContainer& container) { DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField OnRelayout\n"); @@ -746,7 +771,10 @@ void TextField::OnKeyInputFocusGained() notifier.ContentSelectedSignal().Connect(this, &TextField::OnClipboardTextSelected); } - mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event + if(IsEditable() && mController->IsUserInteractionEnabled()) + { + mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event + } EmitKeyInputFocusSignal(true); // Calls back into the Control hence done last. } diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.h b/dali-toolkit/internal/controls/text-controls/text-field-impl.h index d2d7fdf..6c4faa6 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.h @@ -212,6 +212,11 @@ private: // From Control void OnSceneConnection(int depth) override; /** + * @copydoc Control::OnPropertySet() + */ + void OnPropertySet(Property::Index index, const Property::Value& propertyValue) override; + + /** * @copydoc Dali::CustomActorImpl::OnKeyEvent(const KeyEvent&) */ bool OnKeyEvent(const KeyEvent& event) override; diff --git a/dali-toolkit/internal/text/decorator/text-decorator.cpp b/dali-toolkit/internal/text/decorator/text-decorator.cpp index f4d2ca4..d89adf9 100644 --- a/dali-toolkit/internal/text/decorator/text-decorator.cpp +++ b/dali-toolkit/internal/text/decorator/text-decorator.cpp @@ -2109,6 +2109,27 @@ int Decorator::GetCursorWidth() const void Decorator::SetEditable(bool editable) { mImpl->mHidePrimaryCursorAndGrabHandle = !editable; + // If editable is false, all decorators should be disabled. + if(!editable) + { + if(IsHighlightActive()) + { + SetHighlightActive(false); + } + if(IsHandleActive(LEFT_SELECTION_HANDLE)) + { + SetHandleActive(LEFT_SELECTION_HANDLE, false); + } + if(IsHandleActive(RIGHT_SELECTION_HANDLE)) + { + SetHandleActive(RIGHT_SELECTION_HANDLE, false); + } + if(IsPopupActive()) + { + SetPopupActive(false); + } + } + mImpl->Relayout(mImpl->mControlSize); } /** Handles **/ diff --git a/dali-toolkit/internal/text/text-controller-event-handler.cpp b/dali-toolkit/internal/text/text-controller-event-handler.cpp index 7494cb6..d5c41a1 100644 --- a/dali-toolkit/internal/text/text-controller-event-handler.cpp +++ b/dali-toolkit/internal/text/text-controller-event-handler.cpp @@ -117,6 +117,7 @@ bool Controller::EventHandler::KeyEvent(Controller& controller, const Dali::KeyE bool textChanged = false; bool relayoutNeeded = false; + bool isEditable = controller.IsEditable() && controller.IsUserInteractionEnabled(); if((NULL != controller.mImpl->mEventData) && (keyEvent.GetState() == KeyEvent::DOWN)) @@ -148,7 +149,7 @@ bool Controller::EventHandler::KeyEvent(Controller& controller, const Dali::KeyE (Dali::DALI_KEY_CURSOR_DOWN == keyCode)) { // If don't have any text, do nothing. - if(!controller.mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters) + if(!controller.mImpl->mTextUpdateInfo.mPreviousNumberOfCharacters || !isEditable) { return false; } @@ -207,7 +208,7 @@ bool Controller::EventHandler::KeyEvent(Controller& controller, const Dali::KeyE // Do nothing return false; } - else if(keyEvent.IsCtrlModifier() && !keyEvent.IsShiftModifier()) + else if(keyEvent.IsCtrlModifier() && !keyEvent.IsShiftModifier() && isEditable) { bool consumed = false; if(keyName == KEY_C_NAME || keyName == KEY_INSERT_NAME || logicalKey == KEY_C_NAME || logicalKey == KEY_INSERT_NAME) @@ -273,7 +274,7 @@ bool Controller::EventHandler::KeyEvent(Controller& controller, const Dali::KeyE else { DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Controller::KeyEvent %p keyString %s\n", &controller, keyString.c_str()); - if(!controller.IsEditable()) return false; + if(!isEditable) return false; std::string refinedKey = keyString; if(controller.mImpl->mInputFilter != NULL && !refinedKey.empty()) diff --git a/dali-toolkit/internal/text/text-controller-impl.cpp b/dali-toolkit/internal/text/text-controller-impl.cpp index 318c196..c24a5cf 100644 --- a/dali-toolkit/internal/text/text-controller-impl.cpp +++ b/dali-toolkit/internal/text/text-controller-impl.cpp @@ -909,7 +909,8 @@ void Controller::Impl::SetEditable(bool editable) if(mEventData->mDecorator) { - mEventData->mDecorator->SetEditable(editable); + bool decoratorEditable = editable && mIsUserInteractionEnabled; + mEventData->mDecorator->SetEditable(decoratorEditable); } } } @@ -1874,6 +1875,17 @@ void Controller::Impl::SetDefaultColor(const Vector4& color) } } +void Controller::Impl::SetUserInteractionEnabled(bool enabled) +{ + mIsUserInteractionEnabled = enabled; + + if(mEventData && mEventData->mDecorator) + { + bool editable = mEventData->mEditingEnabled && enabled; + mEventData->mDecorator->SetEditable(editable); + } +} + void Controller::Impl::ClearFontData() { if(mFontDefaults) diff --git a/dali-toolkit/internal/text/text-controller-impl.h b/dali-toolkit/internal/text/text-controller-impl.h index 8be1767..5944039 100644 --- a/dali-toolkit/internal/text/text-controller-impl.h +++ b/dali-toolkit/internal/text/text-controller-impl.h @@ -41,6 +41,7 @@ const float DEFAULT_TEXTFIT_MIN = 10.f; const float DEFAULT_TEXTFIT_MAX = 100.f; const float DEFAULT_TEXTFIT_STEP = 1.f; const float DEFAULT_FONT_SIZE_SCALE = 1.f; +const float DEFAULT_DISABLED_COLOR_OPACITY = 0.3f; //Forward declarations struct CursorInfo; @@ -358,10 +359,12 @@ struct Controller::Impl mTextFitMaxSize(DEFAULT_TEXTFIT_MAX), mTextFitStepSize(DEFAULT_TEXTFIT_STEP), mFontSizeScale(DEFAULT_FONT_SIZE_SCALE), + mDisabledColorOpacity(DEFAULT_DISABLED_COLOR_OPACITY), mFontSizeScaleEnabled(true), mTextFitEnabled(false), mTextFitChanged(false), - mIsLayoutDirectionChanged(false) + mIsLayoutDirectionChanged(false), + mIsUserInteractionEnabled(true) { mModel = Model::New(); @@ -874,6 +877,11 @@ struct Controller::Impl void SetDefaultColor(const Vector4& color); /** + * @copydoc Controller::SetUserInteractionEnabled() + */ + void SetUserInteractionEnabled(bool enabled); + + /** * @brief Helper to clear font-specific data (only). */ void ClearFontData(); @@ -1014,10 +1022,12 @@ public: float mTextFitMaxSize; ///< Maximum Font Size for text fit. Default 100 float mTextFitStepSize; ///< Step Size for font intervalse. Default 1 float mFontSizeScale; ///< Scale value for Font Size. Default 1.0 + float mDisabledColorOpacity; ///< Color opacity when disabled. bool mFontSizeScaleEnabled : 1; ///< Whether the font size scale is enabled. bool mTextFitEnabled : 1; ///< Whether the text's fit is enabled. bool mTextFitChanged : 1; ///< Whether the text fit property has changed. bool mIsLayoutDirectionChanged : 1; ///< Whether the layout has changed. + bool mIsUserInteractionEnabled : 1; ///< Whether the user interaction is enabled. private: friend ControllerImplEventHandler; diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index b0f740d..bf92f6a 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -747,6 +747,26 @@ const Vector4& Controller::GetDefaultColor() const return mImpl->mTextColor; } +void Controller::SetDisabledColorOpacity(float opacity) +{ + mImpl->mDisabledColorOpacity = opacity; +} + +float Controller::GetDisabledColorOpacity() const +{ + return mImpl->mDisabledColorOpacity; +} + +void Controller::SetUserInteractionEnabled(bool enabled) +{ + mImpl->SetUserInteractionEnabled(enabled); +} + +bool Controller::IsUserInteractionEnabled() const +{ + return mImpl->mIsUserInteractionEnabled; +} + void Controller::SetPlaceholderTextColor(const Vector4& textColor) { PlaceholderHandler::SetPlaceholderTextColor(*this, textColor); diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h index 81a0318..3e987dd 100644 --- a/dali-toolkit/internal/text/text-controller.h +++ b/dali-toolkit/internal/text/text-controller.h @@ -504,6 +504,20 @@ public: // Configure the text controller. bool IsTextFitChanged() const; /** + * @brief Sets disabled color opacity. + * + * @param[in] opacity The color opacity value in disabled state. + */ + void SetDisabledColorOpacity(float opacity); + + /** + * @brief Retrieves the disabled color opacity. + * + * @return The disabled color opacity value for disabled state. + */ + float GetDisabledColorOpacity() const; + + /** * @brief Enable or disable the placeholder text elide. * @param enabled Whether to enable the placeholder text elide. */ @@ -1004,6 +1018,20 @@ public: // Default style & Input style const Vector4& GetDefaultColor() const; /** + * @brief Sets the user interaction enabled. + * + * @param enabled whether to enable the user interaction. + */ + void SetUserInteractionEnabled(bool enabled); + + /** + * @brief Whether the user interaction is enabled. + * + * @return true if the user interaction is enabled, false otherwise. + */ + bool IsUserInteractionEnabled() const; + + /** * @brief Set the text color * * @param textColor The text color -- 2.7.4