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