[ATSPI] Implementation of Hypertext and Hyperlink in text controls
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-editor-property-handler.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <dali-toolkit/internal/controls/text-controls/text-editor-property-handler.h>
18 #include <dali-toolkit/internal/controls/text-controls/common-text-utils.h>
19
20 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
21
22 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
23 #include <dali-toolkit/internal/text/text-controller.h>
24 #include <dali-toolkit/internal/text/text-effects-style.h>
25 #include <dali-toolkit/internal/text/text-enumerations-impl.h>
26 #include <dali-toolkit/internal/text/text-font-style.h>
27 #include <dali-toolkit/public-api/text/text-enumerations.h>
28 #include <dali/integration-api/debug.h>
29
30 #if defined(DEBUG_ENABLED)
31 extern Debug::Filter* gTextEditorLogFilter;
32 #endif
33
34 namespace Dali::Toolkit::Internal
35 {
36 const char* const TextEditor::PropertyHandler::IMAGE_MAP_FILENAME_STRING{"filename"};
37
38 /// Retrieves a filename from a value that is a Property::Map
39 std::string TextEditor::PropertyHandler::GetImageFileNameFromPropertyValue(const Property::Value& value)
40 {
41   std::string          filename;
42   const Property::Map* map = value.GetMap();
43   if(map)
44   {
45     const Property::Value* filenameValue = map->Find(TextEditor::PropertyHandler::IMAGE_MAP_FILENAME_STRING);
46     if(filenameValue)
47     {
48       filenameValue->Get(filename);
49     }
50   }
51   return filename;
52 }
53
54 void TextEditor::PropertyHandler::SetProperty(Toolkit::TextEditor textEditor, Property::Index index, const Property::Value& value)
55 {
56   TextEditor& impl(GetImpl(textEditor));
57   DALI_ASSERT_DEBUG(impl.mController && "No text controller");
58   DALI_ASSERT_DEBUG(impl.mDecorator && "No text decorator");
59
60   switch(index)
61   {
62     case Toolkit::DevelTextEditor::Property::RENDERING_BACKEND:
63     {
64       int backend = value.Get<int>();
65       DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend);
66
67       if(impl.mRenderingBackend != backend)
68       {
69         impl.mRenderingBackend = backend;
70         impl.mRenderer.Reset();
71         impl.RequestTextRelayout();
72       }
73       break;
74     }
75     case Toolkit::TextEditor::Property::TEXT:
76     {
77       const std::string& text = value.Get<std::string>();
78       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p TEXT %s\n", impl.mController.Get(), text.c_str());
79
80       impl.mController->SetText(text);
81       break;
82     }
83     case Toolkit::TextEditor::Property::TEXT_COLOR:
84     {
85       const Vector4& textColor = value.Get<Vector4>();
86       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a);
87
88       if(impl.mController->GetDefaultColor() != textColor)
89       {
90         impl.mController->SetDefaultColor(textColor);
91         impl.mController->SetInputColor(textColor);
92         impl.mRenderer.Reset();
93       }
94       break;
95     }
96     case Toolkit::TextEditor::Property::FONT_FAMILY:
97     {
98       const std::string& fontFamily = value.Get<std::string>();
99       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str());
100       impl.mController->SetDefaultFontFamily(fontFamily);
101       break;
102     }
103     case Toolkit::TextEditor::Property::FONT_STYLE:
104     {
105       SetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT);
106       break;
107     }
108     case Toolkit::TextEditor::Property::POINT_SIZE:
109     {
110       const float pointSize = value.Get<float>();
111       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p POINT_SIZE %f\n", impl.mController.Get(), pointSize);
112
113       if(!Equals(impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE), pointSize))
114       {
115         impl.mController->SetDefaultFontSize(pointSize, Text::Controller::POINT_SIZE);
116       }
117       break;
118     }
119     case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
120     {
121       Text::HorizontalAlignment::Type alignment(static_cast<Text::HorizontalAlignment::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
122       if(Text::GetHorizontalAlignmentEnumeration(value, alignment))
123       {
124         DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p HORIZONTAL_ALIGNMENT %d\n", impl.mController.Get(), alignment);
125         impl.mController->SetHorizontalAlignment(alignment);
126       }
127       break;
128     }
129     case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
130     {
131       const float threshold = value.Get<float>();
132       DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold);
133
134       impl.mDecorator->SetScrollThreshold(threshold);
135       break;
136     }
137     case Toolkit::TextEditor::Property::SCROLL_SPEED:
138     {
139       const float speed = value.Get<float>();
140       DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p SCROLL_SPEED %f\n", impl.mController.Get(), speed);
141
142       impl.mDecorator->SetScrollSpeed(speed);
143       break;
144     }
145     case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
146     {
147       const Vector4& color = value.Get<Vector4>();
148       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
149
150       impl.mDecorator->SetCursorColor(Toolkit::Text::PRIMARY_CURSOR, color);
151       impl.RequestTextRelayout();
152       break;
153     }
154     case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
155     {
156       const Vector4& color = value.Get<Vector4>();
157       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
158
159       impl.mDecorator->SetCursorColor(Toolkit::Text::SECONDARY_CURSOR, color);
160       impl.RequestTextRelayout();
161       break;
162     }
163     case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
164     {
165       const bool enable = value.Get<bool>();
166       DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable);
167
168       impl.mController->SetEnableCursorBlink(enable);
169       impl.RequestTextRelayout();
170       break;
171     }
172     case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
173     {
174       const float interval = value.Get<float>();
175       DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval);
176
177       impl.mDecorator->SetCursorBlinkInterval(interval);
178       break;
179     }
180     case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
181     {
182       const float duration = value.Get<float>();
183       DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration);
184
185       impl.mDecorator->SetCursorBlinkDuration(duration);
186       break;
187     }
188     case Toolkit::TextEditor::Property::CURSOR_WIDTH:
189     {
190       const int width = value.Get<int>();
191       DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p CURSOR_WIDTH %d\n", impl.mController.Get(), width);
192
193       impl.mDecorator->SetCursorWidth(width);
194       impl.mController->GetLayoutEngine().SetCursorWidth(width);
195       break;
196     }
197     case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
198     {
199       const std::string imageFileName = value.Get<std::string>();
200       DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str());
201
202       if(imageFileName.size())
203       {
204         impl.mDecorator->SetHandleImage(Toolkit::Text::GRAB_HANDLE, Toolkit::Text::HANDLE_IMAGE_RELEASED, imageFileName);
205         impl.RequestTextRelayout();
206       }
207       break;
208     }
209     case Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE:
210     {
211       const std::string imageFileName = value.Get<std::string>();
212       DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str());
213
214       if(imageFileName.size())
215       {
216         impl.mDecorator->SetHandleImage(Toolkit::Text::GRAB_HANDLE, Toolkit::Text::HANDLE_IMAGE_PRESSED, imageFileName);
217         impl.RequestTextRelayout();
218       }
219       break;
220     }
221     case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
222     {
223       const std::string filename = GetImageFileNameFromPropertyValue(value);
224
225       if(filename.size())
226       {
227         impl.mDecorator->SetHandleImage(Toolkit::Text::LEFT_SELECTION_HANDLE, Toolkit::Text::HANDLE_IMAGE_RELEASED, filename);
228         impl.RequestTextRelayout();
229       }
230       break;
231     }
232     case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT:
233     {
234       const std::string filename = GetImageFileNameFromPropertyValue(value);
235
236       if(filename.size())
237       {
238         impl.mDecorator->SetHandleImage(Toolkit::Text::RIGHT_SELECTION_HANDLE, Toolkit::Text::HANDLE_IMAGE_RELEASED, filename);
239         impl.RequestTextRelayout();
240       }
241       break;
242     }
243     case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
244     {
245       const std::string filename = GetImageFileNameFromPropertyValue(value);
246
247       if(filename.size())
248       {
249         impl.mDecorator->SetHandleImage(Toolkit::Text::LEFT_SELECTION_HANDLE, Toolkit::Text::HANDLE_IMAGE_PRESSED, filename);
250         impl.RequestTextRelayout();
251       }
252       break;
253     }
254     case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
255     {
256       const std::string filename = GetImageFileNameFromPropertyValue(value);
257
258       if(filename.size())
259       {
260         impl.mDecorator->SetHandleImage(Toolkit::Text::RIGHT_SELECTION_HANDLE, Toolkit::Text::HANDLE_IMAGE_PRESSED, filename);
261         impl.RequestTextRelayout();
262       }
263       break;
264     }
265     case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
266     {
267       const std::string filename = GetImageFileNameFromPropertyValue(value);
268
269       if(filename.size())
270       {
271         impl.mDecorator->SetHandleImage(Toolkit::Text::LEFT_SELECTION_HANDLE_MARKER,
272                                         Toolkit::Text::HANDLE_IMAGE_RELEASED,
273                                         filename);
274         impl.RequestTextRelayout();
275       }
276       break;
277     }
278     case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
279     {
280       const std::string filename = GetImageFileNameFromPropertyValue(value);
281
282       if(filename.size())
283       {
284         impl.mDecorator->SetHandleImage(Toolkit::Text::RIGHT_SELECTION_HANDLE_MARKER,
285                                         Toolkit::Text::HANDLE_IMAGE_RELEASED,
286                                         filename);
287         impl.RequestTextRelayout();
288       }
289       break;
290     }
291     case Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR:
292     {
293       const Vector4 color = value.Get<Vector4>();
294       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p SELECTION_HIGHLIGHT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
295
296       impl.mDecorator->SetHighlightColor(color);
297       impl.RequestTextRelayout();
298       break;
299     }
300     case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
301     {
302       const Rect<int>& box = value.Get<Rect<int> >();
303       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height);
304
305       impl.mDecorator->SetBoundingBox(box);
306       impl.RequestTextRelayout();
307       break;
308     }
309     case Toolkit::TextEditor::Property::ENABLE_MARKUP:
310     {
311       const bool enableMarkup = value.Get<bool>();
312       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup);
313
314       impl.mController->SetMarkupProcessorEnabled(enableMarkup);
315       CommonTextUtils::SynchronizeTextAnchorsInParent(textEditor, impl.mController, impl.mAnchorActors);
316       break;
317     }
318     case Toolkit::TextEditor::Property::INPUT_COLOR:
319     {
320       const Vector4& inputColor = value.Get<Vector4>();
321       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p INPUT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), inputColor.r, inputColor.g, inputColor.b, inputColor.a);
322
323       impl.mController->SetInputColor(inputColor);
324       break;
325     }
326     case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
327     {
328       const std::string& fontFamily = value.Get<std::string>();
329       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str());
330       impl.mController->SetInputFontFamily(fontFamily);
331       break;
332     }
333     case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
334     {
335       SetFontStyleProperty(impl.mController, value, Text::FontStyle::INPUT);
336       break;
337     }
338     case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
339     {
340       const float pointSize = value.Get<float>();
341       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize);
342       impl.mController->SetInputFontPointSize(pointSize);
343       break;
344     }
345     case Toolkit::TextEditor::Property::LINE_SPACING:
346     {
347       const float lineSpacing = value.Get<float>();
348       impl.mController->SetDefaultLineSpacing(lineSpacing);
349       impl.mRenderer.Reset();
350       break;
351     }
352     case Toolkit::TextEditor::Property::INPUT_LINE_SPACING:
353     {
354       const float lineSpacing = value.Get<float>();
355       impl.mController->SetInputLineSpacing(lineSpacing);
356       impl.mRenderer.Reset();
357       break;
358     }
359     case Toolkit::TextEditor::Property::UNDERLINE:
360     {
361       const bool update = SetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
362       if(update)
363       {
364         impl.mRenderer.Reset();
365       }
366       break;
367     }
368     case Toolkit::TextEditor::Property::INPUT_UNDERLINE:
369     {
370       const bool update = SetUnderlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
371       if(update)
372       {
373         impl.mRenderer.Reset();
374       }
375       break;
376     }
377     case Toolkit::TextEditor::Property::SHADOW:
378     {
379       const bool update = SetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
380       if(update)
381       {
382         impl.mRenderer.Reset();
383       }
384       break;
385     }
386     case Toolkit::TextEditor::Property::INPUT_SHADOW:
387     {
388       const bool update = SetShadowProperties(impl.mController, value, Text::EffectStyle::INPUT);
389       if(update)
390       {
391         impl.mRenderer.Reset();
392       }
393       break;
394     }
395     case Toolkit::TextEditor::Property::EMBOSS:
396     {
397       const bool update = SetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
398       if(update)
399       {
400         impl.mRenderer.Reset();
401       }
402       break;
403     }
404     case Toolkit::TextEditor::Property::INPUT_EMBOSS:
405     {
406       const bool update = SetEmbossProperties(impl.mController, value, Text::EffectStyle::INPUT);
407       if(update)
408       {
409         impl.mRenderer.Reset();
410       }
411       break;
412     }
413     case Toolkit::TextEditor::Property::OUTLINE:
414     {
415       const bool update = SetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
416       if(update)
417       {
418         impl.mRenderer.Reset();
419       }
420       break;
421     }
422     case Toolkit::TextEditor::Property::INPUT_OUTLINE:
423     {
424       const bool update = SetOutlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
425       if(update)
426       {
427         impl.mRenderer.Reset();
428       }
429       break;
430     }
431     case Toolkit::TextEditor::Property::SMOOTH_SCROLL:
432     {
433       const bool enable = value.Get<bool>();
434       DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor SMOOTH_SCROLL %d\n", enable);
435
436       impl.mScrollAnimationEnabled = enable;
437       break;
438     }
439     case Toolkit::TextEditor::Property::SMOOTH_SCROLL_DURATION:
440     {
441       const float duration = value.Get<float>();
442       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor SMOOTH_SCROLL_DURATION %f\n", duration);
443
444       impl.mScrollAnimationDuration = duration;
445       if(impl.mTextVerticalScroller)
446       {
447         impl.mTextVerticalScroller->SetDuration(duration);
448       }
449       break;
450     }
451     case Toolkit::TextEditor::Property::ENABLE_SCROLL_BAR:
452     {
453       const bool enable = value.Get<bool>();
454       DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor SHOW_SCROLL_BAR %d\n", enable);
455
456       impl.mScrollBarEnabled = enable;
457       break;
458     }
459     case Toolkit::TextEditor::Property::SCROLL_BAR_SHOW_DURATION:
460     {
461       const float duration = value.Get<float>();
462       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor SCROLL_BAR_SHOW_DURATION %f\n", duration);
463
464       impl.mAnimationPeriod.delaySeconds = duration;
465       break;
466     }
467     case Toolkit::TextEditor::Property::SCROLL_BAR_FADE_DURATION:
468     {
469       const float duration = value.Get<float>();
470       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor SCROLL_BAR_FADE_DURATION %f\n", duration);
471
472       impl.mAnimationPeriod.durationSeconds = duration;
473       break;
474     }
475     case Toolkit::TextEditor::Property::PIXEL_SIZE:
476     {
477       const float pixelSize = value.Get<float>();
478       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize);
479
480       if(!Equals(impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE), pixelSize))
481       {
482         impl.mController->SetDefaultFontSize(pixelSize, Text::Controller::PIXEL_SIZE);
483       }
484       break;
485     }
486     case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT:
487     {
488       const std::string& text = value.Get<std::string>();
489       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor::OnPropertySet %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str());
490
491       impl.mController->SetPlaceholderText(Text::Controller::PLACEHOLDER_TYPE_INACTIVE, text);
492       break;
493     }
494     case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR:
495     {
496       const Vector4& textColor = value.Get<Vector4>();
497       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p PLACEHOLDER_TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a);
498
499       if(impl.mController->GetPlaceholderTextColor() != textColor)
500       {
501         impl.mController->SetPlaceholderTextColor(textColor);
502         impl.mRenderer.Reset();
503       }
504       break;
505     }
506     case Toolkit::TextEditor::Property::ENABLE_SELECTION:
507     {
508       const bool enableSelection = value.Get<bool>();
509       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p ENABLE_SELECTION %d\n", impl.mController.Get(), enableSelection);
510       impl.mController->SetSelectionEnabled(enableSelection);
511       break;
512     }
513     case Toolkit::TextEditor::Property::PLACEHOLDER:
514     {
515       const Property::Map* map = value.GetMap();
516       if(map)
517       {
518         impl.mController->SetPlaceholderProperty(*map);
519       }
520       break;
521     }
522     case Toolkit::TextEditor::Property::LINE_WRAP_MODE:
523     {
524       Text::LineWrap::Mode lineWrapMode(static_cast<Text::LineWrap::Mode>(-1)); // Set to invalid value to ensure a valid mode does get set
525       if(Toolkit::Text::GetLineWrapModeEnumeration(value, lineWrapMode))
526       {
527         DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p LineWrap::MODE %d\n", impl.mController.Get(), lineWrapMode);
528         impl.mController->SetLineWrapMode(lineWrapMode);
529       }
530       break;
531     }
532     case Toolkit::DevelTextEditor::Property::ENABLE_SHIFT_SELECTION:
533     {
534       const bool shiftSelection = value.Get<bool>();
535       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p ENABLE_SHIFT_SELECTION %d\n", impl.mController.Get(), shiftSelection);
536
537       impl.mController->SetShiftSelectionEnabled(shiftSelection);
538       break;
539     }
540     case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE:
541     {
542       const bool grabHandleEnabled = value.Get<bool>();
543       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p ENABLE_GRAB_HANDLE %d\n", impl.mController.Get(), grabHandleEnabled);
544
545       impl.mController->SetGrabHandleEnabled(grabHandleEnabled);
546       break;
547     }
548     case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
549     {
550       impl.mController->SetMatchLayoutDirection(value.Get<bool>() ? DevelText::MatchLayoutDirection::LOCALE : DevelText::MatchLayoutDirection::CONTENTS);
551       break;
552     }
553     case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
554     {
555       const int max = value.Get<int>();
556       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p MAX_LENGTH %d\n", impl.mController.Get(), max);
557
558       impl.mController->SetMaximumNumberOfCharacters(max);
559       break;
560     }
561     case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_START:
562     {
563       uint32_t start = static_cast<uint32_t>(value.Get<int>());
564       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p SELECTED_TEXT_START %d\n", impl.mController.Get(), start);
565       impl.SetTextSelectionRange(&start, nullptr);
566       break;
567     }
568     case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_END:
569     {
570       uint32_t end = static_cast<uint32_t>(value.Get<int>());
571       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p SELECTED_TEXT_END %d\n", impl.mController.Get(), end);
572       impl.SetTextSelectionRange(nullptr, &end);
573       break;
574     }
575     case Toolkit::DevelTextEditor::Property::ENABLE_EDITING:
576     {
577       const bool editable = value.Get<bool>();
578       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p ENABLE_EDITING %d\n", impl.mController.Get(), editable);
579       impl.SetEditable(editable);
580       break;
581     }
582     case Toolkit::DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION:
583     {
584       float horizontalScroll = value.Get<float>();
585       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p HORIZONTAL_SCROLL_POSITION %d\n", impl.mController.Get(), horizontalScroll);
586       if(horizontalScroll >= 0.0f)
587       {
588         impl.ScrollBy(Vector2(horizontalScroll - impl.GetHorizontalScrollPosition(), 0));
589       }
590       break;
591     }
592     case Toolkit::DevelTextEditor::Property::VERTICAL_SCROLL_POSITION:
593     {
594       float verticalScroll = value.Get<float>();
595       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p VERTICAL_SCROLL_POSITION %d\n", impl.mController.Get(), verticalScroll);
596       if(verticalScroll >= 0.0f)
597       {
598         impl.ScrollBy(Vector2(0, verticalScroll - impl.GetVerticalScrollPosition()));
599       }
600       break;
601     }
602     case Toolkit::DevelTextEditor::Property::FONT_SIZE_SCALE:
603     {
604       const float scale = value.Get<float>();
605       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p FONT_SIZE_SCALE %f\n", impl.mController.Get(), scale);
606
607       if(!Equals(impl.mController->GetFontSizeScale(), scale))
608       {
609         impl.mController->SetFontSizeScale(scale);
610       }
611       break;
612     }
613     case Toolkit::DevelTextEditor::Property::PRIMARY_CURSOR_POSITION:
614     {
615       uint32_t position = static_cast<uint32_t>(value.Get<int>());
616       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p PRIMARY_CURSOR_POSITION %d\n", impl.mController.Get(), position);
617       if(impl.mController->SetPrimaryCursorPosition(position, impl.HasKeyInputFocus()))
618       {
619         impl.SetKeyInputFocus();
620       }
621       break;
622     }
623     case Toolkit::DevelTextEditor::Property::GRAB_HANDLE_COLOR:
624     {
625       const Vector4 color = value.Get<Vector4>();
626       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p GRAB_HANDLE_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
627
628       impl.mDecorator->SetHandleColor(color);
629       impl.RequestTextRelayout();
630       break;
631     }
632     case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE_POPUP:
633     {
634       const bool grabHandlePopupEnabled = value.Get<bool>();
635       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p ENABLE_GRAB_HANDLE_POPUP %d\n", impl.mController.Get(), grabHandlePopupEnabled);
636
637       impl.mController->SetGrabHandlePopupEnabled(grabHandlePopupEnabled);
638       break;
639     }
640     case Toolkit::DevelTextEditor::Property::INPUT_METHOD_SETTINGS:
641     {
642       const Property::Map* map = value.GetMap();
643       if(map)
644       {
645         impl.mInputMethodOptions.ApplyProperty(*map);
646       }
647       impl.mController->SetInputModePassword(impl.mInputMethodOptions.IsPassword());
648
649       Toolkit::Control control = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
650       if(control == textEditor)
651       {
652         impl.mInputMethodContext.ApplyOptions(impl.mInputMethodOptions);
653       }
654       break;
655     }
656     case Toolkit::DevelTextEditor::Property::INPUT_FILTER:
657     {
658       const Property::Map* map = value.GetMap();
659       if(map)
660       {
661         impl.mController->SetInputFilterOption(*map);
662       }
663       break;
664     }
665     case Toolkit::DevelTextEditor::Property::ELLIPSIS:
666     {
667       const bool ellipsis = value.Get<bool>();
668       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis);
669
670       impl.mController->SetTextElideEnabled(ellipsis);
671       break;
672     }
673     case Toolkit::DevelTextEditor::Property::ELLIPSIS_POSITION:
674     {
675       DevelText::EllipsisPosition::Type ellipsisPositionType(static_cast<DevelText::EllipsisPosition::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
676       if(Text::GetEllipsisPositionTypeEnumeration(value, ellipsisPositionType))
677       {
678         DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p EllipsisPosition::Type %d\n", impl.mController.Get(), ellipsisPositionType);
679         impl.mController->SetEllipsisPosition(ellipsisPositionType);
680       }
681       break;
682     }
683     case Toolkit::DevelTextEditor::Property::MIN_LINE_SIZE:
684     {
685       const float minLineSize = value.Get<float>();
686       DALI_LOG_INFO(gTextEditorLogFilter, Debug::Verbose, "TextEditor %p MIN_LINE_SIZE %f\n", impl.mController.Get(), minLineSize);
687
688       impl.mController->SetDefaultLineSize(minLineSize);
689       impl.mRenderer.Reset();
690       break;
691     }
692   }
693 }
694
695 Property::Value TextEditor::PropertyHandler::GetProperty(Toolkit::TextEditor textEditor, Property::Index index)
696 {
697   Property::Value value;
698   TextEditor&     impl(GetImpl(textEditor));
699   DALI_ASSERT_DEBUG(impl.mController && "No text controller");
700   DALI_ASSERT_DEBUG(impl.mDecorator && "No text decorator");
701
702   switch(index)
703   {
704     case Toolkit::DevelTextEditor::Property::RENDERING_BACKEND:
705     {
706       value = impl.mRenderingBackend;
707       break;
708     }
709     case Toolkit::TextEditor::Property::TEXT:
710     {
711       std::string text;
712       impl.mController->GetText(text);
713       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p returning text: %s\n", impl.mController.Get(), text.c_str());
714       value = text;
715       break;
716     }
717     case Toolkit::TextEditor::Property::TEXT_COLOR:
718     {
719       value = impl.mController->GetDefaultColor();
720       break;
721     }
722     case Toolkit::TextEditor::Property::FONT_FAMILY:
723     {
724       value = impl.mController->GetDefaultFontFamily();
725       break;
726     }
727     case Toolkit::TextEditor::Property::FONT_STYLE:
728     {
729       GetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT);
730       break;
731     }
732     case Toolkit::TextEditor::Property::POINT_SIZE:
733     {
734       value = impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE);
735       break;
736     }
737     case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
738     {
739       const char* name = Text::GetHorizontalAlignmentString(impl.mController->GetHorizontalAlignment());
740       if(name)
741       {
742         value = std::string(name);
743       }
744       break;
745     }
746     case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
747     {
748       value = impl.mDecorator->GetScrollThreshold();
749       break;
750     }
751     case Toolkit::TextEditor::Property::SCROLL_SPEED:
752     {
753       value = impl.mDecorator->GetScrollSpeed();
754       break;
755     }
756     case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
757     {
758       value = impl.mDecorator->GetColor(Text::PRIMARY_CURSOR);
759       break;
760     }
761     case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
762     {
763       value = impl.mDecorator->GetColor(Text::SECONDARY_CURSOR);
764       break;
765     }
766     case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
767     {
768       value = impl.mController->GetEnableCursorBlink();
769       break;
770     }
771     case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
772     {
773       value = impl.mDecorator->GetCursorBlinkInterval();
774       break;
775     }
776     case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
777     {
778       value = impl.mDecorator->GetCursorBlinkDuration();
779       break;
780     }
781     case Toolkit::TextEditor::Property::CURSOR_WIDTH:
782     {
783       value = impl.mDecorator->GetCursorWidth();
784       break;
785     }
786     case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
787     {
788       value = impl.mDecorator->GetHandleImage(Text::GRAB_HANDLE, Text::HANDLE_IMAGE_RELEASED);
789       break;
790     }
791     case Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE:
792     {
793       value = impl.mDecorator->GetHandleImage(Text::GRAB_HANDLE, Text::HANDLE_IMAGE_PRESSED);
794       break;
795     }
796     case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
797     {
798       impl.GetHandleImagePropertyValue(value, Text::LEFT_SELECTION_HANDLE, Text::HANDLE_IMAGE_RELEASED);
799       break;
800     }
801     case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT:
802     {
803       impl.GetHandleImagePropertyValue(value, Text::RIGHT_SELECTION_HANDLE, Text::HANDLE_IMAGE_RELEASED);
804       break;
805     }
806     case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
807     {
808       impl.GetHandleImagePropertyValue(value, Text::LEFT_SELECTION_HANDLE, Text::HANDLE_IMAGE_PRESSED);
809       break;
810     }
811     case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
812     {
813       impl.GetHandleImagePropertyValue(value, Text::RIGHT_SELECTION_HANDLE, Text::HANDLE_IMAGE_PRESSED);
814       break;
815     }
816     case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
817     {
818       impl.GetHandleImagePropertyValue(value, Text::LEFT_SELECTION_HANDLE_MARKER, Text::HANDLE_IMAGE_RELEASED);
819       break;
820     }
821     case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
822     {
823       impl.GetHandleImagePropertyValue(value, Text::RIGHT_SELECTION_HANDLE_MARKER, Text::HANDLE_IMAGE_RELEASED);
824       break;
825     }
826     case Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR:
827     {
828       value = impl.mDecorator->GetHighlightColor();
829       break;
830     }
831     case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
832     {
833       Rect<int> boundingBox;
834       impl.mDecorator->GetBoundingBox(boundingBox);
835       value = boundingBox;
836       break;
837     }
838     case Toolkit::TextEditor::Property::ENABLE_MARKUP:
839     {
840       value = impl.mController->IsMarkupProcessorEnabled();
841       break;
842     }
843     case Toolkit::TextEditor::Property::INPUT_COLOR:
844     {
845       value = impl.mController->GetInputColor();
846       break;
847     }
848     case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
849     {
850       value = impl.mController->GetInputFontFamily();
851       break;
852     }
853     case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
854     {
855       GetFontStyleProperty(impl.mController, value, Text::FontStyle::INPUT);
856       break;
857     }
858     case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
859     {
860       value = impl.mController->GetInputFontPointSize();
861       break;
862     }
863     case Toolkit::TextEditor::Property::LINE_SPACING:
864     {
865       value = impl.mController->GetDefaultLineSpacing();
866       break;
867     }
868     case Toolkit::TextEditor::Property::INPUT_LINE_SPACING:
869     {
870       value = impl.mController->GetInputLineSpacing();
871       break;
872     }
873     case Toolkit::TextEditor::Property::UNDERLINE:
874     {
875       GetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
876       break;
877     }
878     case Toolkit::TextEditor::Property::INPUT_UNDERLINE:
879     {
880       GetUnderlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
881       break;
882     }
883     case Toolkit::TextEditor::Property::SHADOW:
884     {
885       GetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
886       break;
887     }
888     case Toolkit::TextEditor::Property::INPUT_SHADOW:
889     {
890       GetShadowProperties(impl.mController, value, Text::EffectStyle::INPUT);
891       break;
892     }
893     case Toolkit::TextEditor::Property::EMBOSS:
894     {
895       GetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
896       break;
897     }
898     case Toolkit::TextEditor::Property::INPUT_EMBOSS:
899     {
900       GetEmbossProperties(impl.mController, value, Text::EffectStyle::INPUT);
901       break;
902     }
903     case Toolkit::TextEditor::Property::OUTLINE:
904     {
905       GetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
906       break;
907     }
908     case Toolkit::TextEditor::Property::INPUT_OUTLINE:
909     {
910       GetOutlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
911       break;
912     }
913     case Toolkit::TextEditor::Property::SMOOTH_SCROLL:
914     {
915       value = impl.mScrollAnimationEnabled;
916       break;
917     }
918     case Toolkit::TextEditor::Property::SMOOTH_SCROLL_DURATION:
919     {
920       value = impl.mScrollAnimationDuration;
921       break;
922     }
923     case Toolkit::TextEditor::Property::ENABLE_SCROLL_BAR:
924     {
925       value = impl.mScrollBarEnabled;
926       break;
927     }
928     case Toolkit::TextEditor::Property::SCROLL_BAR_SHOW_DURATION:
929     {
930       value = impl.mAnimationPeriod.delaySeconds;
931       break;
932     }
933     case Toolkit::TextEditor::Property::SCROLL_BAR_FADE_DURATION:
934     {
935       value = impl.mAnimationPeriod.durationSeconds;
936       break;
937     }
938     case Toolkit::TextEditor::Property::PIXEL_SIZE:
939     {
940       value = impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE);
941       break;
942     }
943     case Toolkit::TextEditor::Property::LINE_COUNT:
944     {
945       float width = textEditor.GetProperty(Actor::Property::SIZE_WIDTH).Get<float>();
946       value       = impl.mController->GetLineCount(width);
947       break;
948     }
949     case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT:
950     {
951       std::string text;
952       impl.mController->GetPlaceholderText(Text::Controller::PLACEHOLDER_TYPE_INACTIVE, text);
953       value = text;
954       break;
955     }
956     case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR:
957     {
958       value = impl.mController->GetPlaceholderTextColor();
959       break;
960     }
961     case Toolkit::TextEditor::Property::ENABLE_SELECTION:
962     {
963       value = impl.mController->IsSelectionEnabled();
964       break;
965     }
966     case Toolkit::TextEditor::Property::PLACEHOLDER:
967     {
968       Property::Map map;
969       impl.mController->GetPlaceholderProperty(map);
970       value = map;
971       break;
972     }
973     case Toolkit::TextEditor::Property::LINE_WRAP_MODE:
974     {
975       value = impl.mController->GetLineWrapMode();
976       break;
977     }
978     case Toolkit::DevelTextEditor::Property::ENABLE_SHIFT_SELECTION:
979     {
980       value = impl.mController->IsShiftSelectionEnabled();
981       break;
982     }
983     case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE:
984     {
985       value = impl.mController->IsGrabHandleEnabled();
986       break;
987     }
988     case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
989     {
990       value = impl.mController->GetMatchLayoutDirection() != DevelText::MatchLayoutDirection::CONTENTS;
991       break;
992     }
993     case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
994     {
995       value = impl.mController->GetMaximumNumberOfCharacters();
996       break;
997     }
998     case Toolkit::DevelTextEditor::Property::SELECTED_TEXT:
999     {
1000       value = impl.mController->GetSelectedText();
1001       break;
1002     }
1003     case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_START:
1004     {
1005       Uint32Pair range = impl.GetTextSelectionRange();
1006       value            = static_cast<int>(range.first);
1007       break;
1008     }
1009     case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_END:
1010     {
1011       Uint32Pair range = impl.GetTextSelectionRange();
1012       value            = static_cast<int>(range.second);
1013       break;
1014     }
1015     case Toolkit::DevelTextEditor::Property::ENABLE_EDITING:
1016     {
1017       value = impl.IsEditable();
1018       break;
1019     }
1020     case Toolkit::DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION:
1021     {
1022       value = impl.GetHorizontalScrollPosition();
1023       break;
1024     }
1025     case Toolkit::DevelTextEditor::Property::VERTICAL_SCROLL_POSITION:
1026     {
1027       value = impl.GetVerticalScrollPosition();
1028       break;
1029     }
1030     case Toolkit::DevelTextEditor::Property::FONT_SIZE_SCALE:
1031     {
1032       value = impl.mController->GetFontSizeScale();
1033       break;
1034     }
1035     case Toolkit::DevelTextEditor::Property::PRIMARY_CURSOR_POSITION:
1036     {
1037       value = static_cast<int>(impl.mController->GetPrimaryCursorPosition());
1038       break;
1039     }
1040     case Toolkit::DevelTextEditor::Property::GRAB_HANDLE_COLOR:
1041     {
1042       value = impl.mDecorator->GetHandleColor();
1043       break;
1044     }
1045     case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE_POPUP:
1046     {
1047       value = impl.mController->IsGrabHandlePopupEnabled();
1048       break;
1049     }
1050     case Toolkit::DevelTextEditor::Property::INPUT_METHOD_SETTINGS:
1051     {
1052       Property::Map map;
1053       impl.mInputMethodOptions.RetrieveProperty(map);
1054       value = map;
1055       break;
1056     }
1057     case Toolkit::DevelTextEditor::Property::INPUT_FILTER:
1058     {
1059       Property::Map map;
1060       impl.mController->GetInputFilterOption(map);
1061       value = map;
1062       break;
1063     }
1064     case Toolkit::DevelTextEditor::Property::ELLIPSIS:
1065     {
1066       value = impl.mController->IsTextElideEnabled();
1067       break;
1068     }
1069     case Toolkit::DevelTextEditor::Property::ELLIPSIS_POSITION:
1070     {
1071       value = impl.mController->GetEllipsisPosition();
1072       break;
1073     }
1074     case Toolkit::DevelTextEditor::Property::MIN_LINE_SIZE:
1075     {
1076       value = impl.mController->GetDefaultLineSize();
1077       break;
1078     }
1079   } //switch
1080   return value;
1081 }
1082
1083 } // namespace Dali::Toolkit::Internal