Extending Style - Adding Strikethrough
[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/common-text-utils.h>
18 #include <dali-toolkit/internal/controls/text-controls/text-editor-property-handler.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     case Toolkit::DevelTextEditor::Property::STRIKETHROUGH:
693     {
694       const bool update = SetStrikethroughProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
695       if(update)
696       {
697         impl.mRenderer.Reset();
698       }
699       break;
700     }
701     case Toolkit::DevelTextEditor::Property::INPUT_STRIKETHROUGH:
702     {
703       const bool update = SetStrikethroughProperties(impl.mController, value, Text::EffectStyle::INPUT);
704       if(update)
705       {
706         impl.mRenderer.Reset();
707       }
708       break;
709     }
710   }
711 }
712
713 Property::Value TextEditor::PropertyHandler::GetProperty(Toolkit::TextEditor textEditor, Property::Index index)
714 {
715   Property::Value value;
716   TextEditor&     impl(GetImpl(textEditor));
717   DALI_ASSERT_DEBUG(impl.mController && "No text controller");
718   DALI_ASSERT_DEBUG(impl.mDecorator && "No text decorator");
719
720   switch(index)
721   {
722     case Toolkit::DevelTextEditor::Property::RENDERING_BACKEND:
723     {
724       value = impl.mRenderingBackend;
725       break;
726     }
727     case Toolkit::TextEditor::Property::TEXT:
728     {
729       std::string text;
730       impl.mController->GetText(text);
731       DALI_LOG_INFO(gTextEditorLogFilter, Debug::General, "TextEditor %p returning text: %s\n", impl.mController.Get(), text.c_str());
732       value = text;
733       break;
734     }
735     case Toolkit::TextEditor::Property::TEXT_COLOR:
736     {
737       value = impl.mController->GetDefaultColor();
738       break;
739     }
740     case Toolkit::TextEditor::Property::FONT_FAMILY:
741     {
742       value = impl.mController->GetDefaultFontFamily();
743       break;
744     }
745     case Toolkit::TextEditor::Property::FONT_STYLE:
746     {
747       GetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT);
748       break;
749     }
750     case Toolkit::TextEditor::Property::POINT_SIZE:
751     {
752       value = impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE);
753       break;
754     }
755     case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
756     {
757       const char* name = Text::GetHorizontalAlignmentString(impl.mController->GetHorizontalAlignment());
758       if(name)
759       {
760         value = std::string(name);
761       }
762       break;
763     }
764     case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
765     {
766       value = impl.mDecorator->GetScrollThreshold();
767       break;
768     }
769     case Toolkit::TextEditor::Property::SCROLL_SPEED:
770     {
771       value = impl.mDecorator->GetScrollSpeed();
772       break;
773     }
774     case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
775     {
776       value = impl.mDecorator->GetColor(Text::PRIMARY_CURSOR);
777       break;
778     }
779     case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
780     {
781       value = impl.mDecorator->GetColor(Text::SECONDARY_CURSOR);
782       break;
783     }
784     case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
785     {
786       value = impl.mController->GetEnableCursorBlink();
787       break;
788     }
789     case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
790     {
791       value = impl.mDecorator->GetCursorBlinkInterval();
792       break;
793     }
794     case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
795     {
796       value = impl.mDecorator->GetCursorBlinkDuration();
797       break;
798     }
799     case Toolkit::TextEditor::Property::CURSOR_WIDTH:
800     {
801       value = impl.mDecorator->GetCursorWidth();
802       break;
803     }
804     case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
805     {
806       value = impl.mDecorator->GetHandleImage(Text::GRAB_HANDLE, Text::HANDLE_IMAGE_RELEASED);
807       break;
808     }
809     case Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE:
810     {
811       value = impl.mDecorator->GetHandleImage(Text::GRAB_HANDLE, Text::HANDLE_IMAGE_PRESSED);
812       break;
813     }
814     case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
815     {
816       impl.GetHandleImagePropertyValue(value, Text::LEFT_SELECTION_HANDLE, Text::HANDLE_IMAGE_RELEASED);
817       break;
818     }
819     case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT:
820     {
821       impl.GetHandleImagePropertyValue(value, Text::RIGHT_SELECTION_HANDLE, Text::HANDLE_IMAGE_RELEASED);
822       break;
823     }
824     case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
825     {
826       impl.GetHandleImagePropertyValue(value, Text::LEFT_SELECTION_HANDLE, Text::HANDLE_IMAGE_PRESSED);
827       break;
828     }
829     case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
830     {
831       impl.GetHandleImagePropertyValue(value, Text::RIGHT_SELECTION_HANDLE, Text::HANDLE_IMAGE_PRESSED);
832       break;
833     }
834     case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
835     {
836       impl.GetHandleImagePropertyValue(value, Text::LEFT_SELECTION_HANDLE_MARKER, Text::HANDLE_IMAGE_RELEASED);
837       break;
838     }
839     case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
840     {
841       impl.GetHandleImagePropertyValue(value, Text::RIGHT_SELECTION_HANDLE_MARKER, Text::HANDLE_IMAGE_RELEASED);
842       break;
843     }
844     case Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR:
845     {
846       value = impl.mDecorator->GetHighlightColor();
847       break;
848     }
849     case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
850     {
851       Rect<int> boundingBox;
852       impl.mDecorator->GetBoundingBox(boundingBox);
853       value = boundingBox;
854       break;
855     }
856     case Toolkit::TextEditor::Property::ENABLE_MARKUP:
857     {
858       value = impl.mController->IsMarkupProcessorEnabled();
859       break;
860     }
861     case Toolkit::TextEditor::Property::INPUT_COLOR:
862     {
863       value = impl.mController->GetInputColor();
864       break;
865     }
866     case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
867     {
868       value = impl.mController->GetInputFontFamily();
869       break;
870     }
871     case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
872     {
873       GetFontStyleProperty(impl.mController, value, Text::FontStyle::INPUT);
874       break;
875     }
876     case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
877     {
878       value = impl.mController->GetInputFontPointSize();
879       break;
880     }
881     case Toolkit::TextEditor::Property::LINE_SPACING:
882     {
883       value = impl.mController->GetDefaultLineSpacing();
884       break;
885     }
886     case Toolkit::TextEditor::Property::INPUT_LINE_SPACING:
887     {
888       value = impl.mController->GetInputLineSpacing();
889       break;
890     }
891     case Toolkit::TextEditor::Property::UNDERLINE:
892     {
893       GetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
894       break;
895     }
896     case Toolkit::TextEditor::Property::INPUT_UNDERLINE:
897     {
898       GetUnderlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
899       break;
900     }
901     case Toolkit::TextEditor::Property::SHADOW:
902     {
903       GetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
904       break;
905     }
906     case Toolkit::TextEditor::Property::INPUT_SHADOW:
907     {
908       GetShadowProperties(impl.mController, value, Text::EffectStyle::INPUT);
909       break;
910     }
911     case Toolkit::TextEditor::Property::EMBOSS:
912     {
913       GetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
914       break;
915     }
916     case Toolkit::TextEditor::Property::INPUT_EMBOSS:
917     {
918       GetEmbossProperties(impl.mController, value, Text::EffectStyle::INPUT);
919       break;
920     }
921     case Toolkit::TextEditor::Property::OUTLINE:
922     {
923       GetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
924       break;
925     }
926     case Toolkit::TextEditor::Property::INPUT_OUTLINE:
927     {
928       GetOutlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
929       break;
930     }
931     case Toolkit::TextEditor::Property::SMOOTH_SCROLL:
932     {
933       value = impl.mScrollAnimationEnabled;
934       break;
935     }
936     case Toolkit::TextEditor::Property::SMOOTH_SCROLL_DURATION:
937     {
938       value = impl.mScrollAnimationDuration;
939       break;
940     }
941     case Toolkit::TextEditor::Property::ENABLE_SCROLL_BAR:
942     {
943       value = impl.mScrollBarEnabled;
944       break;
945     }
946     case Toolkit::TextEditor::Property::SCROLL_BAR_SHOW_DURATION:
947     {
948       value = impl.mAnimationPeriod.delaySeconds;
949       break;
950     }
951     case Toolkit::TextEditor::Property::SCROLL_BAR_FADE_DURATION:
952     {
953       value = impl.mAnimationPeriod.durationSeconds;
954       break;
955     }
956     case Toolkit::TextEditor::Property::PIXEL_SIZE:
957     {
958       value = impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE);
959       break;
960     }
961     case Toolkit::TextEditor::Property::LINE_COUNT:
962     {
963       float width = textEditor.GetProperty(Actor::Property::SIZE_WIDTH).Get<float>();
964       value       = impl.mController->GetLineCount(width);
965       break;
966     }
967     case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT:
968     {
969       std::string text;
970       impl.mController->GetPlaceholderText(Text::Controller::PLACEHOLDER_TYPE_INACTIVE, text);
971       value = text;
972       break;
973     }
974     case Toolkit::DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR:
975     {
976       value = impl.mController->GetPlaceholderTextColor();
977       break;
978     }
979     case Toolkit::TextEditor::Property::ENABLE_SELECTION:
980     {
981       value = impl.mController->IsSelectionEnabled();
982       break;
983     }
984     case Toolkit::TextEditor::Property::PLACEHOLDER:
985     {
986       Property::Map map;
987       impl.mController->GetPlaceholderProperty(map);
988       value = map;
989       break;
990     }
991     case Toolkit::TextEditor::Property::LINE_WRAP_MODE:
992     {
993       value = impl.mController->GetLineWrapMode();
994       break;
995     }
996     case Toolkit::DevelTextEditor::Property::STRIKETHROUGH:
997     {
998       GetStrikethroughProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
999       break;
1000     }
1001     case Toolkit::DevelTextEditor::Property::INPUT_STRIKETHROUGH:
1002     {
1003       GetStrikethroughProperties(impl.mController, value, Text::EffectStyle::INPUT);
1004       break;
1005     }
1006     case Toolkit::DevelTextEditor::Property::ENABLE_SHIFT_SELECTION:
1007     {
1008       value = impl.mController->IsShiftSelectionEnabled();
1009       break;
1010     }
1011     case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE:
1012     {
1013       value = impl.mController->IsGrabHandleEnabled();
1014       break;
1015     }
1016     case Toolkit::DevelTextEditor::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
1017     {
1018       value = impl.mController->GetMatchLayoutDirection() != DevelText::MatchLayoutDirection::CONTENTS;
1019       break;
1020     }
1021     case Toolkit::DevelTextEditor::Property::MAX_LENGTH:
1022     {
1023       value = impl.mController->GetMaximumNumberOfCharacters();
1024       break;
1025     }
1026     case Toolkit::DevelTextEditor::Property::SELECTED_TEXT:
1027     {
1028       value = impl.mController->GetSelectedText();
1029       break;
1030     }
1031     case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_START:
1032     {
1033       Uint32Pair range = impl.GetTextSelectionRange();
1034       value            = static_cast<int>(range.first);
1035       break;
1036     }
1037     case Toolkit::DevelTextEditor::Property::SELECTED_TEXT_END:
1038     {
1039       Uint32Pair range = impl.GetTextSelectionRange();
1040       value            = static_cast<int>(range.second);
1041       break;
1042     }
1043     case Toolkit::DevelTextEditor::Property::ENABLE_EDITING:
1044     {
1045       value = impl.IsEditable();
1046       break;
1047     }
1048     case Toolkit::DevelTextEditor::Property::HORIZONTAL_SCROLL_POSITION:
1049     {
1050       value = impl.GetHorizontalScrollPosition();
1051       break;
1052     }
1053     case Toolkit::DevelTextEditor::Property::VERTICAL_SCROLL_POSITION:
1054     {
1055       value = impl.GetVerticalScrollPosition();
1056       break;
1057     }
1058     case Toolkit::DevelTextEditor::Property::FONT_SIZE_SCALE:
1059     {
1060       value = impl.mController->GetFontSizeScale();
1061       break;
1062     }
1063     case Toolkit::DevelTextEditor::Property::PRIMARY_CURSOR_POSITION:
1064     {
1065       value = static_cast<int>(impl.mController->GetPrimaryCursorPosition());
1066       break;
1067     }
1068     case Toolkit::DevelTextEditor::Property::GRAB_HANDLE_COLOR:
1069     {
1070       value = impl.mDecorator->GetHandleColor();
1071       break;
1072     }
1073     case Toolkit::DevelTextEditor::Property::ENABLE_GRAB_HANDLE_POPUP:
1074     {
1075       value = impl.mController->IsGrabHandlePopupEnabled();
1076       break;
1077     }
1078     case Toolkit::DevelTextEditor::Property::INPUT_METHOD_SETTINGS:
1079     {
1080       Property::Map map;
1081       impl.mInputMethodOptions.RetrieveProperty(map);
1082       value = map;
1083       break;
1084     }
1085     case Toolkit::DevelTextEditor::Property::INPUT_FILTER:
1086     {
1087       Property::Map map;
1088       impl.mController->GetInputFilterOption(map);
1089       value = map;
1090       break;
1091     }
1092     case Toolkit::DevelTextEditor::Property::ELLIPSIS:
1093     {
1094       value = impl.mController->IsTextElideEnabled();
1095       break;
1096     }
1097     case Toolkit::DevelTextEditor::Property::ELLIPSIS_POSITION:
1098     {
1099       value = impl.mController->GetEllipsisPosition();
1100       break;
1101     }
1102     case Toolkit::DevelTextEditor::Property::MIN_LINE_SIZE:
1103     {
1104       value = impl.mController->GetDefaultLineSize();
1105       break;
1106     }
1107   } //switch
1108   return value;
1109 }
1110
1111 } // namespace Dali::Toolkit::Internal