2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-toolkit/internal/controls/text-controls/text-field-impl.h>
22 #include <dali/devel-api/actors/actor-devel.h>
23 #include <dali/devel-api/adaptor-framework/key-devel.h>
24 #include <dali/devel-api/common/stage.h>
25 #include <dali/devel-api/object/property-helper-devel.h>
26 #include <dali/integration-api/debug.h>
27 #include <dali/public-api/actors/layer.h>
28 #include <dali/public-api/adaptor-framework/key.h>
29 #include <dali/public-api/common/dali-common.h>
30 #include <dali/public-api/object/type-registry-helper.h>
34 #include <dali-toolkit/devel-api/controls/control-devel.h>
35 #include <dali-toolkit/devel-api/controls/text-controls/text-field-devel.h>
36 #include <dali-toolkit/devel-api/text/rendering-backend.h>
37 #include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
38 #include <dali-toolkit/internal/controls/text-controls/text-field-property-handler.h>
39 #include <dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h>
40 #include <dali-toolkit/internal/styling/style-manager-impl.h>
41 #include <dali-toolkit/internal/text/rendering/text-backend.h>
42 #include <dali-toolkit/internal/text/text-effects-style.h>
43 #include <dali-toolkit/internal/text/text-enumerations-impl.h>
44 #include <dali-toolkit/internal/text/text-font-style.h>
45 #include <dali-toolkit/internal/text/text-view.h>
46 #include <dali-toolkit/public-api/text/text-enumerations.h>
47 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
48 #include <dali-toolkit/public-api/visuals/visual-properties.h>
49 #include <dali/integration-api/adaptor-framework/adaptor.h>
51 using namespace Dali::Toolkit::Text;
53 #if defined(DEBUG_ENABLED)
54 Debug::Filter* gTextFieldLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
63 namespace // unnamed namespace
65 const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::DevelText::DEFAULT_RENDERING_BACKEND;
66 } // unnamed namespace
73 return Toolkit::TextField::New();
77 // Setup properties, signals and actions using the type-registry.
78 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextField, Toolkit::Control, Create );
80 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "text", STRING, TEXT )
81 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "placeholderText", STRING, PLACEHOLDER_TEXT )
82 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "placeholderTextFocused", STRING, PLACEHOLDER_TEXT_FOCUSED )
83 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "fontFamily", STRING, FONT_FAMILY )
84 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "fontStyle", MAP, FONT_STYLE )
85 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "pointSize", FLOAT, POINT_SIZE )
86 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "maxLength", INTEGER, MAX_LENGTH )
87 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "exceedPolicy", INTEGER, EXCEED_POLICY )
88 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "horizontalAlignment", STRING, HORIZONTAL_ALIGNMENT )
89 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "verticalAlignment", STRING, VERTICAL_ALIGNMENT )
90 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "textColor", VECTOR4, TEXT_COLOR )
91 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "placeholderTextColor", VECTOR4, PLACEHOLDER_TEXT_COLOR )
92 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "primaryCursorColor", VECTOR4, PRIMARY_CURSOR_COLOR )
93 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "secondaryCursorColor", VECTOR4, SECONDARY_CURSOR_COLOR )
94 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "enableCursorBlink", BOOLEAN, ENABLE_CURSOR_BLINK )
95 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "cursorBlinkInterval", FLOAT, CURSOR_BLINK_INTERVAL )
96 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "cursorBlinkDuration", FLOAT, CURSOR_BLINK_DURATION )
97 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "cursorWidth", INTEGER, CURSOR_WIDTH )
98 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "grabHandleImage", STRING, GRAB_HANDLE_IMAGE )
99 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "grabHandlePressedImage", STRING, GRAB_HANDLE_PRESSED_IMAGE )
100 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "scrollThreshold", FLOAT, SCROLL_THRESHOLD )
101 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "scrollSpeed", FLOAT, SCROLL_SPEED )
102 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "selectionHandleImageLeft", MAP, SELECTION_HANDLE_IMAGE_LEFT )
103 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "selectionHandleImageRight", MAP, SELECTION_HANDLE_IMAGE_RIGHT )
104 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "selectionHandlePressedImageLeft", MAP, SELECTION_HANDLE_PRESSED_IMAGE_LEFT )
105 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "selectionHandlePressedImageRight", MAP, SELECTION_HANDLE_PRESSED_IMAGE_RIGHT)
106 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "selectionHandleMarkerImageLeft", MAP, SELECTION_HANDLE_MARKER_IMAGE_LEFT )
107 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "selectionHandleMarkerImageRight", MAP, SELECTION_HANDLE_MARKER_IMAGE_RIGHT )
108 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "selectionHighlightColor", VECTOR4, SELECTION_HIGHLIGHT_COLOR )
109 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "decorationBoundingBox", RECTANGLE, DECORATION_BOUNDING_BOX )
110 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "inputMethodSettings", MAP, INPUT_METHOD_SETTINGS )
111 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "inputColor", VECTOR4, INPUT_COLOR )
112 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "enableMarkup", BOOLEAN, ENABLE_MARKUP )
113 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "inputFontFamily", STRING, INPUT_FONT_FAMILY )
114 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "inputFontStyle", MAP, INPUT_FONT_STYLE )
115 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "inputPointSize", FLOAT, INPUT_POINT_SIZE )
116 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "underline", MAP, UNDERLINE )
117 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "inputUnderline", MAP, INPUT_UNDERLINE )
118 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "shadow", MAP, SHADOW )
119 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "inputShadow", MAP, INPUT_SHADOW )
120 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "emboss", MAP, EMBOSS )
121 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "inputEmboss", MAP, INPUT_EMBOSS )
122 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "outline", MAP, OUTLINE )
123 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "inputOutline", MAP, INPUT_OUTLINE )
124 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "hiddenInputSettings", MAP, HIDDEN_INPUT_SETTINGS )
125 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "pixelSize", FLOAT, PIXEL_SIZE )
126 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "enableSelection", BOOLEAN, ENABLE_SELECTION )
127 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "placeholder", MAP, PLACEHOLDER )
128 DALI_PROPERTY_REGISTRATION(Toolkit, TextField, "ellipsis", BOOLEAN, ELLIPSIS )
129 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "enableShiftSelection", BOOLEAN, ENABLE_SHIFT_SELECTION )
130 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "enableGrabHandle", BOOLEAN, ENABLE_GRAB_HANDLE )
131 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "matchSystemLanguageDirection", BOOLEAN, MATCH_SYSTEM_LANGUAGE_DIRECTION )
132 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "enableGrabHandlePopup", BOOLEAN, ENABLE_GRAB_HANDLE_POPUP )
133 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "textBackground", VECTOR4, BACKGROUND )
134 DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY(Toolkit, TextField, "selectedText", STRING, SELECTED_TEXT )
135 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "renderingBackend", INTEGER, RENDERING_BACKEND )
136 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "selectedTextStart", INTEGER, SELECTED_TEXT_START )
137 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "selectedTextEnd", INTEGER, SELECTED_TEXT_END )
138 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "enableEditing", BOOLEAN, ENABLE_EDITING )
139 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "fontSizeScale", FLOAT, FONT_SIZE_SCALE )
140 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "enableFontSizeScale", BOOLEAN, ENABLE_FONT_SIZE_SCALE )
141 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "primaryCursorPosition", INTEGER, PRIMARY_CURSOR_POSITION )
142 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "grabHandleColor", VECTOR4, GRAB_HANDLE_COLOR )
143 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "inputFilter", MAP, INPUT_FILTER )
144 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "ellipsisPosition", INTEGER, ELLIPSIS_POSITION )
145 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "strikethrough", MAP, STRIKETHROUGH )
146 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "inputStrikethrough", MAP, INPUT_STRIKETHROUGH )
147 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "characterSpacing", FLOAT, CHARACTER_SPACING )
148 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit, TextField, "selectionPopupStyle", MAP, SELECTION_POPUP_STYLE )
150 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "textChanged", SIGNAL_TEXT_CHANGED )
151 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "maxLengthReached", SIGNAL_MAX_LENGTH_REACHED )
152 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED )
153 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "anchorClicked", SIGNAL_ANCHOR_CLICKED )
154 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "inputFiltered", SIGNAL_INPUT_FILTERED )
155 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "cursorPositionChanged", SIGNAL_CURSOR_POSITION_CHANGED)
156 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "selectionChanged", SIGNAL_SELECTION_CHANGED )
157 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "selectionCleared", SIGNAL_SELECTION_CLEARED )
158 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "selectionStarted", SIGNAL_SELECTION_STARTED )
160 DALI_TYPE_REGISTRATION_END()
163 Toolkit::TextField::InputStyle::Mask ConvertInputStyle(Text::InputStyle::Mask inputStyleMask)
165 Toolkit::TextField::InputStyle::Mask fieldInputStyleMask = Toolkit::TextField::InputStyle::NONE;
167 if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_COLOR))
169 fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::COLOR);
171 if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_FAMILY))
173 fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_FAMILY);
175 if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_POINT_SIZE))
177 fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::POINT_SIZE);
179 if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WEIGHT))
181 fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE);
183 if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WIDTH))
185 fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE);
187 if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_SLANT))
189 fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE);
191 if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_UNDERLINE))
193 fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::UNDERLINE);
195 if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_SHADOW))
197 fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::SHADOW);
199 if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_EMBOSS))
201 fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::EMBOSS);
203 if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_OUTLINE))
205 fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::OUTLINE);
207 return fieldInputStyleMask;
212 Toolkit::TextField TextField::New()
214 // Create the implementation, temporarily owned by this handle on stack
215 IntrusivePtr<TextField> impl = new TextField();
217 // Pass ownership to CustomActor handle
218 Toolkit::TextField handle(*impl);
220 // Second-phase init of the implementation
221 // This can only be done after the CustomActor connection has been made...
227 void TextField::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
229 Toolkit::TextField textField = Toolkit::TextField::DownCast(Dali::BaseHandle(object));
231 DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField SetProperty\n");
235 PropertyHandler::SetProperty(textField, index, value);
239 Property::Value TextField::GetProperty(BaseObject* object, Property::Index index)
241 Property::Value value;
243 Toolkit::TextField textField = Toolkit::TextField::DownCast(Dali::BaseHandle(object));
247 value = PropertyHandler::GetProperty(textField, index);
253 void TextField::SelectWholeText()
255 if(mController && mController->IsShowingRealText())
257 mController->SelectWholeText();
262 void TextField::SelectNone()
264 if(mController && mController->IsShowingRealText())
266 mController->SelectNone();
270 void TextField::SelectText(const uint32_t start, const uint32_t end)
272 if(mController && mController->IsShowingRealText())
274 mController->SelectText(start, end);
279 string TextField::GetSelectedText() const
281 string selectedText = "";
282 if(mController && mController->IsShowingRealText())
284 selectedText = mController->GetSelectedText();
289 void TextField::SetTextSelectionRange(const uint32_t* start, const uint32_t* end)
291 if(mController && mController->IsShowingRealText())
293 mController->SetTextSelectionRange(start, end);
298 Uint32Pair TextField::GetTextSelectionRange() const
301 if(mController && mController->IsShowingRealText())
303 range = mController->GetTextSelectionRange();
308 string TextField::CopyText()
310 string copiedText = "";
311 if(mController && mController->IsShowingRealText())
313 copiedText = mController->CopyText();
318 string TextField::CutText()
321 if(mController && mController->IsShowingRealText())
323 cutText = mController->CutText();
328 void TextField::PasteText()
332 SetKeyInputFocus(); //Giving focus to the field that was passed to the PasteText in case the passed field (current field) doesn't have focus.
333 mController->PasteText();
337 InputMethodContext TextField::GetInputMethodContext()
339 return mInputMethodContext;
342 bool TextField::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
344 Dali::BaseHandle handle(object);
346 bool connected(true);
347 Toolkit::TextField field = Toolkit::TextField::DownCast(handle);
349 if(0 == strcmp(signalName.c_str(), SIGNAL_TEXT_CHANGED))
351 field.TextChangedSignal().Connect(tracker, functor);
353 else if(0 == strcmp(signalName.c_str(), SIGNAL_MAX_LENGTH_REACHED))
355 field.MaxLengthReachedSignal().Connect(tracker, functor);
357 else if(0 == strcmp(signalName.c_str(), SIGNAL_INPUT_STYLE_CHANGED))
359 field.InputStyleChangedSignal().Connect(tracker, functor);
361 else if(0 == strcmp(signalName.c_str(), SIGNAL_ANCHOR_CLICKED))
365 Internal::TextField& fieldImpl(GetImpl(field));
366 fieldImpl.AnchorClickedSignal().Connect(tracker, functor);
369 else if(0 == strcmp(signalName.c_str(), SIGNAL_CURSOR_POSITION_CHANGED))
373 Internal::TextField& fieldImpl(GetImpl(field));
374 fieldImpl.CursorPositionChangedSignal().Connect(tracker, functor);
377 else if(0 == strcmp(signalName.c_str(), SIGNAL_INPUT_FILTERED))
381 Internal::TextField& fieldImpl(GetImpl(field));
382 fieldImpl.InputFilteredSignal().Connect(tracker, functor);
385 else if(0 == strcmp(signalName.c_str(), SIGNAL_SELECTION_CHANGED))
389 Internal::TextField& fieldImpl(GetImpl(field));
390 fieldImpl.SelectionChangedSignal().Connect(tracker, functor);
393 else if(0 == strcmp(signalName.c_str(), SIGNAL_SELECTION_CLEARED))
397 Internal::TextField& fieldImpl(GetImpl(field));
398 fieldImpl.SelectionClearedSignal().Connect(tracker, functor);
401 else if(0 == strcmp(signalName.c_str(), SIGNAL_SELECTION_STARTED))
405 Internal::TextField& fieldImpl(GetImpl(field));
406 fieldImpl.SelectionStartedSignal().Connect(tracker, functor);
411 // signalName does not match any signal
418 Toolkit::TextField::TextChangedSignalType& TextField::TextChangedSignal()
420 return mTextChangedSignal;
423 Toolkit::TextField::MaxLengthReachedSignalType& TextField::MaxLengthReachedSignal()
425 return mMaxLengthReachedSignal;
428 Toolkit::TextField::InputStyleChangedSignalType& TextField::InputStyleChangedSignal()
430 return mInputStyleChangedSignal;
433 DevelTextField::AnchorClickedSignalType& TextField::AnchorClickedSignal()
435 return mAnchorClickedSignal;
438 DevelTextField::CursorPositionChangedSignalType& TextField::CursorPositionChangedSignal()
440 return mCursorPositionChangedSignal;
443 DevelTextField::InputFilteredSignalType& TextField::InputFilteredSignal()
445 return mInputFilteredSignal;
448 DevelTextField::SelectionChangedSignalType& TextField::SelectionChangedSignal()
450 return mSelectionChangedSignal;
453 DevelTextField::SelectionClearedSignalType& TextField::SelectionClearedSignal()
455 return mSelectionClearedSignal;
458 DevelTextField::SelectionStartedSignalType& TextField::SelectionStartedSignal()
460 return mSelectionStartedSignal;
463 void TextField::OnAccessibilityStatusChanged()
465 CommonTextUtils::SynchronizeTextAnchorsInParent(Self(), mController, mAnchorActors);
468 void TextField::OnInitialize()
472 mController = Text::Controller::New(this, this, this, this);
474 // When using the vector-based rendering, the size of the GLyphs are different
475 TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
476 mController->SetGlyphType(glyphType);
478 mDecorator = Text::Decorator::New(*mController,
481 mInputMethodContext = InputMethodContext::New(self);
483 mController->GetLayoutEngine().SetLayout(Layout::Engine::SINGLE_LINE_BOX);
485 // Enables the text input.
486 mController->EnableTextInput(mDecorator, mInputMethodContext);
488 // Enables the horizontal scrolling after the text input has been enabled.
489 mController->SetHorizontalScrollEnabled(true);
491 // Disables the vertical scrolling.
492 mController->SetVerticalScrollEnabled(false);
494 // Disable the smooth handle panning.
495 mController->SetSmoothHandlePanEnabled(false);
497 mController->SetNoTextDoubleTapAction(Controller::NoTextTap::HIGHLIGHT);
498 mController->SetNoTextLongPressAction(Controller::NoTextTap::HIGHLIGHT);
500 // Sets layoutDirection value
501 Dali::Stage stage = Dali::Stage::GetCurrent();
502 Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(stage.GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
503 mController->SetLayoutDirection(layoutDirection);
505 self.LayoutDirectionChangedSignal().Connect(this, &TextField::OnLayoutDirectionChanged);
507 // Forward input events to controller
508 EnableGestureDetection(static_cast<GestureType::Value>(GestureType::TAP | GestureType::PAN | GestureType::LONG_PRESS));
509 GetTapGestureDetector().SetMaximumTapsRequired(2);
510 GetTapGestureDetector().ReceiveAllTapEvents(true);
512 self.TouchedSignal().Connect(this, &TextField::OnTouched);
514 // Set BoundingBox to stage size if not already set.
515 Rect<int> boundingBox;
516 mDecorator->GetBoundingBox(boundingBox);
518 if(boundingBox.IsEmpty())
520 Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
521 mDecorator->SetBoundingBox(Rect<int>(0.0f, 0.0f, stageSize.width, stageSize.height));
524 // Flip vertically the 'left' selection handle
525 mDecorator->FlipHandleVertically(LEFT_SELECTION_HANDLE, true);
527 // Fill-parent area by default
528 self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
529 self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT);
530 self.OnSceneSignal().Connect(this, &TextField::OnSceneConnect);
532 DevelControl::SetInputMethodContext(*this, mInputMethodContext);
534 if(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy)
540 self.SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::ENTRY);
541 self.SetProperty(DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
543 Accessibility::Bridge::EnabledSignal().Connect(this, &TextField::OnAccessibilityStatusChanged);
544 Accessibility::Bridge::DisabledSignal().Connect(this, &TextField::OnAccessibilityStatusChanged);
547 DevelControl::ControlAccessible* TextField::CreateAccessibleObject()
549 return new TextFieldAccessible(Self());
552 void TextField::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
554 DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnStyleChange\n");
558 case StyleChange::DEFAULT_FONT_CHANGE:
560 DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnStyleChange DEFAULT_FONT_CHANGE\n");
561 const std::string& newFont = GetImpl(styleManager).GetDefaultFontFamily();
562 // Property system did not set the font so should update it.
563 mController->UpdateAfterFontChange(newFont);
568 case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
570 GetImpl(styleManager).ApplyThemeStyle(Toolkit::Control(GetOwner()));
574 case StyleChange::THEME_CHANGE:
576 // Nothing to do, let control base class handle this
581 // Up call to Control
582 Control::OnStyleChange(styleManager, change);
585 Vector3 TextField::GetNaturalSize()
588 padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
590 Vector3 naturalSize = mController->GetNaturalSize();
591 naturalSize.width += (padding.start + padding.end);
592 naturalSize.height += (padding.top + padding.bottom);
597 float TextField::GetHeightForWidth(float width)
600 padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
601 return mController->GetHeightForWidth(width) + padding.top + padding.bottom;
604 void TextField::ResizeActor(Actor& actor, const Vector2& size)
606 if(actor.GetProperty<Vector3>(Dali::Actor::Property::SIZE).GetVectorXY() != size)
608 actor.SetProperty(Actor::Property::SIZE, size);
612 void TextField::OnPropertySet(Property::Index index, const Property::Value& propertyValue)
614 DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnPropertySet index[%d]\n", index);
618 case DevelActor::Property::USER_INTERACTION_ENABLED:
620 const bool enabled = propertyValue.Get<bool>();
621 mController->SetUserInteractionEnabled(enabled);
624 float opacity = enabled ? 1.0f : mController->GetDisabledColorOpacity();
625 mStencil.SetProperty(Actor::Property::OPACITY, opacity);
631 Control::OnPropertySet(index, propertyValue); // up call to control for non-handled properties
637 void TextField::OnRelayout(const Vector2& size, RelayoutContainer& container)
639 DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField OnRelayout\n");
644 padding = self.GetProperty<Extents>(Toolkit::Control::Property::PADDING);
646 Vector2 contentSize(size.x - (padding.start + padding.end), size.y - (padding.top + padding.bottom));
648 // Support Right-To-Left of padding
649 Dali::LayoutDirection::Type layoutDirection = mController->GetLayoutDirection(self);
651 if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
653 std::swap(padding.start, padding.end);
658 mStencil.SetProperty(Actor::Property::POSITION, Vector2(padding.start, padding.top));
659 ResizeActor(mStencil, contentSize);
663 mActiveLayer.SetProperty(Actor::Property::POSITION, Vector2(padding.start, padding.top));
664 ResizeActor(mActiveLayer, contentSize);
668 mCursorLayer.SetProperty(Actor::Property::POSITION, Vector2(padding.start, padding.top));
669 ResizeActor(mCursorLayer, contentSize);
672 // If there is text changed, callback is called.
675 EmitTextChangedSignal();
678 const Text::Controller::UpdateTextType updateTextType = mController->Relayout(contentSize, layoutDirection);
680 if((Text::Controller::NONE_UPDATED != updateTextType) ||
683 DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnRelayout %p Displaying new contents\n", mController.Get());
686 (Text::Controller::NONE_UPDATED != (Text::Controller::DECORATOR_UPDATED & updateTextType)))
688 mDecorator->Relayout(contentSize);
693 mRenderer = Backend::Get().NewRenderer(mRenderingBackend);
696 RenderText(updateTextType);
699 if(mCursorPositionChanged)
701 EmitCursorPositionChangedSignal();
704 if(mSelectionStarted)
706 EmitSelectionStartedSignal();
709 if(mSelectionChanged)
711 EmitSelectionChangedSignal();
714 if(mSelectionCleared)
716 EmitSelectionClearedSignal();
719 // The text-field emits signals when the input style changes. These changes of style are
720 // detected during the relayout process (size negotiation), i.e after the cursor has been moved. Signals
721 // can't be emitted during the size negotiation as the callbacks may update the UI.
722 // The text-field adds an idle callback to the adaptor to emit the signals after the size negotiation.
723 if(!mController->IsInputStyleChangedSignalsQueueEmpty())
725 if(Adaptor::IsAvailable())
727 Adaptor& adaptor = Adaptor::Get();
729 if(NULL == mIdleCallback)
731 // @note: The callback manager takes the ownership of the callback object.
732 mIdleCallback = MakeCallback(this, &TextField::OnIdleSignal);
733 adaptor.AddIdle(mIdleCallback, false);
739 Text::ControllerPtr TextField::GetTextController()
744 void TextField::RenderText(Text::Controller::UpdateTextType updateTextType)
746 CommonTextUtils::RenderText(Self(), mRenderer, mController, mDecorator, mAlignmentOffset, mRenderableActor, mBackgroundActor, mCursorLayer, mStencil, mClippingDecorationActors, mAnchorActors, updateTextType);
749 void TextField::OnKeyInputFocusGained()
751 DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnKeyInputFocusGained %p\n", mController.Get());
752 if(mInputMethodContext && IsEditable())
754 // All input panel properties, such as layout, return key type, and input hint, should be set before input panel activates (or shows).
755 mInputMethodContext.ApplyOptions(mInputMethodOptions);
756 mInputMethodContext.NotifyTextInputMultiLine(false);
758 mInputMethodContext.StatusChangedSignal().Connect(this, &TextField::KeyboardStatusChanged);
760 mInputMethodContext.EventReceivedSignal().Connect(this, &TextField::OnInputMethodContextEvent);
762 // Notify that the text editing start.
763 mInputMethodContext.Activate();
765 // When window gain lost focus, the inputMethodContext is deactivated. Thus when window gain focus again, the inputMethodContext must be activated.
766 mInputMethodContext.SetRestoreAfterFocusLost(true);
768 ClipboardEventNotifier notifier(ClipboardEventNotifier::Get());
772 notifier.ContentSelectedSignal().Connect(this, &TextField::OnClipboardTextSelected);
775 if(IsEditable() && mController->IsUserInteractionEnabled())
777 mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event
780 EmitKeyInputFocusSignal(true); // Calls back into the Control hence done last.
783 void TextField::OnKeyInputFocusLost()
785 DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField:OnKeyInputFocusLost %p\n", mController.Get());
786 if(mInputMethodContext)
788 mInputMethodContext.StatusChangedSignal().Disconnect(this, &TextField::KeyboardStatusChanged);
789 // The text editing is finished. Therefore the inputMethodContext don't have restore activation.
790 mInputMethodContext.SetRestoreAfterFocusLost(false);
792 // Notify that the text editing finish.
793 mInputMethodContext.Deactivate();
795 mInputMethodContext.EventReceivedSignal().Disconnect(this, &TextField::OnInputMethodContextEvent);
797 ClipboardEventNotifier notifier(ClipboardEventNotifier::Get());
801 notifier.ContentSelectedSignal().Disconnect(this, &TextField::OnClipboardTextSelected);
804 mController->KeyboardFocusLostEvent();
806 EmitKeyInputFocusSignal(false); // Calls back into the Control hence done last.
809 bool TextField::OnAccessibilityActivated()
815 void TextField::OnTap(const TapGesture& gesture)
817 DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnTap %p\n", mController.Get());
818 if(mInputMethodContext && IsEditable())
820 mInputMethodContext.Activate();
822 // Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures
824 padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
825 const Vector2& localPoint = gesture.GetLocalPoint();
826 mController->TapEvent(gesture.GetNumberOfTaps(), localPoint.x - padding.start, localPoint.y - padding.top);
827 mController->AnchorEvent(localPoint.x - padding.start, localPoint.y - padding.top);
829 Dali::Toolkit::KeyboardFocusManager keyboardFocusManager = Dali::Toolkit::KeyboardFocusManager::Get();
830 if (keyboardFocusManager)
832 keyboardFocusManager.SetCurrentFocusActor(Self());
837 void TextField::OnPan(const PanGesture& gesture)
839 mController->PanEvent(gesture.GetState(), gesture.GetDisplacement());
840 if(gesture.GetState() == GestureState::STARTED && !mController->IsScrollable(gesture.GetDisplacement()))
842 Dali::DevelActor::SetNeedGesturePropagation(Self(), true);
846 void TextField::OnLongPress(const LongPressGesture& gesture)
848 if(mInputMethodContext && IsEditable())
850 mInputMethodContext.Activate();
853 padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
854 const Vector2& localPoint = gesture.GetLocalPoint();
855 mController->LongPressEvent(gesture.GetState(), localPoint.x - padding.start, localPoint.y - padding.top);
860 bool TextField::OnKeyEvent(const KeyEvent& event)
862 DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.GetKeyCode());
864 if(Dali::DALI_KEY_ESCAPE == event.GetKeyCode() && mController->ShouldClearFocusOnEscape())
866 // Make sure ClearKeyInputFocus when only key is up
867 if(event.GetState() == KeyEvent::UP)
869 Dali::Toolkit::KeyboardFocusManager keyboardFocusManager = Dali::Toolkit::KeyboardFocusManager::Get();
870 if (keyboardFocusManager)
872 keyboardFocusManager.ClearFocus();
874 ClearKeyInputFocus();
879 else if(Dali::DevelKey::DALI_KEY_RETURN == event.GetKeyCode())
881 // Do nothing when enter is comming.
885 return mController->KeyEvent(event);
888 void TextField::RequestTextRelayout()
893 bool TextField::IsEditable() const
895 return mController->IsEditable();
898 void TextField::SetEditable(bool editable)
900 mController->SetEditable(editable);
901 if(mInputMethodContext && !editable)
903 mInputMethodContext.Deactivate();
907 void TextField::TextInserted(unsigned int position, unsigned int length, const std::string& content)
909 GetAccessibleObject()->EmitTextInserted(position, length, content);
912 void TextField::TextDeleted(unsigned int position, unsigned int length, const std::string& content)
914 GetAccessibleObject()->EmitTextDeleted(position, length, content);
917 void TextField::CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition)
919 GetAccessibleObject()->EmitTextCursorMoved(newPosition);
921 if((oldPosition != newPosition) && !mCursorPositionChanged)
923 mCursorPositionChanged = true;
924 mOldPosition = oldPosition;
928 void TextField::TextChanged(bool immediate)
930 if(immediate) // Emits TextChangedSignal immediately
932 EmitTextChangedSignal();
940 void TextField::EmitTextChangedSignal()
942 Dali::Toolkit::TextField handle(GetOwner());
943 mTextChangedSignal.Emit(handle);
944 mTextChanged = false;
947 void TextField::MaxLengthReached()
949 Dali::Toolkit::TextField handle(GetOwner());
950 mMaxLengthReachedSignal.Emit(handle);
953 void TextField::InputStyleChanged(Text::InputStyle::Mask inputStyleMask)
955 Dali::Toolkit::TextField handle(GetOwner());
956 mInputStyleChangedSignal.Emit(handle, ConvertInputStyle(inputStyleMask));
959 void TextField::AnchorClicked(const std::string& href)
961 Dali::Toolkit::TextField handle(GetOwner());
962 mAnchorClickedSignal.Emit(handle, href.c_str(), href.length());
965 void TextField::EmitCursorPositionChangedSignal()
967 Dali::Toolkit::TextField handle(GetOwner());
968 mCursorPositionChangedSignal.Emit(handle, mOldPosition);
969 mCursorPositionChanged = false;
972 void TextField::InputFiltered(Toolkit::InputFilter::Property::Type type)
974 Dali::Toolkit::TextField handle(GetOwner());
975 mInputFilteredSignal.Emit(handle, type);
978 void TextField::EmitSelectionChangedSignal()
980 Dali::Toolkit::TextField handle(GetOwner());
981 mSelectionChangedSignal.Emit(handle, mOldSelectionStart, mOldSelectionEnd);
982 mSelectionChanged = false;
985 void TextField::EmitSelectionClearedSignal()
987 Dali::Toolkit::TextField handle(GetOwner());
988 mSelectionClearedSignal.Emit(handle);
989 mSelectionCleared = false;
992 void TextField::EmitSelectionStartedSignal()
994 Dali::Toolkit::TextField handle(GetOwner());
995 mSelectionStartedSignal.Emit(handle);
996 mSelectionStarted = false;
999 void TextField::SelectionChanged(uint32_t oldStart, uint32_t oldEnd, uint32_t newStart, uint32_t newEnd)
1001 if(((oldStart != newStart) || (oldEnd != newEnd)) && !mSelectionChanged)
1003 if(newStart == newEnd)
1005 mSelectionCleared = true;
1009 if(oldStart == oldEnd)
1011 mSelectionStarted = true;
1015 mSelectionChanged = true;
1016 mOldSelectionStart = oldStart;
1017 mOldSelectionEnd = oldEnd;
1019 if(mOldSelectionStart > mOldSelectionEnd)
1022 uint32_t temp = mOldSelectionStart;
1023 mOldSelectionStart = mOldSelectionEnd;
1024 mOldSelectionEnd = temp;
1029 void TextField::AddDecoration(Actor& actor, DecorationType type, bool needsClipping)
1035 mClippingDecorationActors.push_back(actor);
1038 // If the actor is a layer type, add it.
1039 if(type == DecorationType::ACTIVE_LAYER)
1041 AddLayer(mActiveLayer, actor);
1043 else if(type == DecorationType::CURSOR_LAYER)
1045 AddLayer(mCursorLayer, actor);
1050 void TextField::AddLayer(Actor& layer, Actor& actor)
1052 actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
1053 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1058 void TextField::GetControlBackgroundColor(Vector4& color) const
1060 Property::Value propValue = Self().GetProperty(Toolkit::Control::Property::BACKGROUND);
1061 Property::Map* resultMap = propValue.GetMap();
1063 Property::Value* colorValue = nullptr;
1064 if(resultMap && (colorValue = resultMap->Find(ColorVisual::Property::MIX_COLOR)))
1066 colorValue->Get(color);
1070 void TextField::OnSceneConnect(Dali::Actor actor)
1074 RenderText(static_cast<Text::Controller::UpdateTextType>(Text::Controller::MODEL_UPDATED | Text::Controller::DECORATOR_UPDATED));
1078 mHasBeenStaged = true;
1082 InputMethodContext::CallbackData TextField::OnInputMethodContextEvent(Dali::InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
1084 DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::OnInputMethodContextEvent %p eventName %d\n", mController.Get(), inputMethodContextEvent.eventName);
1085 return mController->OnInputMethodContextEvent(inputMethodContext, inputMethodContextEvent);
1088 void TextField::GetHandleImagePropertyValue(Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType)
1093 map[PropertyHandler::IMAGE_MAP_FILENAME_STRING] = mDecorator->GetHandleImage(handleType, handleImageType);
1099 void TextField::EnableClipping()
1103 // Creates an extra control to be used as stencil buffer.
1104 mStencil = Control::New();
1105 mStencil.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1106 mStencil.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
1108 // Creates a background visual. Even if the color is transparent it updates the stencil.
1109 mStencil.SetProperty(Toolkit::Control::Property::BACKGROUND,
1110 Property::Map().Add(Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR).Add(ColorVisual::Property::MIX_COLOR, Color::TRANSPARENT));
1112 // Enable the clipping property.
1113 mStencil.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX);
1114 mStencil.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
1116 Self().Add(mStencil);
1120 void TextField::OnClipboardTextSelected(ClipboardEventNotifier& clipboard)
1122 mController->PasteClipboardItemEvent();
1125 void TextField::KeyboardStatusChanged(bool keyboardShown)
1127 DALI_LOG_INFO(gTextFieldLogFilter, Debug::Verbose, "TextField::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown);
1129 // Just hide the grab handle when keyboard is hidden.
1132 mController->KeyboardFocusLostEvent();
1136 mController->KeyboardFocusGainEvent(); // Initially called by OnKeyInputFocusGained
1140 void TextField::OnSceneConnection(int depth)
1142 // Sets the depth to the visuals inside the text's decorator.
1143 mDecorator->SetTextDepth(depth);
1145 // The depth of the text renderer is set in the RenderText() called from OnRelayout().
1147 // Call the Control::OnSceneConnection() to set the depth of the background.
1148 Control::OnSceneConnection(depth);
1151 bool TextField::OnTouched(Actor actor, const TouchEvent& touch)
1156 void TextField::OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type)
1158 mController->ChangedLayoutDirection();
1161 void TextField::OnIdleSignal()
1163 // Emits the change of input style signals.
1164 mController->ProcessInputStyleChangedSignals();
1166 // Set the pointer to null as the callback manager deletes the callback after execute it.
1167 mIdleCallback = NULL;
1170 TextField::TextField()
1171 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
1172 mIdleCallback(NULL),
1173 mAlignmentOffset(0.f),
1174 mRenderingBackend(DEFAULT_RENDERING_BACKEND),
1175 mExceedPolicy(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP),
1176 mHasBeenStaged(false),
1177 mTextChanged(false),
1178 mCursorPositionChanged(false),
1179 mSelectionChanged(false),
1180 mSelectionCleared(false),
1182 mOldSelectionStart(0u),
1183 mOldSelectionEnd(0u),
1184 mSelectionStarted(false)
1188 TextField::~TextField()
1190 UnparentAndReset(mStencil);
1192 if((NULL != mIdleCallback) && Adaptor::IsAvailable())
1194 Adaptor::Get().RemoveIdle(mIdleCallback);
1198 Vector<Vector2> TextField::GetTextSize(const uint32_t startIndex, const uint32_t endIndex) const
1200 return mController->GetTextSize(startIndex, endIndex);
1203 Vector<Vector2> TextField::GetTextPosition(const uint32_t startIndex, const uint32_t endIndex) const
1205 return mController->GetTextPosition(startIndex, endIndex);
1208 std::string TextField::TextFieldAccessible::GetName() const
1215 return GetWholeText();
1218 const std::vector<Toolkit::TextAnchor>& TextField::TextFieldAccessible::GetTextAnchors() const
1220 auto self = Toolkit::TextField::DownCast(Self());
1222 return Toolkit::GetImpl(self).mAnchorActors;
1225 Toolkit::Text::ControllerPtr TextField::TextFieldAccessible::GetTextController() const
1227 auto self = Toolkit::TextField::DownCast(Self());
1229 return Toolkit::GetImpl(self).GetTextController();
1232 std::uint32_t TextField::TextFieldAccessible::GetSubstituteCharacter() const
1234 auto self = Toolkit::TextField::DownCast(Self());
1235 auto hiddenInputSettings = self.GetProperty<Property::Map>(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS);
1236 auto substChar = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::SUBSTITUTE_CHARACTER);
1240 return static_cast<std::uint32_t>(substChar->Get<int>());
1243 return TextControlAccessible::GetSubstituteCharacter();
1246 bool TextField::TextFieldAccessible::IsHiddenInput() const
1248 auto self = Toolkit::TextField::DownCast(Self());
1249 auto hiddenInputSettings = self.GetProperty<Property::Map>(Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS);
1250 auto mode = hiddenInputSettings.Find(Toolkit::HiddenInput::Property::MODE);
1252 return (mode && (mode->Get<int>() != Toolkit::HiddenInput::Mode::HIDE_NONE));
1255 void TextField::TextFieldAccessible::RequestTextRelayout()
1257 auto self = Toolkit::TextField::DownCast(Self());
1258 auto& selfImpl = Toolkit::GetImpl(self);
1260 selfImpl.RequestTextRelayout();
1263 } // namespace Internal
1265 } // namespace Toolkit