X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=dali-toolkit%2Finternal%2Fcontrols%2Ftext-controls%2Ftext-field-impl.cpp;h=626dcf246327b6c42128bfadef82373ee2b0f710;hb=895806b4ad86de88dcc731aeb8e3dbe453ce4202;hp=8b5b18d372a933412ac4838c278d90bf88b1e6df;hpb=760285a850a7bf256a799cfb23ff2283520dc02a;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git 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 8b5b18d..626dcf2 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * Copyright (c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,17 +24,18 @@ #include #include #include +#include #include #include #include #include // INTERNAL INCLUDES -#include #include #include #include #include +#include #include #include #include @@ -136,10 +137,14 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "selectedTextStar 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, "enableFontSizeScale", BOOLEAN, ENABLE_FONT_SIZE_SCALE ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "primaryCursorPosition", INTEGER, PRIMARY_CURSOR_POSITION ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "grabHandleColor", VECTOR4, GRAB_HANDLE_COLOR ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "inputFilter", MAP, INPUT_FILTER ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "ellipsisPosition", INTEGER, ELLIPSIS_POSITION ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "strikethrough", MAP, STRIKETHROUGH ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "inputStrikethrough", MAP, INPUT_STRIKETHROUGH ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "characterSpacing", FLOAT, CHARACTER_SPACING ) DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "textChanged", SIGNAL_TEXT_CHANGED ) DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "maxLengthReached", SIGNAL_MAX_LENGTH_REACHED ) @@ -153,6 +158,75 @@ DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "selectionCleared", SIGNAL_SEL DALI_TYPE_REGISTRATION_END() // clang-format on +Toolkit::TextField::InputStyle::Mask ConvertInputStyle(Text::InputStyle::Mask inputStyleMask) +{ + Toolkit::TextField::InputStyle::Mask fieldInputStyleMask = Toolkit::TextField::InputStyle::NONE; + + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_COLOR)) + { + fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::COLOR); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_FAMILY)) + { + fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_FAMILY); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_POINT_SIZE)) + { + fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::POINT_SIZE); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_WEIGHT)) + { + fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_WIDTH)) + { + fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_SLANT)) + { + fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_UNDERLINE)) + { + fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::UNDERLINE); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_SHADOW)) + { + fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::SHADOW); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_EMBOSS)) + { + fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::EMBOSS); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_OUTLINE)) + { + fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::OUTLINE); + } + return fieldInputStyleMask; +} + +bool IsHiddenInput(Toolkit::TextField textField) +{ + Property::Map hiddenInputSettings = textField.GetProperty(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS); + auto mode = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::MODE); + if(mode && (mode->Get() != Toolkit::HiddenInput::Mode::HIDE_NONE)) + { + return true; + } + return false; +} + +char GetSubstituteCharacter(Toolkit::TextField textField) +{ + Property::Map hiddenInputSettings = textField.GetProperty(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS); + auto substChar = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::SUBSTITUTE_CHARACTER); + if(substChar) + { + return static_cast(substChar->Get()); + } + return STAR; +} + } // namespace Toolkit::TextField TextField::New() @@ -393,6 +467,11 @@ DevelTextField::SelectionClearedSignalType& TextField::SelectionClearedSignal() return mSelectionClearedSignal; } +void TextField::OnAccessibilityStatusChanged() +{ + CommonTextUtils::SynchronizeTextAnchorsInParent(Self(), mController, mAnchorActors); +} + void TextField::OnInitialize() { Actor self = Self(); @@ -471,6 +550,9 @@ void TextField::OnInitialize() return std::unique_ptr( new AccessibleImpl(actor, Dali::Accessibility::Role::ENTRY)); }); + + Accessibility::Bridge::EnabledSignal().Connect(this, &TextField::OnAccessibilityStatusChanged); + Accessibility::Bridge::DisabledSignal().Connect(this, &TextField::OnAccessibilityStatusChanged); } void TextField::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) @@ -632,101 +714,7 @@ Text::ControllerPtr TextField::GetTextController() void TextField::RenderText(Text::Controller::UpdateTextType updateTextType) { - Actor renderableActor; - - if(Text::Controller::NONE_UPDATED != (Text::Controller::MODEL_UPDATED & updateTextType)) - { - if(mRenderer) - { - Dali::Toolkit::TextField handle = Dali::Toolkit::TextField(GetOwner()); - - renderableActor = mRenderer->Render(mController->GetView(), - handle, - Property::INVALID_INDEX, // Animatable property not supported - mAlignmentOffset, - DepthIndex::CONTENT); - } - - if(renderableActor != mRenderableActor) - { - UnparentAndReset(mBackgroundActor); - UnparentAndReset(mRenderableActor); - mRenderableActor = renderableActor; - - if(mRenderableActor) - { - mBackgroundActor = mController->CreateBackgroundActor(); - } - } - } - - if(mRenderableActor) - { - const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition(); - - float renderableActorPositionX, renderableActorPositionY; - - if(mStencil) - { - renderableActorPositionX = scrollOffset.x + mAlignmentOffset; - renderableActorPositionY = scrollOffset.y; - } - else - { - Extents padding; - padding = Self().GetProperty(Toolkit::Control::Property::PADDING); - - // Support Right-To-Left of padding - Dali::LayoutDirection::Type layoutDirection = static_cast(Self().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get()); - if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection) - { - std::swap(padding.start, padding.end); - } - - renderableActorPositionX = scrollOffset.x + mAlignmentOffset + padding.start; - renderableActorPositionY = scrollOffset.y + padding.top; - } - - mRenderableActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY)); - - // Make sure the actors are parented correctly with/without clipping - Actor self = mStencil ? mStencil : Self(); - - Actor highlightActor; - - for(std::vector::iterator it = mClippingDecorationActors.begin(), - endIt = mClippingDecorationActors.end(); - it != endIt; - ++it) - { - self.Add(*it); - it->LowerToBottom(); - - if(it->GetProperty(Dali::Actor::Property::NAME) == "HighlightActor") - { - highlightActor = *it; - } - } - mClippingDecorationActors.clear(); - - self.Add(mRenderableActor); - - if(mBackgroundActor) - { - if(mDecorator && mDecorator->IsHighlightVisible()) - { - self.Add(mBackgroundActor); - mBackgroundActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY)); // In text field's coords. - mBackgroundActor.LowerBelow(highlightActor); - } - else - { - mRenderableActor.Add(mBackgroundActor); - mBackgroundActor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); // In renderable actor's coords. - mBackgroundActor.LowerToBottom(); - } - } - } + CommonTextUtils::RenderText(Self(), mRenderer, mController, mDecorator, mAlignmentOffset, mRenderableActor, mBackgroundActor, mStencil, mClippingDecorationActors, mAnchorActors, updateTextType); } void TextField::OnKeyInputFocusGained() @@ -928,51 +916,7 @@ void TextField::MaxLengthReached() void TextField::InputStyleChanged(Text::InputStyle::Mask inputStyleMask) { Dali::Toolkit::TextField handle(GetOwner()); - - Toolkit::TextField::InputStyle::Mask fieldInputStyleMask = Toolkit::TextField::InputStyle::NONE; - - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_COLOR)) - { - fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::COLOR); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_FAMILY)) - { - fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_FAMILY); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_POINT_SIZE)) - { - fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::POINT_SIZE); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_WEIGHT)) - { - fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_WIDTH)) - { - fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_SLANT)) - { - fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_UNDERLINE)) - { - fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::UNDERLINE); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_SHADOW)) - { - fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::SHADOW); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_EMBOSS)) - { - fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::EMBOSS); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_OUTLINE)) - { - fieldInputStyleMask = static_cast(fieldInputStyleMask | Toolkit::TextField::InputStyle::OUTLINE); - } - - mInputStyleChangedSignal.Emit(handle, fieldInputStyleMask); + mInputStyleChangedSignal.Emit(handle, ConvertInputStyle(inputStyleMask)); } void TextField::AnchorClicked(const std::string& href) @@ -1188,13 +1132,28 @@ TextField::~TextField() } } -std::string TextField::AccessibleImpl::GetName() +Vector TextField::GetTextSize(const uint32_t startIndex, const uint32_t endIndex) const +{ + return mController->GetTextSize(startIndex, endIndex); +} + +Vector TextField::GetTextPosition(const uint32_t startIndex, const uint32_t endIndex) const +{ + return mController->GetTextPosition(startIndex, endIndex); +} + +std::string TextField::AccessibleImpl::GetName() const { auto self = Toolkit::TextField::DownCast(Self()); + if(IsHiddenInput(self)) + { + return {}; + } + return self.GetProperty(Toolkit::TextField::Property::TEXT).Get(); } -std::string TextField::AccessibleImpl::GetText(size_t startOffset, size_t endOffset) +std::string TextField::AccessibleImpl::GetText(size_t startOffset, size_t endOffset) const { if(endOffset <= startOffset) { @@ -1208,11 +1167,14 @@ std::string TextField::AccessibleImpl::GetText(size_t startOffset, size_t endOff { return {}; } - + if(IsHiddenInput(self)) + { + return std::string(endOffset - startOffset, GetSubstituteCharacter(self)); + } return text.substr(startOffset, endOffset - startOffset); } -size_t TextField::AccessibleImpl::GetCharacterCount() +size_t TextField::AccessibleImpl::GetCharacterCount() const { auto self = Toolkit::TextField::DownCast(Self()); auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get(); @@ -1220,7 +1182,7 @@ size_t TextField::AccessibleImpl::GetCharacterCount() return text.size(); } -size_t TextField::AccessibleImpl::GetCursorOffset() +size_t TextField::AccessibleImpl::GetCursorOffset() const { auto self = Toolkit::TextField::DownCast(Self()); return Dali::Toolkit::GetImpl(self).GetTextController()->GetCursorPosition(); @@ -1243,14 +1205,21 @@ bool TextField::AccessibleImpl::SetCursorOffset(size_t offset) } Dali::Accessibility::Range TextField::AccessibleImpl::GetTextAtOffset( - size_t offset, Dali::Accessibility::TextBoundary boundary) + size_t offset, Dali::Accessibility::TextBoundary boundary) const { - auto self = Toolkit::TextField::DownCast(Self()); + auto self = Toolkit::TextField::DownCast(Self()); + auto range = Dali::Accessibility::Range{}; + + if(IsHiddenInput(self)) + { + // Returning empty object, as there is no possibility to parse the textfield + // when its content is hidden. + return range; + } + auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get(); auto textSize = text.size(); - auto range = Dali::Accessibility::Range{}; - switch(boundary) { case Dali::Accessibility::TextBoundary::CHARACTER: @@ -1334,7 +1303,7 @@ Dali::Accessibility::Range TextField::AccessibleImpl::GetTextAtOffset( return range; } -Dali::Accessibility::Range TextField::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex) +Dali::Accessibility::Range TextField::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex) const { // Since DALi supports only one selection indexes higher than 0 are ignored if(selectionIndex > 0) @@ -1342,13 +1311,21 @@ Dali::Accessibility::Range TextField::AccessibleImpl::GetRangeOfSelection(size_t return {}; } - auto self = Toolkit::TextField::DownCast(Self()); - auto controller = Dali::Toolkit::GetImpl(self).GetTextController(); + auto self = Toolkit::TextField::DownCast(Self()); + auto controller = Dali::Toolkit::GetImpl(self).GetTextController(); + auto indices = controller->GetSelectionIndexes(); + + auto startOffset = static_cast(indices.first); + auto endOffset = static_cast(indices.second); + + if(IsHiddenInput(self)) + { + return {startOffset, endOffset, std::string(endOffset - startOffset, GetSubstituteCharacter(self))}; + } + std::string value{}; controller->RetrieveSelection(value); - auto indices = controller->GetSelectionIndexes(); - - return {static_cast(indices.first), static_cast(indices.second), value}; + return {startOffset, endOffset, value}; } bool TextField::AccessibleImpl::RemoveSelection(size_t selectionIndex) @@ -1426,13 +1403,13 @@ Dali::Accessibility::States TextField::AccessibleImpl::CalculateStates() { using namespace Dali::Accessibility; - auto states = DevelControl::AccessibleImpl::CalculateStates(); + auto states = DevelControl::ControlAccessible::CalculateStates(); states[State::EDITABLE] = true; states[State::FOCUSABLE] = true; Toolkit::Control focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl(); - if(mSelf == focusControl) + if(Self() == focusControl) { states[State::FOCUSED] = true; } @@ -1459,6 +1436,30 @@ bool TextField::AccessibleImpl::SetTextContents(std::string newContents) return true; } +int32_t TextField::AccessibleImpl::GetLinkCount() const +{ + auto self = Toolkit::TextField::DownCast(Self()); + return Dali::Toolkit::GetImpl(self).mAnchorActors.size(); +} + +Accessibility::Hyperlink* TextField::AccessibleImpl::GetLink(int32_t linkIndex) const +{ + if(linkIndex < 0 || linkIndex >= GetLinkCount()) + { + return nullptr; + } + auto self = Toolkit::TextField::DownCast(Self()); + auto anchorActor = Dali::Toolkit::GetImpl(self).mAnchorActors[linkIndex]; + return dynamic_cast(Dali::Accessibility::Accessible::Get(anchorActor)); +} + +int32_t TextField::AccessibleImpl::GetLinkIndex(int32_t characterOffset) const +{ + auto self = Toolkit::TextField::DownCast(Self()); + auto controller = Dali::Toolkit::GetImpl(self).GetTextController(); + return controller->GetAnchorIndex(static_cast(characterOffset)); +} + } // namespace Internal } // namespace Toolkit