// EXTERNAL INCLUDES
#include <dali/devel-api/actors/actor-devel.h>
-#include <dali/devel-api/adaptor-framework/window-devel.h>
#include <dali/devel-api/common/stage.h>
#include <dali/devel-api/object/property-helper-devel.h>
#include <dali/integration-api/adaptor-framework/adaptor.h>
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, "inputMethodSettings", MAP, INPUT_METHOD_SETTINGS )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextEditor, "inputFilter", MAP, INPUT_FILTER )
DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged", SIGNAL_TEXT_CHANGED )
DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED)
DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "maxLengthReached", SIGNAL_MAX_LENGTH_REACHED )
DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "anchorClicked", SIGNAL_ANCHOR_CLICKED )
+DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputFiltered", SIGNAL_INPUT_FILTERED )
+
DALI_TYPE_REGISTRATION_END()
// clang-format on
}
case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
{
- impl.mController->SetMatchSystemLanguageDirection(value.Get<bool>());
+ impl.mController->SetMatchLayoutDirection(value.Get<bool>() ? DevelText::MatchLayoutDirection::LOCALE : DevelText::MatchLayoutDirection::CONTENTS);
break;
}
case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
impl.mController->SetGrabHandlePopupEnabled(grabHandlePopupEnabled);
break;
}
+ case Toolkit::DevelTextEditor::Property::INPUT_METHOD_SETTINGS:
+ {
+ const Property::Map* map = value.GetMap();
+ if(map)
+ {
+ impl.mInputMethodOptions.ApplyProperty(*map);
+ }
+ impl.mController->SetInputModePassword(impl.mInputMethodOptions.IsPassword());
+
+ Toolkit::Control control = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
+ if(control == textEditor)
+ {
+ impl.mInputMethodContext.ApplyOptions(impl.mInputMethodOptions);
+ }
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::INPUT_FILTER:
+ {
+ const Property::Map* map = value.GetMap();
+ if(map)
+ {
+ impl.mController->SetInputFilterOption(*map);
+ }
+ break;
+ }
} // switch
} // texteditor
}
}
case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
{
- value = impl.mController->IsMatchSystemLanguageDirection();
+ value = impl.mController->GetMatchLayoutDirection() != DevelText::MatchLayoutDirection::CONTENTS;
break;
}
case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
value = impl.mController->IsGrabHandlePopupEnabled();
break;
}
+ case Toolkit::DevelTextEditor::Property::INPUT_METHOD_SETTINGS:
+ {
+ Property::Map map;
+ impl.mInputMethodOptions.RetrieveProperty(map);
+ value = map;
+ break;
+ }
+ case Toolkit::DevelTextEditor::Property::INPUT_FILTER:
+ {
+ Property::Map map;
+ impl.mController->GetInputFilterOption(map);
+ value = map;
+ break;
+ }
} //switch
}
return mAnchorClickedSignal;
}
+DevelTextEditor::InputFilteredSignalType& TextEditor::InputFilteredSignal()
+{
+ return mInputFilteredSignal;
+}
+
Text::ControllerPtr TextEditor::getController()
{
return mController;
editorImpl.AnchorClickedSignal().Connect(tracker, functor);
}
}
+ else if(0 == strcmp(signalName.c_str(), SIGNAL_INPUT_FILTERED))
+ {
+ if(editor)
+ {
+ Internal::TextEditor& editorImpl(GetImpl(editor));
+ editorImpl.InputFilteredSignal().Connect(tracker, functor);
+ }
+ }
else
{
// signalName does not match any signal
Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(stage.GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
mController->SetLayoutDirection(layoutDirection);
+ self.LayoutDirectionChangedSignal().Connect(this, &TextEditor::OnLayoutDirectionChanged);
+
// Forward input events to controller
EnableGestureDetection(static_cast<GestureType::Value>(GestureType::TAP | GestureType::PAN | GestureType::LONG_PRESS));
GetTapGestureDetector().SetMaximumTapsRequired(2);
Vector2 contentSize(size.x - (padding.start + padding.end), size.y - (padding.top + padding.bottom));
// Support Right-To-Left of padding
- Dali::LayoutDirection::Type layoutDirection;
- if(mController->IsMatchSystemLanguageDirection())
- {
- layoutDirection = static_cast<Dali::LayoutDirection::Type>(DevelWindow::Get(self).GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
- }
- else
- {
- layoutDirection = static_cast<Dali::LayoutDirection::Type>(self.GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
- }
+ Dali::LayoutDirection::Type layoutDirection = mController->GetLayoutDirection(self);
+
if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
{
std::swap(padding.start, padding.end);
ResizeActor(mActiveLayer, contentSize);
}
+ // If there is text changed, callback is called.
+ if(mTextChanged)
+ {
+ EmitTextChangedSignal();
+ }
+
const Text::Controller::UpdateTextType updateTextType = mController->Relayout(contentSize, layoutDirection);
if((Text::Controller::NONE_UPDATED != updateTextType) ||
}
RenderText(updateTextType);
-
- // If there is text changed, callback is called.
- if(mTextChanged)
- {
- EmitTextChangedSignal();
- }
}
// The text-editor emits signals when the input style changes. These changes of style are
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<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;
{
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();
if(mInputMethodContext && IsEditable())
{
// All input panel properties, such as layout, return key type, and input hint, should be set before input panel activates (or shows).
+ mInputMethodContext.ApplyOptions(mInputMethodOptions);
mInputMethodContext.NotifyTextInputMultiLine(true);
mInputMethodContext.StatusChangedSignal().Connect(this, &TextEditor::KeyboardStatusChanged);
mAnchorClickedSignal.Emit(handle, href.c_str(), href.length());
}
+void TextEditor::InputFiltered(Toolkit::InputFilter::Property::Type type)
+{
+ Dali::Toolkit::TextEditor handle(GetOwner());
+ mInputFilteredSignal.Emit(handle, type);
+}
+
void TextEditor::AddDecoration(Actor& actor, bool needsClipping)
{
if(actor)
return range;
}
+void TextEditor::GetControlBackgroundColor(Vector4& color) const
+{
+ Property::Value propValue = Self().GetProperty(Toolkit::Control::Property::BACKGROUND);
+ Property::Map* resultMap = propValue.GetMap();
+
+ Property::Value* colorValue = nullptr;
+ if(resultMap && (colorValue = resultMap->Find(ColorVisual::Property::MIX_COLOR)))
+ {
+ colorValue->Get(color);
+ }
+}
+
void TextEditor::UpdateScrollBar()
{
using namespace Dali;
}
}
+void TextEditor::OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type)
+{
+ mController->ChangedLayoutDirection();
+}
+
TextEditor::TextEditor()
: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
mAnimationPeriod(0.0f, 0.0f),
Dali::Toolkit::GetImpl(slf).getController()->CopyStringToClipboard(txt.substr(startPosition, endPosition - startPosition));
slf.SetProperty(Toolkit::TextEditor::Property::TEXT,
- txt.substr(0, startPosition) + txt.substr(endPosition - startPosition, txt.size()));
+ txt.substr(0, startPosition) + txt.substr(endPosition));
+
+ return true;
+}
+
+bool TextEditor::AccessibleImpl::DeleteText(size_t startPosition,
+ size_t endPosition)
+{
+ if(endPosition <= startPosition)
+ return false;
+
+ auto slf = Toolkit::TextEditor::DownCast(Self());
+ auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
+
+ slf.SetProperty(Toolkit::TextEditor::Property::TEXT,
+ txt.substr(0, startPosition) + txt.substr(endPosition));
return true;
}
return states;
}
+bool TextEditor::AccessibleImpl::InsertText(size_t startPosition,
+ std::string text)
+{
+ auto slf = Toolkit::TextEditor::DownCast(Self());
+ auto txt = slf.GetProperty(Toolkit::TextEditor::Property::TEXT).Get<std::string>();
+
+ txt.insert(startPosition, text);
+
+ slf.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(txt));
+
+ return true;
+}
+
+bool TextEditor::AccessibleImpl::SetTextContents(std::string newContents)
+{
+ auto slf = Toolkit::TextEditor::DownCast(Self());
+ slf.SetProperty(Toolkit::TextEditor::Property::TEXT, std::move(newContents));
+ return true;
+}
+
} // namespace Internal
} // namespace Toolkit