X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Ftext-controls%2Ftext-editor-impl.cpp;h=4e6fc1f1f7b5ec09f2e91a9ddfd210cc202520d4;hb=0512ac82e2c23d8eada7840b5a72cdabe13a5f54;hp=b07da0460a8f2a25aec99972a69567bbd793b698;hpb=760285a850a7bf256a799cfb23ff2283520dc02a;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git 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 b07da04..4e6fc1f 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-editor-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,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -31,11 +32,10 @@ #include // INTERNAL INCLUDES -#include #include -#include #include #include +#include #include #include #include @@ -145,6 +145,7 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "verticalScrollP 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, "enableFontSizeScale", BOOLEAN, ENABLE_FONT_SIZE_SCALE ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "primaryCursorPosition", INTEGER, PRIMARY_CURSOR_POSITION ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "grabHandleColor", VECTOR4, GRAB_HANDLE_COLOR ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "enableGrabHandlePopup", BOOLEAN, ENABLE_GRAB_HANDLE_POPUP ) @@ -153,6 +154,10 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "inputFilter", DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "ellipsis", BOOLEAN, ELLIPSIS ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "ellipsisPosition", INTEGER, ELLIPSIS_POSITION ) DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "minLineSize", FLOAT, MIN_LINE_SIZE ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "strikethrough", MAP, STRIKETHROUGH ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "inputStrikethrough", MAP, INPUT_STRIKETHROUGH ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "characterSpacing", FLOAT, CHARACTER_SPACING ) +DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "relativeLineSize", FLOAT, RELATIVE_LINE_SIZE ) DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged", SIGNAL_TEXT_CHANGED ) DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED ) @@ -162,10 +167,67 @@ DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputFiltered", SIGNAL_IN DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "cursorPositionChanged", SIGNAL_CURSOR_POSITION_CHANGED) DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "selectionChanged", SIGNAL_SELECTION_CHANGED ) DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "selectionCleared", SIGNAL_SELECTION_CLEARED ) +DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "selectionStarted", SIGNAL_SELECTION_STARTED ) DALI_TYPE_REGISTRATION_END() // clang-format on +Toolkit::TextEditor::InputStyle::Mask ConvertInputStyle(Text::InputStyle::Mask inputStyleMask) +{ + Toolkit::TextEditor::InputStyle::Mask editorInputStyleMask = Toolkit::TextEditor::InputStyle::NONE; + + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_COLOR)) + { + editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::COLOR); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_FAMILY)) + { + editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_FAMILY); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_POINT_SIZE)) + { + editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::POINT_SIZE); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_WEIGHT)) + { + editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_WIDTH)) + { + editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_SLANT)) + { + editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_LINE_SPACING)) + { + editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::LINE_SPACING); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_UNDERLINE)) + { + editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::UNDERLINE); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_SHADOW)) + { + editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::SHADOW); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_EMBOSS)) + { + editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::EMBOSS); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_OUTLINE)) + { + editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::OUTLINE); + } + if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_STRIKETHROUGH)) + { + editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::STRIKETHROUGH); + } + + return editorInputStyleMask; +} + } // namespace Toolkit::TextEditor TextEditor::New() @@ -289,6 +351,16 @@ float TextEditor::GetVerticalScrollPosition() return 0; } +Vector TextEditor::GetTextSize(const uint32_t startIndex, const uint32_t endIndex) const +{ + return mController->GetTextSize(startIndex, endIndex); +} + +Vector TextEditor::GetTextPosition(const uint32_t startIndex, const uint32_t endIndex) const +{ + return mController->GetTextPosition(startIndex, endIndex); +} + string TextEditor::GetSelectedText() const { string selectedText = ""; @@ -334,6 +406,11 @@ DevelTextEditor::SelectionClearedSignalType& TextEditor::SelectionClearedSignal( return mSelectionClearedSignal; } +DevelTextEditor::SelectionStartedSignalType& TextEditor::SelectionStartedSignal() +{ + return mSelectionStartedSignal; +} + Text::ControllerPtr TextEditor::GetTextController() { return mController; @@ -402,6 +479,14 @@ bool TextEditor::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* editorImpl.SelectionClearedSignal().Connect(tracker, functor); } } + else if(0 == strcmp(signalName.c_str(), SIGNAL_SELECTION_STARTED)) + { + if(editor) + { + Internal::TextEditor& editorImpl(GetImpl(editor)); + editorImpl.SelectionStartedSignal().Connect(tracker, functor); + } + } else { // signalName does not match any signal @@ -426,6 +511,11 @@ Toolkit::TextEditor::ScrollStateChangedSignalType& TextEditor::ScrollStateChange return mScrollStateChangedSignal; } +void TextEditor::OnAccessibilityStatusChanged() +{ + CommonTextUtils::SynchronizeTextAnchorsInParent(Self(), mController, mAnchorActors); +} + void TextEditor::OnInitialize() { Actor self = Self(); @@ -513,9 +603,11 @@ void TextEditor::OnInitialize() self.Add(mStencil); DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) { - return std::unique_ptr( - new AccessibleImpl(actor, Dali::Accessibility::Role::ENTRY)); + return std::make_unique(actor, Dali::Accessibility::Role::ENTRY); }); + + Accessibility::Bridge::EnabledSignal().Connect(this, &TextEditor::OnAccessibilityStatusChanged); + Accessibility::Bridge::DisabledSignal().Connect(this, &TextEditor::OnAccessibilityStatusChanged); } void TextEditor::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) @@ -607,6 +699,11 @@ void TextEditor::OnRelayout(const Vector2& size, RelayoutContainer& container) mActiveLayer.SetProperty(Actor::Property::POSITION, Vector2(padding.start, padding.top)); ResizeActor(mActiveLayer, contentSize); } + if(mCursorLayer) + { + mCursorLayer.SetProperty(Actor::Property::POSITION, Vector2(padding.start, padding.top)); + ResizeActor(mCursorLayer, contentSize); + } // If there is text changed, callback is called. if(mTextChanged) @@ -640,6 +737,11 @@ void TextEditor::OnRelayout(const Vector2& size, RelayoutContainer& container) EmitCursorPositionChangedSignal(); } + if(mSelectionStarted) + { + EmitSelectionStartedSignal(); + } + if(mSelectionChanged) { EmitSelectionChangedSignal(); @@ -672,100 +774,9 @@ void TextEditor::OnRelayout(const Vector2& size, RelayoutContainer& container) void TextEditor::RenderText(Text::Controller::UpdateTextType updateTextType) { - Actor renderableActor; - - if(Text::Controller::NONE_UPDATED != (Text::Controller::MODEL_UPDATED & updateTextType)) - { - if(mRenderer) - { - Dali::Toolkit::TextEditor handle = Dali::Toolkit::TextEditor(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(); - } - } - } - + CommonTextUtils::RenderText(Self(), mRenderer, mController, mDecorator, mAlignmentOffset, mRenderableActor, mBackgroundActor, mStencil, mClippingDecorationActors, mAnchorActors, updateTextType); 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(); - } - } - ApplyScrollPosition(); } UpdateScrollBar(); @@ -896,26 +907,17 @@ void TextEditor::RequestTextRelayout() void TextEditor::TextInserted(unsigned int position, unsigned int length, const std::string& content) { - if(Accessibility::IsUp()) - { - Control::Impl::GetAccessibilityObject(Self())->EmitTextInserted(position, length, content); - } + GetAccessibleObject()->EmitTextInserted(position, length, content); } void TextEditor::TextDeleted(unsigned int position, unsigned int length, const std::string& content) { - if(Accessibility::IsUp()) - { - Control::Impl::GetAccessibilityObject(Self())->EmitTextDeleted(position, length, content); - } + GetAccessibleObject()->EmitTextDeleted(position, length, content); } void TextEditor::CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition) { - if(Accessibility::IsUp()) - { - Control::Impl::GetAccessibilityObject(Self())->EmitTextCursorMoved(newPosition); - } + GetAccessibleObject()->EmitTextCursorMoved(newPosition); if((oldPosition != newPosition) && !mCursorPositionChanged) { @@ -952,55 +954,7 @@ void TextEditor::MaxLengthReached() void TextEditor::InputStyleChanged(Text::InputStyle::Mask inputStyleMask) { Dali::Toolkit::TextEditor handle(GetOwner()); - - Toolkit::TextEditor::InputStyle::Mask editorInputStyleMask = Toolkit::TextEditor::InputStyle::NONE; - - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_COLOR)) - { - editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::COLOR); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_FAMILY)) - { - editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_FAMILY); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_POINT_SIZE)) - { - editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::POINT_SIZE); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_WEIGHT)) - { - editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_WIDTH)) - { - editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_FONT_SLANT)) - { - editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_LINE_SPACING)) - { - editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::LINE_SPACING); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_UNDERLINE)) - { - editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::UNDERLINE); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_SHADOW)) - { - editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::SHADOW); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_EMBOSS)) - { - editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::EMBOSS); - } - if(InputStyle::NONE != static_cast(inputStyleMask & InputStyle::INPUT_OUTLINE)) - { - editorInputStyleMask = static_cast(editorInputStyleMask | Toolkit::TextEditor::InputStyle::OUTLINE); - } - - mInputStyleChangedSignal.Emit(handle, editorInputStyleMask); + mInputStyleChangedSignal.Emit(handle, ConvertInputStyle(inputStyleMask)); } void TextEditor::AnchorClicked(const std::string& href) @@ -1036,6 +990,13 @@ void TextEditor::EmitSelectionClearedSignal() mSelectionCleared = false; } +void TextEditor::EmitSelectionStartedSignal() +{ + Dali::Toolkit::TextEditor handle(GetOwner()); + mSelectionStartedSignal.Emit(handle); + mSelectionStarted = false; +} + void TextEditor::SelectionChanged(uint32_t oldStart, uint32_t oldEnd, uint32_t newStart, uint32_t newEnd) { if(((oldStart != newStart) || (oldEnd != newEnd)) && !mSelectionChanged) @@ -1044,6 +1005,13 @@ void TextEditor::SelectionChanged(uint32_t oldStart, uint32_t oldEnd, uint32_t n { mSelectionCleared = true; } + else + { + if(oldStart == oldEnd) + { + mSelectionStarted = true; + } + } mSelectionChanged = true; mOldSelectionStart = oldStart; @@ -1059,7 +1027,7 @@ void TextEditor::SelectionChanged(uint32_t oldStart, uint32_t oldEnd, uint32_t n } } -void TextEditor::AddDecoration(Actor& actor, bool needsClipping) +void TextEditor::AddDecoration(Actor& actor, DecorationType type, bool needsClipping) { if(actor) { @@ -1067,16 +1035,27 @@ void TextEditor::AddDecoration(Actor& actor, bool needsClipping) { mClippingDecorationActors.push_back(actor); } - else + + // If the actor is a layer type, add it. + if(type == DecorationType::ACTIVE_LAYER) { - actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT); - actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); - Self().Add(actor); - mActiveLayer = actor; + AddLayer(mActiveLayer, actor); + } + else if(type == DecorationType::CURSOR_LAYER) + { + AddLayer(mCursorLayer, actor); } } } +void TextEditor::AddLayer(Actor& layer, Actor& actor) +{ + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT); + actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + Self().Add(actor); + layer = actor; +} + void TextEditor::SetTextSelectionRange(const uint32_t* start, const uint32_t* end) { if(mController && mController->IsShowingRealText()) @@ -1343,7 +1322,8 @@ TextEditor::TextEditor() mSelectionCleared(false), mOldPosition(0u), mOldSelectionStart(0u), - mOldSelectionEnd(0u) + mOldSelectionEnd(0u), + mSelectionStarted(false) { } @@ -1358,273 +1338,31 @@ TextEditor::~TextEditor() } } -std::string TextEditor::AccessibleImpl::GetName() -{ - auto self = Toolkit::TextEditor::DownCast(Self()); - return self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get(); -} - -std::string TextEditor::AccessibleImpl::GetText(size_t startOffset, size_t endOffset) -{ - if(endOffset <= startOffset) - { - return {}; - } - - auto self = Toolkit::TextEditor::DownCast(Self()); - auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get(); - - if(startOffset > text.size() || endOffset > text.size()) - { - return {}; - } - - return text.substr(startOffset, endOffset - startOffset); -} - -size_t TextEditor::AccessibleImpl::GetCharacterCount() -{ - auto self = Toolkit::TextEditor::DownCast(Self()); - auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get(); - - return text.size(); -} - -size_t TextEditor::AccessibleImpl::GetCursorOffset() -{ - auto slf = Toolkit::TextEditor::DownCast(Self()); - return Dali::Toolkit::GetImpl(slf).GetTextController()->GetCursorPosition(); -} - -bool TextEditor::AccessibleImpl::SetCursorOffset(size_t offset) -{ - auto slf = Toolkit::TextEditor::DownCast(Self()); - auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get(); - if(offset > txt.size()) - { - return false; - } - - auto& slfImpl = Dali::Toolkit::GetImpl(slf); - slfImpl.GetTextController()->ResetCursorPosition(offset); - slfImpl.RequestTextRelayout(); - - return true; -} - -Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset(size_t offset, Dali::Accessibility::TextBoundary boundary) -{ - auto self = Toolkit::TextEditor::DownCast(Self()); - auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get(); - auto textSize = text.size(); - - auto range = Dali::Accessibility::Range{}; - - switch(boundary) - { - case Dali::Accessibility::TextBoundary::CHARACTER: - { - if(offset < textSize) - { - range.content = text[offset]; - range.startOffset = offset; - range.endOffset = offset + 1; - } - break; - } - case Dali::Accessibility::TextBoundary::WORD: - case Dali::Accessibility::TextBoundary::LINE: - { - auto textString = text.c_str(); - auto breaks = std::vector(textSize, 0); - - if(boundary == Dali::Accessibility::TextBoundary::WORD) - { - Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast(textString), textSize, "", breaks.data()); - } - else - { - Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast(textString), textSize, "", breaks.data()); - } - - auto index = 0u; - auto counter = 0u; - while(index < textSize && counter <= offset) - { - auto start = index; - if(breaks[index]) - { - while(breaks[index]) - { - index++; - } - counter++; - } - else - { - if(boundary == Dali::Accessibility::TextBoundary::WORD) - { - index++; - } - if(boundary == Dali::Accessibility::TextBoundary::LINE) - { - counter++; - } - } - - if((counter > 0) && ((counter - 1) == offset)) - { - range.content = text.substr(start, index - start + 1); - range.startOffset = start; - range.endOffset = index + 1; - } - - if(boundary == Dali::Accessibility::TextBoundary::LINE) - { - index++; - } - } - break; - } - case Dali::Accessibility::TextBoundary::SENTENCE: - { - /* not supported by default */ - break; - } - case Dali::Accessibility::TextBoundary::PARAGRAPH: - { - /* Paragraph is not supported by libunibreak library */ - break; - } - default: - break; - } - - return range; -} - -Dali::Accessibility::Range TextEditor::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex) -{ - // Since DALi supports only one selection indexes higher than 0 are ignored - if(selectionIndex > 0) - { - return {}; - } - - auto self = Toolkit::TextEditor::DownCast(Self()); - auto controller = Dali::Toolkit::GetImpl(self).GetTextController(); - std::string value{}; - controller->RetrieveSelection(value); - auto indices = controller->GetSelectionIndexes(); - - return {static_cast(indices.first), static_cast(indices.second), value}; -} - -bool TextEditor::AccessibleImpl::RemoveSelection(size_t selectionIndex) -{ - // Since DALi supports only one selection indexes higher than 0 are ignored - if(selectionIndex > 0) - { - return false; - } - - auto self = Toolkit::TextEditor::DownCast(Self()); - Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0); - return true; -} - -bool TextEditor::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset) -{ - // Since DALi supports only one selection indexes higher than 0 are ignored - if(selectionIndex > 0) - { - return false; - } - - auto self = Toolkit::TextEditor::DownCast(Self()); - Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset); - return true; -} - -bool TextEditor::AccessibleImpl::CopyText(size_t startPosition, size_t endPosition) +std::string TextEditor::TextEditorAccessible::GetName() const { - if(endPosition <= startPosition) - { - return false; - } - - auto self = Toolkit::TextEditor::DownCast(Self()); - auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get(); - Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition)); - - return true; + return GetWholeText(); } -bool TextEditor::AccessibleImpl::CutText(size_t startPosition, size_t endPosition) +const std::vector& TextEditor::TextEditorAccessible::GetTextAnchors() const { - if(endPosition <= startPosition) - { - return false; - } - auto self = Toolkit::TextEditor::DownCast(Self()); - auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get(); - Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition)); - self.SetProperty(Toolkit::TextEditor::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition)); - - return true; + return Toolkit::GetImpl(self).mAnchorActors; } -bool TextEditor::AccessibleImpl::DeleteText(size_t startPosition, size_t endPosition) +Toolkit::Text::ControllerPtr TextEditor::TextEditorAccessible::GetTextController() const { - if(endPosition <= startPosition) - { - return false; - } - auto self = Toolkit::TextEditor::DownCast(Self()); - auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get(); - - self.SetProperty(Toolkit::TextEditor::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition)); - return true; + return Toolkit::GetImpl(self).GetTextController(); } -Dali::Accessibility::States TextEditor::AccessibleImpl::CalculateStates() +void TextEditor::TextEditorAccessible::RequestTextRelayout() { - using namespace Dali::Accessibility; - - auto states = DevelControl::AccessibleImpl::CalculateStates(); - states[State::EDITABLE] = true; - states[State::FOCUSABLE] = true; - - Toolkit::Control focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl(); - if(mSelf == focusControl) - { - states[State::FOCUSED] = true; - } + auto self = Toolkit::TextEditor::DownCast(Self()); + auto& selfImpl = Toolkit::GetImpl(self); - return states; -} - -bool TextEditor::AccessibleImpl::InsertText(size_t startPosition, std::string text) -{ - auto self = Toolkit::TextEditor::DownCast(Self()); - auto insertedText = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get(); - - insertedText.insert(startPosition, text); - - self.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(insertedText)); - - return true; -} - -bool TextEditor::AccessibleImpl::SetTextContents(std::string newContents) -{ - auto self = Toolkit::TextEditor::DownCast(Self()); - self.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(newContents)); - return true; + selfImpl.RequestTextRelayout(); } } // namespace Internal