/*
- * 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.
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 )
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_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged", SIGNAL_TEXT_CHANGED )
DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED )
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
{
editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::OUTLINE);
}
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_STRIKETHROUGH))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::STRIKETHROUGH);
+ }
+
return editorInputStyleMask;
}
return 0;
}
+Vector<Vector2> TextEditor::GetTextSize(const uint32_t startIndex, const uint32_t endIndex) const
+{
+ return mController->GetTextSize(startIndex, endIndex);
+}
+
+Vector<Vector2> TextEditor::GetTextPosition(const uint32_t startIndex, const uint32_t endIndex) const
+{
+ return mController->GetTextPosition(startIndex, endIndex);
+}
+
string TextEditor::GetSelectedText() const
{
string selectedText = "";
return mSelectionClearedSignal;
}
+DevelTextEditor::SelectionStartedSignalType& TextEditor::SelectionStartedSignal()
+{
+ return mSelectionStartedSignal;
+}
+
Text::ControllerPtr TextEditor::GetTextController()
{
return mController;
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
return mScrollStateChangedSignal;
}
+void TextEditor::OnAccessibilityStatusChanged()
+{
+ CommonTextUtils::SynchronizeTextAnchorsInParent(Self(), mController, mAnchorActors);
+}
+
void TextEditor::OnInitialize()
{
Actor self = Self();
return std::unique_ptr<Dali::Accessibility::Accessible>(
new AccessibleImpl(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)
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)
EmitCursorPositionChangedSignal();
}
+ if(mSelectionStarted)
+ {
+ EmitSelectionStartedSignal();
+ }
+
if(mSelectionChanged)
{
EmitSelectionChangedSignal();
void TextEditor::RenderText(Text::Controller::UpdateTextType updateTextType)
{
- CommonTextUtils::RenderText(Self(), mRenderer, mController, mDecorator, mAlignmentOffset, mRenderableActor, mBackgroundActor, mStencil, mClippingDecorationActors, updateTextType);
+ CommonTextUtils::RenderText(Self(), mRenderer, mController, mDecorator, mAlignmentOffset, mRenderableActor, mBackgroundActor, mStencil, mClippingDecorationActors, mAnchorActors, updateTextType);
if(mRenderableActor)
{
ApplyScrollPosition();
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)
{
mSelectionCleared = true;
}
+ else
+ {
+ if(oldStart == oldEnd)
+ {
+ mSelectionStarted = true;
+ }
+ }
mSelectionChanged = true;
mOldSelectionStart = oldStart;
}
}
-void TextEditor::AddDecoration(Actor& actor, bool needsClipping)
+void TextEditor::AddDecoration(Actor& actor, DecorationType type, bool needsClipping)
{
if(actor)
{
{
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())
mSelectionCleared(false),
mOldPosition(0u),
mOldSelectionStart(0u),
- mOldSelectionEnd(0u)
+ mOldSelectionEnd(0u),
+ mSelectionStarted(false)
{
}
}
}
-std::string TextEditor::AccessibleImpl::GetName()
+std::string TextEditor::AccessibleImpl::GetName() const
{
auto self = Toolkit::TextEditor::DownCast(Self());
return self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
}
-std::string TextEditor::AccessibleImpl::GetText(size_t startOffset, size_t endOffset)
+std::string TextEditor::AccessibleImpl::GetText(size_t startOffset, size_t endOffset) const
{
if(endOffset <= startOffset)
{
return text.substr(startOffset, endOffset - startOffset);
}
-size_t TextEditor::AccessibleImpl::GetCharacterCount()
+size_t TextEditor::AccessibleImpl::GetCharacterCount() const
{
auto self = Toolkit::TextEditor::DownCast(Self());
auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
return text.size();
}
-size_t TextEditor::AccessibleImpl::GetCursorOffset()
+size_t TextEditor::AccessibleImpl::GetCursorOffset() const
{
auto slf = Toolkit::TextEditor::DownCast(Self());
return Dali::Toolkit::GetImpl(slf).GetTextController()->GetCursorPosition();
return true;
}
-Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset(size_t offset, Dali::Accessibility::TextBoundary boundary)
+Dali::Accessibility::Range TextEditor::AccessibleImpl::GetTextAtOffset(size_t offset, Dali::Accessibility::TextBoundary boundary) const
{
auto self = Toolkit::TextEditor::DownCast(Self());
auto text = self.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
return range;
}
-Dali::Accessibility::Range TextEditor::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex)
+Dali::Accessibility::Range TextEditor::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex) const
{
// Since DALi supports only one selection indexes higher than 0 are ignored
if(selectionIndex > 0)
{
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;
}
return true;
}
+int32_t TextEditor::AccessibleImpl::GetLinkCount() const
+{
+ auto self = Toolkit::TextEditor::DownCast(Self());
+ return Dali::Toolkit::GetImpl(self).mAnchorActors.size();
+}
+
+Accessibility::Hyperlink* TextEditor::AccessibleImpl::GetLink(int32_t linkIndex) const
+{
+ if(linkIndex < 0 || linkIndex >= GetLinkCount())
+ {
+ return nullptr;
+ }
+ auto self = Toolkit::TextEditor::DownCast(Self());
+ auto anchorActor = Dali::Toolkit::GetImpl(self).mAnchorActors[linkIndex];
+ return dynamic_cast<Accessibility::Hyperlink*>(Dali::Accessibility::Accessible::Get(anchorActor));
+}
+
+int32_t TextEditor::AccessibleImpl::GetLinkIndex(int32_t characterOffset) const
+{
+ auto self = Toolkit::TextEditor::DownCast(Self());
+ auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
+ return controller->GetAnchorIndex(static_cast<size_t>(characterOffset));
+}
+
} // namespace Internal
} // namespace Toolkit