/*
- * 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.
#include <dali/devel-api/object/property-helper-devel.h>
#include <dali/integration-api/adaptor-framework/adaptor.h>
#include <dali/integration-api/debug.h>
+#include <dali/public-api/actors/layer.h>
#include <dali/public-api/adaptor-framework/key.h>
#include <dali/public-api/common/dali-common.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <limits>
// INTERNAL INCLUDES
-#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
#include <dali-toolkit/devel-api/text/rendering-backend.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
#include <dali-toolkit/internal/controls/text-controls/text-editor-property-handler.h>
#include <dali-toolkit/internal/styling/style-manager-impl.h>
#include <dali-toolkit/internal/text/rendering/text-backend.h>
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_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<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_COLOR))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::COLOR);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_FAMILY))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_FAMILY);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_POINT_SIZE))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::POINT_SIZE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WEIGHT))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WIDTH))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_SLANT))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_LINE_SPACING))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::LINE_SPACING);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_UNDERLINE))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::UNDERLINE);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_SHADOW))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::SHADOW);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_EMBOSS))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::EMBOSS);
+ }
+ if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_OUTLINE))
+ {
+ editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::OUTLINE);
+ }
+ return editorInputStyleMask;
+}
+
} // namespace
Toolkit::TextEditor TextEditor::New()
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 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)
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<Extents>(Toolkit::Control::Property::PADDING);
-
- // Support Right-To-Left of padding
- Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(Self().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
- 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<Actor>::iterator it = mClippingDecorationActors.begin(),
- endIt = mClippingDecorationActors.end();
- it != endIt;
- ++it)
- {
- self.Add(*it);
- it->LowerToBottom();
-
- if(it->GetProperty<std::string>(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();
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<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_COLOR))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::COLOR);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_FAMILY))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_FAMILY);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_POINT_SIZE))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::POINT_SIZE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WEIGHT))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WIDTH))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_SLANT))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::FONT_STYLE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_LINE_SPACING))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::LINE_SPACING);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_UNDERLINE))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::UNDERLINE);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_SHADOW))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::SHADOW);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_EMBOSS))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::EMBOSS);
- }
- if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_OUTLINE))
- {
- editorInputStyleMask = static_cast<Toolkit::TextEditor::InputStyle::Mask>(editorInputStyleMask | Toolkit::TextEditor::InputStyle::OUTLINE);
- }
-
- mInputStyleChangedSignal.Emit(handle, editorInputStyleMask);
+ mInputStyleChangedSignal.Emit(handle, ConvertInputStyle(inputStyleMask));
}
void TextEditor::AnchorClicked(const std::string& href)
}
}
-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