Merge "Add WebView SetTtsFocus" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-field-impl.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
18 // CLASS HEADER
19 #include <dali-toolkit/internal/controls/text-controls/text-field-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/actors/actor-devel.h>
23 #include <dali/devel-api/adaptor-framework/key-devel.h>
24 #include <dali/devel-api/common/stage.h>
25 #include <dali/devel-api/object/property-helper-devel.h>
26 #include <dali/integration-api/debug.h>
27 #include <dali/public-api/adaptor-framework/key.h>
28 #include <dali/public-api/common/dali-common.h>
29 #include <dali/public-api/object/type-registry-helper.h>
30 #include <cstring>
31
32 // INTERNAL INCLUDES
33 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
34 #include <dali-toolkit/devel-api/controls/control-devel.h>
35 #include <dali-toolkit/devel-api/controls/text-controls/text-field-devel.h>
36 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
37 #include <dali-toolkit/devel-api/text/rendering-backend.h>
38 #include <dali-toolkit/internal/styling/style-manager-impl.h>
39 #include <dali-toolkit/internal/text/rendering/text-backend.h>
40 #include <dali-toolkit/internal/text/text-effects-style.h>
41 #include <dali-toolkit/internal/text/text-enumerations-impl.h>
42 #include <dali-toolkit/internal/text/text-font-style.h>
43 #include <dali-toolkit/internal/text/text-view.h>
44 #include <dali-toolkit/public-api/text/text-enumerations.h>
45 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
46 #include <dali-toolkit/public-api/visuals/visual-properties.h>
47 #include <dali/integration-api/adaptor-framework/adaptor.h>
48
49 using namespace Dali::Toolkit::Text;
50
51 namespace Dali
52 {
53 namespace Toolkit
54 {
55 namespace Internal
56 {
57 namespace // unnamed namespace
58 {
59 #if defined(DEBUG_ENABLED)
60 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
61 #endif
62
63 const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::DevelText::DEFAULT_RENDERING_BACKEND;
64 } // unnamed namespace
65
66 namespace
67 {
68 // Type registration
69 BaseHandle Create()
70 {
71   return Toolkit::TextField::New();
72 }
73
74 // clang-format off
75 // Setup properties, signals and actions using the type-registry.
76 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextField, Toolkit::Control, Create );
77
78 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "text",                             STRING,    TEXT                                )
79 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "placeholderText",                  STRING,    PLACEHOLDER_TEXT                    )
80 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "placeholderTextFocused",           STRING,    PLACEHOLDER_TEXT_FOCUSED            )
81 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "fontFamily",                       STRING,    FONT_FAMILY                         )
82 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "fontStyle",                        MAP,       FONT_STYLE                          )
83 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "pointSize",                        FLOAT,     POINT_SIZE                          )
84 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "maxLength",                        INTEGER,   MAX_LENGTH                          )
85 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "exceedPolicy",                     INTEGER,   EXCEED_POLICY                       )
86 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "horizontalAlignment",              STRING,    HORIZONTAL_ALIGNMENT                )
87 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "verticalAlignment",                STRING,    VERTICAL_ALIGNMENT                  )
88 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "textColor",                        VECTOR4,   TEXT_COLOR                          )
89 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "placeholderTextColor",             VECTOR4,   PLACEHOLDER_TEXT_COLOR              )
90 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "primaryCursorColor",               VECTOR4,   PRIMARY_CURSOR_COLOR                )
91 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "secondaryCursorColor",             VECTOR4,   SECONDARY_CURSOR_COLOR              )
92 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "enableCursorBlink",                BOOLEAN,   ENABLE_CURSOR_BLINK                 )
93 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "cursorBlinkInterval",              FLOAT,     CURSOR_BLINK_INTERVAL               )
94 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "cursorBlinkDuration",              FLOAT,     CURSOR_BLINK_DURATION               )
95 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "cursorWidth",                      INTEGER,   CURSOR_WIDTH                        )
96 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "grabHandleImage",                  STRING,    GRAB_HANDLE_IMAGE                   )
97 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "grabHandlePressedImage",           STRING,    GRAB_HANDLE_PRESSED_IMAGE           )
98 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "scrollThreshold",                  FLOAT,     SCROLL_THRESHOLD                    )
99 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "scrollSpeed",                      FLOAT,     SCROLL_SPEED                        )
100 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "selectionHandleImageLeft",         MAP,       SELECTION_HANDLE_IMAGE_LEFT         )
101 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "selectionHandleImageRight",        MAP,       SELECTION_HANDLE_IMAGE_RIGHT        )
102 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "selectionHandlePressedImageLeft",  MAP,       SELECTION_HANDLE_PRESSED_IMAGE_LEFT )
103 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "selectionHandlePressedImageRight", MAP,       SELECTION_HANDLE_PRESSED_IMAGE_RIGHT)
104 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "selectionHandleMarkerImageLeft",   MAP,       SELECTION_HANDLE_MARKER_IMAGE_LEFT  )
105 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "selectionHandleMarkerImageRight",  MAP,       SELECTION_HANDLE_MARKER_IMAGE_RIGHT )
106 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "selectionHighlightColor",          VECTOR4,   SELECTION_HIGHLIGHT_COLOR           )
107 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "decorationBoundingBox",            RECTANGLE, DECORATION_BOUNDING_BOX             )
108 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "inputMethodSettings",              MAP,       INPUT_METHOD_SETTINGS               )
109 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "inputColor",                       VECTOR4,   INPUT_COLOR                         )
110 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "enableMarkup",                     BOOLEAN,   ENABLE_MARKUP                       )
111 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "inputFontFamily",                  STRING,    INPUT_FONT_FAMILY                   )
112 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "inputFontStyle",                   MAP,       INPUT_FONT_STYLE                    )
113 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "inputPointSize",                   FLOAT,     INPUT_POINT_SIZE                    )
114 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "underline",                        MAP,       UNDERLINE                           )
115 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "inputUnderline",                   MAP,       INPUT_UNDERLINE                     )
116 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "shadow",                           MAP,       SHADOW                              )
117 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "inputShadow",                      MAP,       INPUT_SHADOW                        )
118 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "emboss",                           MAP,       EMBOSS                              )
119 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "inputEmboss",                      MAP,       INPUT_EMBOSS                        )
120 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "outline",                          MAP,       OUTLINE                             )
121 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "inputOutline",                     MAP,       INPUT_OUTLINE                       )
122 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "hiddenInputSettings",              MAP,       HIDDEN_INPUT_SETTINGS               )
123 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "pixelSize",                        FLOAT,     PIXEL_SIZE                          )
124 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "enableSelection",                  BOOLEAN,   ENABLE_SELECTION                    )
125 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "placeholder",                      MAP,       PLACEHOLDER                         )
126 DALI_PROPERTY_REGISTRATION(Toolkit,                 TextField, "ellipsis",                         BOOLEAN,   ELLIPSIS                            )
127 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "enableShiftSelection",             BOOLEAN,   ENABLE_SHIFT_SELECTION              )
128 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "enableGrabHandle",                 BOOLEAN,   ENABLE_GRAB_HANDLE                  )
129 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "matchSystemLanguageDirection",     BOOLEAN,   MATCH_SYSTEM_LANGUAGE_DIRECTION     )
130 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "enableGrabHandlePopup",            BOOLEAN,   ENABLE_GRAB_HANDLE_POPUP            )
131 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "textBackground",                   VECTOR4,   BACKGROUND                          )
132 DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY(Toolkit, TextField, "selectedText",                     STRING,    SELECTED_TEXT                       )
133 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "renderingBackend",                 INTEGER,   RENDERING_BACKEND                   )
134 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "selectedTextStart",                INTEGER,   SELECTED_TEXT_START                 )
135 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "selectedTextEnd",                  INTEGER,   SELECTED_TEXT_END                   )
136 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "enableEditing",                    BOOLEAN,   ENABLE_EDITING                      )
137 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "fontSizeScale",                    FLOAT,     FONT_SIZE_SCALE                     )
138 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "primaryCursorPosition",            INTEGER,   PRIMARY_CURSOR_POSITION             )
139 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "grabHandleColor",                  VECTOR4,   GRAB_HANDLE_COLOR                   )
140 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "inputFilter",                      MAP,       INPUT_FILTER                        )
141
142 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "textChanged",       SIGNAL_TEXT_CHANGED       )
143 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "maxLengthReached",  SIGNAL_MAX_LENGTH_REACHED )
144 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "inputStyleChanged", SIGNAL_INPUT_STYLE_CHANGED)
145 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "anchorClicked",     SIGNAL_ANCHOR_CLICKED     )
146 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "inputFiltered",     SIGNAL_INPUT_FILTERED     )
147
148 DALI_TYPE_REGISTRATION_END()
149 // clang-format on
150
151 const char* const IMAGE_MAP_FILENAME_STRING = "filename";
152
153 /// Retrieves a filename from a value that is a Property::Map
154 std::string GetImageFileNameFromPropertyValue(const Property::Value& value)
155 {
156   std::string          filename;
157   const Property::Map* map = value.GetMap();
158   if(map)
159   {
160     const Property::Value* filenameValue = map->Find(IMAGE_MAP_FILENAME_STRING);
161     if(filenameValue)
162     {
163       filenameValue->Get(filename);
164     }
165   }
166   return filename;
167 }
168
169 } // namespace
170
171 Toolkit::TextField TextField::New()
172 {
173   // Create the implementation, temporarily owned by this handle on stack
174   IntrusivePtr<TextField> impl = new TextField();
175
176   // Pass ownership to CustomActor handle
177   Toolkit::TextField handle(*impl);
178
179   // Second-phase init of the implementation
180   // This can only be done after the CustomActor connection has been made...
181   impl->Initialize();
182
183   return handle;
184 }
185
186 void TextField::SetProperty(BaseObject* object, Property::Index index, const Property::Value& value)
187 {
188   Toolkit::TextField textField = Toolkit::TextField::DownCast(Dali::BaseHandle(object));
189
190   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField SetProperty\n");
191
192   if(textField)
193   {
194     TextField& impl(GetImpl(textField));
195     DALI_ASSERT_DEBUG(impl.mController && "No text contoller");
196     DALI_ASSERT_DEBUG(impl.mDecorator && "No text decorator");
197
198     switch(index)
199     {
200       case Toolkit::DevelTextField::Property::RENDERING_BACKEND:
201       {
202         int backend = value.Get<int>();
203         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend);
204
205 #ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
206         if(DevelText::RENDERING_VECTOR_BASED == backend)
207         {
208           backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering
209         }
210 #endif
211         if(impl.mRenderingBackend != backend)
212         {
213           impl.mRenderingBackend = backend;
214           impl.mRenderer.Reset();
215
216           // When using the vector-based rendering, the size of the GLyphs are different
217           TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
218           impl.mController->SetGlyphType(glyphType);
219         }
220         break;
221       }
222       case Toolkit::TextField::Property::TEXT:
223       {
224         const std::string& text = value.Get<std::string>();
225         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p TEXT %s\n", impl.mController.Get(), text.c_str());
226
227         impl.mController->SetText(text);
228         break;
229       }
230       case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
231       {
232         const std::string& text = value.Get<std::string>();
233         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str());
234
235         impl.mController->SetPlaceholderText(Controller::PLACEHOLDER_TYPE_INACTIVE, text);
236         break;
237       }
238       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_FOCUSED:
239       {
240         const std::string& text = value.Get<std::string>();
241         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_FOCUSED %s\n", impl.mController.Get(), text.c_str());
242
243         impl.mController->SetPlaceholderText(Controller::PLACEHOLDER_TYPE_ACTIVE, text);
244         break;
245       }
246       case Toolkit::TextField::Property::FONT_FAMILY:
247       {
248         const std::string& fontFamily = value.Get<std::string>();
249         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str());
250         impl.mController->SetDefaultFontFamily(fontFamily);
251         break;
252       }
253       case Toolkit::TextField::Property::FONT_STYLE:
254       {
255         SetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT);
256         break;
257       }
258       case Toolkit::TextField::Property::POINT_SIZE:
259       {
260         const float pointSize = value.Get<float>();
261         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p POINT_SIZE %f\n", impl.mController.Get(), pointSize);
262
263         if(!Equals(impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE), pointSize))
264         {
265           impl.mController->SetDefaultFontSize(pointSize, Text::Controller::POINT_SIZE);
266         }
267         break;
268       }
269       case Toolkit::TextField::Property::MAX_LENGTH:
270       {
271         const int max = value.Get<int>();
272         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p MAX_LENGTH %d\n", impl.mController.Get(), max);
273
274         impl.mController->SetMaximumNumberOfCharacters(max);
275         break;
276       }
277       case Toolkit::TextField::Property::EXCEED_POLICY:
278       {
279         impl.mExceedPolicy = value.Get<int>();
280
281         if(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == impl.mExceedPolicy)
282         {
283           impl.EnableClipping();
284         }
285         else
286         {
287           UnparentAndReset(impl.mStencil);
288         }
289         impl.RequestTextRelayout();
290         break;
291       }
292       case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
293       {
294         Text::HorizontalAlignment::Type alignment(static_cast<Text::HorizontalAlignment::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
295         if(GetHorizontalAlignmentEnumeration(value, alignment))
296         {
297           DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %d\n", impl.mController.Get(), alignment);
298           impl.mController->SetHorizontalAlignment(alignment);
299         }
300         break;
301       }
302       case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
303       {
304         Toolkit::Text::VerticalAlignment::Type alignment(static_cast<Text::VerticalAlignment::Type>(-1)); // Set to invalid value to ensure a valid mode does get set
305         if(GetVerticalAlignmentEnumeration(value, alignment))
306         {
307           impl.mController->SetVerticalAlignment(alignment);
308           DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %d\n", impl.mController.Get(), alignment);
309         }
310         break;
311       }
312       case Toolkit::TextField::Property::TEXT_COLOR:
313       {
314         const Vector4& textColor = value.Get<Vector4>();
315         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a);
316
317         if(impl.mController->GetDefaultColor() != textColor)
318         {
319           impl.mController->SetDefaultColor(textColor);
320           impl.mController->SetInputColor(textColor);
321           impl.mRenderer.Reset();
322         }
323         break;
324       }
325       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
326       {
327         const Vector4& textColor = value.Get<Vector4>();
328         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a);
329
330         if(impl.mController->GetPlaceholderTextColor() != textColor)
331         {
332           impl.mController->SetPlaceholderTextColor(textColor);
333           impl.mRenderer.Reset();
334         }
335         break;
336       }
337       case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
338       {
339         const Vector4& color = value.Get<Vector4>();
340         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
341
342         impl.mDecorator->SetCursorColor(PRIMARY_CURSOR, color);
343         impl.RequestTextRelayout();
344         break;
345       }
346       case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
347       {
348         const Vector4& color = value.Get<Vector4>();
349         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
350
351         impl.mDecorator->SetCursorColor(SECONDARY_CURSOR, color);
352         impl.RequestTextRelayout();
353         break;
354       }
355       case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
356       {
357         const bool enable = value.Get<bool>();
358         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable);
359
360         impl.mController->SetEnableCursorBlink(enable);
361         impl.RequestTextRelayout();
362         break;
363       }
364       case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
365       {
366         const float interval = value.Get<float>();
367         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval);
368
369         impl.mDecorator->SetCursorBlinkInterval(interval);
370         break;
371       }
372       case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
373       {
374         const float duration = value.Get<float>();
375         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration);
376
377         impl.mDecorator->SetCursorBlinkDuration(duration);
378         break;
379       }
380       case Toolkit::TextField::Property::CURSOR_WIDTH:
381       {
382         const int width = value.Get<int>();
383         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p CURSOR_WIDTH %d\n", impl.mController.Get(), width);
384
385         impl.mDecorator->SetCursorWidth(width);
386         impl.mController->GetLayoutEngine().SetCursorWidth(width);
387         break;
388       }
389       case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
390       {
391         const std::string imageFileName = value.Get<std::string>();
392         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str());
393
394         if(imageFileName.size())
395         {
396           impl.mDecorator->SetHandleImage(GRAB_HANDLE, HANDLE_IMAGE_RELEASED, imageFileName);
397           impl.RequestTextRelayout();
398         }
399         break;
400       }
401       case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
402       {
403         const std::string imageFileName = value.Get<std::string>();
404         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str());
405
406         if(imageFileName.size())
407         {
408           impl.mDecorator->SetHandleImage(GRAB_HANDLE, HANDLE_IMAGE_PRESSED, imageFileName);
409           impl.RequestTextRelayout();
410         }
411         break;
412       }
413       case Toolkit::TextField::Property::SCROLL_THRESHOLD:
414       {
415         const float threshold = value.Get<float>();
416         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold);
417
418         impl.mDecorator->SetScrollThreshold(threshold);
419         break;
420       }
421       case Toolkit::TextField::Property::SCROLL_SPEED:
422       {
423         const float speed = value.Get<float>();
424         DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField %p SCROLL_SPEED %f\n", impl.mController.Get(), speed);
425
426         impl.mDecorator->SetScrollSpeed(speed);
427         break;
428       }
429       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
430       {
431         const std::string filename = GetImageFileNameFromPropertyValue(value);
432
433         if(filename.size())
434         {
435           impl.mDecorator->SetHandleImage(LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename);
436           impl.RequestTextRelayout();
437         }
438         break;
439       }
440       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
441       {
442         const std::string filename = GetImageFileNameFromPropertyValue(value);
443
444         if(filename.size())
445         {
446           impl.mDecorator->SetHandleImage(RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename);
447           impl.RequestTextRelayout();
448         }
449         break;
450       }
451       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
452       {
453         const std::string filename = GetImageFileNameFromPropertyValue(value);
454
455         if(filename.size())
456         {
457           impl.mDecorator->SetHandleImage(LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename);
458           impl.RequestTextRelayout();
459         }
460         break;
461       }
462       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
463       {
464         const std::string filename = GetImageFileNameFromPropertyValue(value);
465
466         if(filename.size())
467         {
468           impl.mDecorator->SetHandleImage(RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename);
469           impl.RequestTextRelayout();
470         }
471         break;
472       }
473       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
474       {
475         const std::string filename = GetImageFileNameFromPropertyValue(value);
476
477         if(filename.size())
478         {
479           impl.mDecorator->SetHandleImage(LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename);
480           impl.RequestTextRelayout();
481         }
482         break;
483       }
484       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
485       {
486         const std::string filename = GetImageFileNameFromPropertyValue(value);
487
488         if(filename.size())
489         {
490           impl.mDecorator->SetHandleImage(RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename);
491           impl.RequestTextRelayout();
492         }
493         break;
494       }
495       case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
496       {
497         const Vector4 color = value.Get<Vector4>();
498         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p SELECTION_HIGHLIGHT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
499
500         impl.mDecorator->SetHighlightColor(color);
501         impl.RequestTextRelayout();
502         break;
503       }
504       case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
505       {
506         const Rect<int> box = value.Get<Rect<int> >();
507         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height);
508
509         impl.mDecorator->SetBoundingBox(box);
510         impl.RequestTextRelayout();
511         break;
512       }
513       case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
514       {
515         const Property::Map* map = value.GetMap();
516         if(map)
517         {
518           impl.mInputMethodOptions.ApplyProperty(*map);
519         }
520         impl.mController->SetInputModePassword(impl.mInputMethodOptions.IsPassword());
521
522         Toolkit::Control control = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
523         if(control == textField)
524         {
525           impl.mInputMethodContext.ApplyOptions(impl.mInputMethodOptions);
526         }
527         break;
528       }
529       case Toolkit::TextField::Property::INPUT_COLOR:
530       {
531         const Vector4 inputColor = value.Get<Vector4>();
532         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p INPUT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), inputColor.r, inputColor.g, inputColor.b, inputColor.a);
533
534         impl.mController->SetInputColor(inputColor);
535         break;
536       }
537       case Toolkit::TextField::Property::ENABLE_MARKUP:
538       {
539         const bool enableMarkup = value.Get<bool>();
540         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup);
541
542         impl.mController->SetMarkupProcessorEnabled(enableMarkup);
543         break;
544       }
545       case Toolkit::TextField::Property::INPUT_FONT_FAMILY:
546       {
547         const std::string& fontFamily = value.Get<std::string>();
548         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str());
549         impl.mController->SetInputFontFamily(fontFamily);
550         break;
551       }
552       case Toolkit::TextField::Property::INPUT_FONT_STYLE:
553       {
554         SetFontStyleProperty(impl.mController, value, Text::FontStyle::INPUT);
555         break;
556       }
557       case Toolkit::TextField::Property::INPUT_POINT_SIZE:
558       {
559         const float pointSize = value.Get<float>();
560         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize);
561         impl.mController->SetInputFontPointSize(pointSize);
562         break;
563       }
564       case Toolkit::TextField::Property::UNDERLINE:
565       {
566         const bool update = SetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
567         if(update)
568         {
569           impl.mRenderer.Reset();
570         }
571         break;
572       }
573       case Toolkit::TextField::Property::INPUT_UNDERLINE:
574       {
575         const bool update = SetUnderlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
576         if(update)
577         {
578           impl.mRenderer.Reset();
579         }
580         break;
581       }
582       case Toolkit::TextField::Property::SHADOW:
583       {
584         const bool update = SetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
585         if(update)
586         {
587           impl.mRenderer.Reset();
588         }
589         break;
590       }
591       case Toolkit::TextField::Property::INPUT_SHADOW:
592       {
593         const bool update = SetShadowProperties(impl.mController, value, Text::EffectStyle::INPUT);
594         if(update)
595         {
596           impl.mRenderer.Reset();
597         }
598         break;
599       }
600       case Toolkit::TextField::Property::EMBOSS:
601       {
602         const bool update = SetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
603         if(update)
604         {
605           impl.mRenderer.Reset();
606         }
607         break;
608       }
609       case Toolkit::TextField::Property::INPUT_EMBOSS:
610       {
611         const bool update = SetEmbossProperties(impl.mController, value, Text::EffectStyle::INPUT);
612         if(update)
613         {
614           impl.mRenderer.Reset();
615         }
616         break;
617       }
618       case Toolkit::TextField::Property::OUTLINE:
619       {
620         const bool update = SetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
621         if(update)
622         {
623           impl.mRenderer.Reset();
624         }
625         break;
626       }
627       case Toolkit::TextField::Property::INPUT_OUTLINE:
628       {
629         const bool update = SetOutlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
630         if(update)
631         {
632           impl.mRenderer.Reset();
633         }
634         break;
635       }
636       case Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS:
637       {
638         const Property::Map* map = value.GetMap();
639         if(map)
640         {
641           impl.mController->SetHiddenInputOption(*map);
642         }
643         break;
644       }
645       case Toolkit::TextField::Property::PIXEL_SIZE:
646       {
647         const float pixelSize = value.Get<float>();
648         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize);
649
650         if(!Equals(impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE), pixelSize))
651         {
652           impl.mController->SetDefaultFontSize(pixelSize, Text::Controller::PIXEL_SIZE);
653         }
654         break;
655       }
656       case Toolkit::TextField::Property::ENABLE_SELECTION:
657       {
658         const bool enableSelection = value.Get<bool>();
659         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_SELECTION %d\n", impl.mController.Get(), enableSelection);
660         impl.mController->SetSelectionEnabled(enableSelection);
661         break;
662       }
663       case Toolkit::TextField::Property::PLACEHOLDER:
664       {
665         const Property::Map* map = value.GetMap();
666         if(map)
667         {
668           impl.mController->SetPlaceholderProperty(*map);
669         }
670         break;
671       }
672       case Toolkit::TextField::Property::ELLIPSIS:
673       {
674         const bool ellipsis = value.Get<bool>();
675         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis);
676
677         impl.mController->SetTextElideEnabled(ellipsis);
678         break;
679       }
680       case Toolkit::DevelTextField::Property::ENABLE_SHIFT_SELECTION:
681       {
682         const bool shiftSelection = value.Get<bool>();
683         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_SHIFT_SELECTION %d\n", impl.mController.Get(), shiftSelection);
684
685         impl.mController->SetShiftSelectionEnabled(shiftSelection);
686         break;
687       }
688       case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE:
689       {
690         const bool grabHandleEnabled = value.Get<bool>();
691         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE %d\n", impl.mController.Get(), grabHandleEnabled);
692
693         impl.mController->SetGrabHandleEnabled(grabHandleEnabled);
694         break;
695       }
696       case Toolkit::DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
697       {
698         impl.mController->SetMatchLayoutDirection(value.Get<bool>() ? DevelText::MatchLayoutDirection::LOCALE : DevelText::MatchLayoutDirection::CONTENTS);
699         break;
700       }
701       case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
702       {
703         const bool grabHandlePopupEnabled = value.Get<bool>();
704         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE_POPUP %d\n", impl.mController.Get(), grabHandlePopupEnabled);
705
706         impl.mController->SetGrabHandlePopupEnabled(grabHandlePopupEnabled);
707         break;
708       }
709       case Toolkit::DevelTextField::Property::BACKGROUND:
710       {
711         const Vector4 backgroundColor = value.Get<Vector4>();
712         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p BACKGROUND %f,%f,%f,%f\n", impl.mController.Get(), backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a);
713
714         impl.mController->SetBackgroundEnabled(true);
715         impl.mController->SetBackgroundColor(backgroundColor);
716         break;
717       }
718       case Toolkit::DevelTextField::Property::SELECTED_TEXT_START:
719       {
720         uint32_t start = static_cast<uint32_t>(value.Get<int>());
721         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p SELECTED_TEXT_START %d\n", impl.mController.Get(), start);
722         impl.SetTextSelectionRange(&start, nullptr);
723         break;
724       }
725       case Toolkit::DevelTextField::Property::SELECTED_TEXT_END:
726       {
727         uint32_t end = static_cast<uint32_t>(value.Get<int>());
728         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p SELECTED_TEXT_END %d\n", impl.mController.Get(), end);
729         impl.SetTextSelectionRange(nullptr, &end);
730         break;
731       }
732       case Toolkit::DevelTextField::Property::ENABLE_EDITING:
733       {
734         const bool editable = value.Get<bool>();
735         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_EDITING %d\n", impl.mController.Get(), editable);
736         impl.SetEditable(editable);
737         break;
738       }
739       case Toolkit::DevelTextField::Property::FONT_SIZE_SCALE:
740       {
741         const float scale = value.Get<float>();
742         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p FONT_SIZE_SCALE %f\n", impl.mController.Get(), scale);
743
744         if(!Equals(impl.mController->GetFontSizeScale(), scale))
745         {
746           impl.mController->SetFontSizeScale(scale);
747         }
748         break;
749       }
750       case Toolkit::DevelTextField::Property::PRIMARY_CURSOR_POSITION:
751       {
752         uint32_t position = static_cast<uint32_t>(value.Get<int>());
753         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p PRIMARY_CURSOR_POSITION %d\n", impl.mController.Get(), position);
754         if(impl.mController->SetPrimaryCursorPosition(position))
755         {
756           impl.SetKeyInputFocus();
757         }
758         break;
759       }
760       case Toolkit::DevelTextField::Property::GRAB_HANDLE_COLOR:
761       {
762         const Vector4 color = value.Get<Vector4>();
763         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p GRAB_HANDLE_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a);
764
765         impl.mDecorator->SetHandleColor(color);
766         impl.RequestTextRelayout();
767         break;
768       }
769       case Toolkit::DevelTextField::Property::INPUT_FILTER:
770       {
771         const Property::Map* map = value.GetMap();
772         if(map)
773         {
774           impl.mController->SetInputFilterOption(*map);
775         }
776         break;
777       }
778     } // switch
779   }   // textfield
780 }
781
782 Property::Value TextField::GetProperty(BaseObject* object, Property::Index index)
783 {
784   Property::Value value;
785
786   Toolkit::TextField textField = Toolkit::TextField::DownCast(Dali::BaseHandle(object));
787
788   if(textField)
789   {
790     TextField& impl(GetImpl(textField));
791     DALI_ASSERT_DEBUG(impl.mController && "No text contoller");
792     DALI_ASSERT_DEBUG(impl.mDecorator && "No text decorator");
793
794     switch(index)
795     {
796       case Toolkit::DevelTextField::Property::RENDERING_BACKEND:
797       {
798         value = impl.mRenderingBackend;
799         break;
800       }
801       case Toolkit::TextField::Property::TEXT:
802       {
803         std::string text;
804         impl.mController->GetText(text);
805         DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p returning text: %s\n", impl.mController.Get(), text.c_str());
806         value = text;
807         break;
808       }
809       case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
810       {
811         std::string text;
812         impl.mController->GetPlaceholderText(Controller::PLACEHOLDER_TYPE_INACTIVE, text);
813         value = text;
814         break;
815       }
816       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_FOCUSED:
817       {
818         std::string text;
819         impl.mController->GetPlaceholderText(Controller::PLACEHOLDER_TYPE_ACTIVE, text);
820         value = text;
821         break;
822       }
823       case Toolkit::TextField::Property::FONT_FAMILY:
824       {
825         value = impl.mController->GetDefaultFontFamily();
826         break;
827       }
828       case Toolkit::TextField::Property::FONT_STYLE:
829       {
830         GetFontStyleProperty(impl.mController, value, Text::FontStyle::DEFAULT);
831         break;
832       }
833       case Toolkit::TextField::Property::POINT_SIZE:
834       {
835         value = impl.mController->GetDefaultFontSize(Text::Controller::POINT_SIZE);
836         break;
837       }
838       case Toolkit::TextField::Property::MAX_LENGTH:
839       {
840         value = impl.mController->GetMaximumNumberOfCharacters();
841         break;
842       }
843       case Toolkit::TextField::Property::EXCEED_POLICY:
844       {
845         value = impl.mExceedPolicy;
846         break;
847       }
848       case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
849       {
850         const char* name = Text::GetHorizontalAlignmentString(impl.mController->GetHorizontalAlignment());
851
852         if(name)
853         {
854           value = std::string(name);
855         }
856         break;
857       }
858       case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
859       {
860         const char* name = Text::GetVerticalAlignmentString(impl.mController->GetVerticalAlignment());
861
862         if(name)
863         {
864           value = std::string(name);
865         }
866         break;
867       }
868       case Toolkit::TextField::Property::TEXT_COLOR:
869       {
870         value = impl.mController->GetDefaultColor();
871         break;
872       }
873       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
874       {
875         value = impl.mController->GetPlaceholderTextColor();
876         break;
877       }
878       case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
879       {
880         value = impl.mDecorator->GetColor(PRIMARY_CURSOR);
881         break;
882       }
883       case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
884       {
885         value = impl.mDecorator->GetColor(SECONDARY_CURSOR);
886         break;
887       }
888       case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
889       {
890         value = impl.mController->GetEnableCursorBlink();
891         break;
892       }
893       case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
894       {
895         value = impl.mDecorator->GetCursorBlinkInterval();
896         break;
897       }
898       case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
899       {
900         value = impl.mDecorator->GetCursorBlinkDuration();
901         break;
902       }
903       case Toolkit::TextField::Property::CURSOR_WIDTH:
904       {
905         value = impl.mDecorator->GetCursorWidth();
906         break;
907       }
908       case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
909       {
910         value = impl.mDecorator->GetHandleImage(GRAB_HANDLE, HANDLE_IMAGE_RELEASED);
911         break;
912       }
913       case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
914       {
915         value = impl.mDecorator->GetHandleImage(GRAB_HANDLE, HANDLE_IMAGE_PRESSED);
916         break;
917       }
918       case Toolkit::TextField::Property::SCROLL_THRESHOLD:
919       {
920         value = impl.mDecorator->GetScrollThreshold();
921         break;
922       }
923       case Toolkit::TextField::Property::SCROLL_SPEED:
924       {
925         value = impl.mDecorator->GetScrollSpeed();
926         break;
927       }
928       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
929       {
930         impl.GetHandleImagePropertyValue(value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED);
931         break;
932       }
933       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
934       {
935         impl.GetHandleImagePropertyValue(value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED);
936         break;
937       }
938       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
939       {
940         impl.GetHandleImagePropertyValue(value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED);
941         break;
942       }
943       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
944       {
945         impl.GetHandleImagePropertyValue(value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED);
946         break;
947       }
948       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
949       {
950         impl.GetHandleImagePropertyValue(value, LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED);
951         break;
952       }
953       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
954       {
955         impl.GetHandleImagePropertyValue(value, RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED);
956         break;
957       }
958       case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
959       {
960         value = impl.mDecorator->GetHighlightColor();
961         break;
962       }
963       case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
964       {
965         Rect<int> boundingBox;
966         impl.mDecorator->GetBoundingBox(boundingBox);
967         value = boundingBox;
968         break;
969       }
970       case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
971       {
972         Property::Map map;
973         impl.mInputMethodOptions.RetrieveProperty(map);
974         value = map;
975         break;
976       }
977       case Toolkit::TextField::Property::INPUT_COLOR:
978       {
979         value = impl.mController->GetInputColor();
980         break;
981       }
982       case Toolkit::TextField::Property::ENABLE_MARKUP:
983       {
984         value = impl.mController->IsMarkupProcessorEnabled();
985         break;
986       }
987       case Toolkit::TextField::Property::INPUT_FONT_FAMILY:
988       {
989         value = impl.mController->GetInputFontFamily();
990         break;
991       }
992       case Toolkit::TextField::Property::INPUT_FONT_STYLE:
993       {
994         GetFontStyleProperty(impl.mController, value, Text::FontStyle::INPUT);
995         break;
996       }
997       case Toolkit::TextField::Property::INPUT_POINT_SIZE:
998       {
999         value = impl.mController->GetInputFontPointSize();
1000         break;
1001       }
1002       case Toolkit::TextField::Property::UNDERLINE:
1003       {
1004         GetUnderlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
1005         break;
1006       }
1007       case Toolkit::TextField::Property::INPUT_UNDERLINE:
1008       {
1009         GetUnderlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
1010         break;
1011       }
1012       case Toolkit::TextField::Property::SHADOW:
1013       {
1014         GetShadowProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
1015         break;
1016       }
1017       case Toolkit::TextField::Property::INPUT_SHADOW:
1018       {
1019         GetShadowProperties(impl.mController, value, Text::EffectStyle::INPUT);
1020         break;
1021       }
1022       case Toolkit::TextField::Property::EMBOSS:
1023       {
1024         GetEmbossProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
1025         break;
1026       }
1027       case Toolkit::TextField::Property::INPUT_EMBOSS:
1028       {
1029         GetEmbossProperties(impl.mController, value, Text::EffectStyle::INPUT);
1030         break;
1031       }
1032       case Toolkit::TextField::Property::OUTLINE:
1033       {
1034         GetOutlineProperties(impl.mController, value, Text::EffectStyle::DEFAULT);
1035         break;
1036       }
1037       case Toolkit::TextField::Property::INPUT_OUTLINE:
1038       {
1039         GetOutlineProperties(impl.mController, value, Text::EffectStyle::INPUT);
1040         break;
1041       }
1042       case Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS:
1043       {
1044         Property::Map map;
1045         impl.mController->GetHiddenInputOption(map);
1046         value = map;
1047         break;
1048       }
1049       case Toolkit::TextField::Property::PIXEL_SIZE:
1050       {
1051         value = impl.mController->GetDefaultFontSize(Text::Controller::PIXEL_SIZE);
1052         break;
1053       }
1054       case Toolkit::TextField::Property::ENABLE_SELECTION:
1055       {
1056         value = impl.mController->IsSelectionEnabled();
1057         break;
1058       }
1059       case Toolkit::TextField::Property::PLACEHOLDER:
1060       {
1061         Property::Map map;
1062         impl.mController->GetPlaceholderProperty(map);
1063         value = map;
1064         break;
1065       }
1066       case Toolkit::TextField::Property::ELLIPSIS:
1067       {
1068         value = impl.mController->IsTextElideEnabled();
1069         break;
1070       }
1071       case Toolkit::DevelTextField::Property::ENABLE_SHIFT_SELECTION:
1072       {
1073         value = impl.mController->IsShiftSelectionEnabled();
1074         break;
1075       }
1076       case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE:
1077       {
1078         value = impl.mController->IsGrabHandleEnabled();
1079         break;
1080       }
1081       case Toolkit::DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
1082       {
1083         value = impl.mController->GetMatchLayoutDirection() != DevelText::MatchLayoutDirection::CONTENTS;
1084         break;
1085       }
1086       case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
1087       {
1088         value = impl.mController->IsGrabHandlePopupEnabled();
1089         break;
1090       }
1091       case Toolkit::DevelTextField::Property::BACKGROUND:
1092       {
1093         value = impl.mController->GetBackgroundColor();
1094         break;
1095       }
1096       case Toolkit::DevelTextField::Property::SELECTED_TEXT:
1097       {
1098         value = impl.mController->GetSelectedText();
1099         break;
1100       }
1101       case Toolkit::DevelTextField::Property::SELECTED_TEXT_START:
1102       {
1103         Uint32Pair range = impl.GetTextSelectionRange();
1104         value            = static_cast<int>(range.first);
1105         break;
1106       }
1107       case Toolkit::DevelTextField::Property::SELECTED_TEXT_END:
1108       {
1109         Uint32Pair range = impl.GetTextSelectionRange();
1110         value            = static_cast<int>(range.second);
1111         break;
1112       }
1113       case Toolkit::DevelTextField::Property::ENABLE_EDITING:
1114       {
1115         value = impl.IsEditable();
1116         break;
1117       }
1118       case Toolkit::DevelTextField::Property::FONT_SIZE_SCALE:
1119       {
1120         value = impl.mController->GetFontSizeScale();
1121         break;
1122       }
1123       case Toolkit::DevelTextField::Property::PRIMARY_CURSOR_POSITION:
1124       {
1125         value = static_cast<int>(impl.mController->GetPrimaryCursorPosition());
1126         break;
1127       }
1128       case Toolkit::DevelTextField::Property::GRAB_HANDLE_COLOR:
1129       {
1130         value = impl.mDecorator->GetHandleColor();
1131         break;
1132       }
1133       case Toolkit::DevelTextField::Property::INPUT_FILTER:
1134       {
1135         Property::Map map;
1136         impl.mController->GetInputFilterOption(map);
1137         value = map;
1138         break;
1139       }
1140     } //switch
1141   }
1142
1143   return value;
1144 }
1145
1146 void TextField::SelectWholeText()
1147 {
1148   if(mController && mController->IsShowingRealText())
1149   {
1150     mController->SelectWholeText();
1151     SetKeyInputFocus();
1152   }
1153 }
1154
1155 void TextField::SelectNone()
1156 {
1157   if(mController && mController->IsShowingRealText())
1158   {
1159     mController->SelectNone();
1160   }
1161 }
1162
1163 string TextField::GetSelectedText() const
1164 {
1165   string selectedText = "";
1166   if(mController && mController->IsShowingRealText())
1167   {
1168     selectedText = mController->GetSelectedText();
1169   }
1170   return selectedText;
1171 }
1172
1173 void TextField::SetTextSelectionRange(const uint32_t* start, const uint32_t* end)
1174 {
1175   if(mController && mController->IsShowingRealText())
1176   {
1177     mController->SetTextSelectionRange(start, end);
1178     SetKeyInputFocus();
1179   }
1180 }
1181
1182 Uint32Pair TextField::GetTextSelectionRange() const
1183 {
1184   Uint32Pair range;
1185   if(mController && mController->IsShowingRealText())
1186   {
1187     range = mController->GetTextSelectionRange();
1188   }
1189   return range;
1190 }
1191
1192 InputMethodContext TextField::GetInputMethodContext()
1193 {
1194   return mInputMethodContext;
1195 }
1196
1197 bool TextField::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
1198 {
1199   Dali::BaseHandle handle(object);
1200
1201   bool               connected(true);
1202   Toolkit::TextField field = Toolkit::TextField::DownCast(handle);
1203
1204   if(0 == strcmp(signalName.c_str(), SIGNAL_TEXT_CHANGED))
1205   {
1206     field.TextChangedSignal().Connect(tracker, functor);
1207   }
1208   else if(0 == strcmp(signalName.c_str(), SIGNAL_MAX_LENGTH_REACHED))
1209   {
1210     field.MaxLengthReachedSignal().Connect(tracker, functor);
1211   }
1212   else if(0 == strcmp(signalName.c_str(), SIGNAL_INPUT_STYLE_CHANGED))
1213   {
1214     field.InputStyleChangedSignal().Connect(tracker, functor);
1215   }
1216   else if(0 == strcmp(signalName.c_str(), SIGNAL_ANCHOR_CLICKED))
1217   {
1218     if(field)
1219     {
1220       Internal::TextField& fieldImpl(GetImpl(field));
1221       fieldImpl.AnchorClickedSignal().Connect(tracker, functor);
1222     }
1223   }
1224   else if(0 == strcmp(signalName.c_str(), SIGNAL_INPUT_FILTERED))
1225   {
1226     if(field)
1227     {
1228       Internal::TextField& fieldImpl(GetImpl(field));
1229       fieldImpl.InputFilteredSignal().Connect(tracker, functor);
1230     }
1231   }
1232   else
1233   {
1234     // signalName does not match any signal
1235     connected = false;
1236   }
1237
1238   return connected;
1239 }
1240
1241 Toolkit::TextField::TextChangedSignalType& TextField::TextChangedSignal()
1242 {
1243   return mTextChangedSignal;
1244 }
1245
1246 Toolkit::TextField::MaxLengthReachedSignalType& TextField::MaxLengthReachedSignal()
1247 {
1248   return mMaxLengthReachedSignal;
1249 }
1250
1251 Toolkit::TextField::InputStyleChangedSignalType& TextField::InputStyleChangedSignal()
1252 {
1253   return mInputStyleChangedSignal;
1254 }
1255
1256 DevelTextField::AnchorClickedSignalType& TextField::AnchorClickedSignal()
1257 {
1258   return mAnchorClickedSignal;
1259 }
1260
1261 DevelTextField::InputFilteredSignalType& TextField::InputFilteredSignal()
1262 {
1263   return mInputFilteredSignal;
1264 }
1265
1266 void TextField::OnInitialize()
1267 {
1268   Actor self = Self();
1269
1270   mController = Text::Controller::New(this, this, this, this);
1271
1272   // When using the vector-based rendering, the size of the GLyphs are different
1273   TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
1274   mController->SetGlyphType(glyphType);
1275
1276   mDecorator = Text::Decorator::New(*mController,
1277                                     *mController);
1278
1279   mInputMethodContext = InputMethodContext::New(self);
1280
1281   mController->GetLayoutEngine().SetLayout(Layout::Engine::SINGLE_LINE_BOX);
1282
1283   // Enables the text input.
1284   mController->EnableTextInput(mDecorator, mInputMethodContext);
1285
1286   // Enables the horizontal scrolling after the text input has been enabled.
1287   mController->SetHorizontalScrollEnabled(true);
1288
1289   // Disables the vertical scrolling.
1290   mController->SetVerticalScrollEnabled(false);
1291
1292   // Disable the smooth handle panning.
1293   mController->SetSmoothHandlePanEnabled(false);
1294
1295   mController->SetNoTextDoubleTapAction(Controller::NoTextTap::HIGHLIGHT);
1296   mController->SetNoTextLongPressAction(Controller::NoTextTap::HIGHLIGHT);
1297
1298   // Sets layoutDirection value
1299   Dali::Stage                 stage           = Dali::Stage::GetCurrent();
1300   Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(stage.GetRootLayer().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
1301   mController->SetLayoutDirection(layoutDirection);
1302
1303   self.LayoutDirectionChangedSignal().Connect(this, &TextField::OnLayoutDirectionChanged);
1304
1305   // Forward input events to controller
1306   EnableGestureDetection(static_cast<GestureType::Value>(GestureType::TAP | GestureType::PAN | GestureType::LONG_PRESS));
1307   GetTapGestureDetector().SetMaximumTapsRequired(2);
1308
1309   self.TouchedSignal().Connect(this, &TextField::OnTouched);
1310
1311   // Set BoundingBox to stage size if not already set.
1312   Rect<int> boundingBox;
1313   mDecorator->GetBoundingBox(boundingBox);
1314
1315   if(boundingBox.IsEmpty())
1316   {
1317     Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
1318     mDecorator->SetBoundingBox(Rect<int>(0.0f, 0.0f, stageSize.width, stageSize.height));
1319   }
1320
1321   // Flip vertically the 'left' selection handle
1322   mDecorator->FlipHandleVertically(LEFT_SELECTION_HANDLE, true);
1323
1324   // Fill-parent area by default
1325   self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH);
1326   self.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT);
1327   self.OnSceneSignal().Connect(this, &TextField::OnSceneConnect);
1328
1329   //Enable highightability
1330   self.SetProperty(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE, true);
1331
1332   DevelControl::SetInputMethodContext(*this, mInputMethodContext);
1333
1334   if(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy)
1335   {
1336     EnableClipping();
1337   }
1338
1339   DevelControl::SetAccessibilityConstructor(self, [](Dali::Actor actor) {
1340     return std::unique_ptr<Dali::Accessibility::Accessible>(
1341       new AccessibleImpl(actor, Dali::Accessibility::Role::ENTRY));
1342   });
1343 }
1344
1345 void TextField::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
1346 {
1347   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::OnStyleChange\n");
1348
1349   switch(change)
1350   {
1351     case StyleChange::DEFAULT_FONT_CHANGE:
1352     {
1353       DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::OnStyleChange DEFAULT_FONT_CHANGE\n");
1354       const std::string& newFont = GetImpl(styleManager).GetDefaultFontFamily();
1355       // Property system did not set the font so should update it.
1356       mController->UpdateAfterFontChange(newFont);
1357       RelayoutRequest();
1358       break;
1359     }
1360
1361     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
1362     {
1363       GetImpl(styleManager).ApplyThemeStyle(Toolkit::Control(GetOwner()));
1364       RelayoutRequest();
1365       break;
1366     }
1367     case StyleChange::THEME_CHANGE:
1368     {
1369       // Nothing to do, let control base class handle this
1370       break;
1371     }
1372   }
1373
1374   // Up call to Control
1375   Control::OnStyleChange(styleManager, change);
1376 }
1377
1378 Vector3 TextField::GetNaturalSize()
1379 {
1380   Extents padding;
1381   padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
1382
1383   Vector3 naturalSize = mController->GetNaturalSize();
1384   naturalSize.width += (padding.start + padding.end);
1385   naturalSize.height += (padding.top + padding.bottom);
1386
1387   return naturalSize;
1388 }
1389
1390 float TextField::GetHeightForWidth(float width)
1391 {
1392   Extents padding;
1393   padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
1394   return mController->GetHeightForWidth(width) + padding.top + padding.bottom;
1395 }
1396
1397 void TextField::ResizeActor(Actor& actor, const Vector2& size)
1398 {
1399   if(actor.GetProperty<Vector3>(Dali::Actor::Property::SIZE).GetVectorXY() != size)
1400   {
1401     actor.SetProperty(Actor::Property::SIZE, size);
1402   }
1403 }
1404
1405 void TextField::OnRelayout(const Vector2& size, RelayoutContainer& container)
1406 {
1407   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField OnRelayout\n");
1408
1409   Actor self = Self();
1410
1411   Extents padding;
1412   padding = self.GetProperty<Extents>(Toolkit::Control::Property::PADDING);
1413
1414   Vector2 contentSize(size.x - (padding.start + padding.end), size.y - (padding.top + padding.bottom));
1415
1416   // Support Right-To-Left of padding
1417   Dali::LayoutDirection::Type layoutDirection = mController->GetLayoutDirection(self);
1418
1419   if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
1420   {
1421     std::swap(padding.start, padding.end);
1422   }
1423
1424   if(mStencil)
1425   {
1426     mStencil.SetProperty(Actor::Property::POSITION, Vector2(padding.start, padding.top));
1427     ResizeActor(mStencil, contentSize);
1428   }
1429   if(mActiveLayer)
1430   {
1431     mActiveLayer.SetProperty(Actor::Property::POSITION, Vector2(padding.start, padding.top));
1432     ResizeActor(mActiveLayer, contentSize);
1433   }
1434
1435   // If there is text changed, callback is called.
1436   if(mTextChanged)
1437   {
1438     EmitTextChangedSignal();
1439   }
1440
1441   const Text::Controller::UpdateTextType updateTextType = mController->Relayout(contentSize, layoutDirection);
1442
1443   if((Text::Controller::NONE_UPDATED != updateTextType) ||
1444      !mRenderer)
1445   {
1446     DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::OnRelayout %p Displaying new contents\n", mController.Get());
1447
1448     if(mDecorator &&
1449        (Text::Controller::NONE_UPDATED != (Text::Controller::DECORATOR_UPDATED & updateTextType)))
1450     {
1451       mDecorator->Relayout(contentSize);
1452     }
1453
1454     if(!mRenderer)
1455     {
1456       mRenderer = Backend::Get().NewRenderer(mRenderingBackend);
1457     }
1458
1459     RenderText(updateTextType);
1460   }
1461
1462   // The text-field emits signals when the input style changes. These changes of style are
1463   // detected during the relayout process (size negotiation), i.e after the cursor has been moved. Signals
1464   // can't be emitted during the size negotiation as the callbacks may update the UI.
1465   // The text-field adds an idle callback to the adaptor to emit the signals after the size negotiation.
1466   if(!mController->IsInputStyleChangedSignalsQueueEmpty())
1467   {
1468     if(Adaptor::IsAvailable())
1469     {
1470       Adaptor& adaptor = Adaptor::Get();
1471
1472       if(NULL == mIdleCallback)
1473       {
1474         // @note: The callback manager takes the ownership of the callback object.
1475         mIdleCallback = MakeCallback(this, &TextField::OnIdleSignal);
1476         adaptor.AddIdle(mIdleCallback, false);
1477       }
1478     }
1479   }
1480 }
1481
1482 Text::ControllerPtr TextField::GetTextController()
1483 {
1484   return mController;
1485 }
1486
1487 void TextField::RenderText(Text::Controller::UpdateTextType updateTextType)
1488 {
1489   Actor renderableActor;
1490
1491   if(Text::Controller::NONE_UPDATED != (Text::Controller::MODEL_UPDATED & updateTextType))
1492   {
1493     if(mRenderer)
1494     {
1495       Dali::Toolkit::TextField handle = Dali::Toolkit::TextField(GetOwner());
1496
1497       renderableActor = mRenderer->Render(mController->GetView(),
1498                                           handle,
1499                                           Property::INVALID_INDEX, // Animatable property not supported
1500                                           mAlignmentOffset,
1501                                           DepthIndex::CONTENT);
1502     }
1503
1504     if(renderableActor != mRenderableActor)
1505     {
1506       UnparentAndReset(mBackgroundActor);
1507       UnparentAndReset(mRenderableActor);
1508       mRenderableActor = renderableActor;
1509
1510       if(mRenderableActor)
1511       {
1512         mBackgroundActor = mController->CreateBackgroundActor();
1513       }
1514     }
1515   }
1516
1517   if(mRenderableActor)
1518   {
1519     const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition();
1520
1521     float renderableActorPositionX, renderableActorPositionY;
1522
1523     if(mStencil)
1524     {
1525       renderableActorPositionX = scrollOffset.x + mAlignmentOffset;
1526       renderableActorPositionY = scrollOffset.y;
1527     }
1528     else
1529     {
1530       Extents padding;
1531       padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
1532
1533       // Support Right-To-Left of padding
1534       Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(Self().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
1535       if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
1536       {
1537         std::swap(padding.start, padding.end);
1538       }
1539
1540       renderableActorPositionX = scrollOffset.x + mAlignmentOffset + padding.start;
1541       renderableActorPositionY = scrollOffset.y + padding.top;
1542     }
1543
1544     mRenderableActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY));
1545
1546     // Make sure the actors are parented correctly with/without clipping
1547     Actor self = mStencil ? mStencil : Self();
1548
1549     Actor highlightActor;
1550
1551     for(std::vector<Actor>::iterator it    = mClippingDecorationActors.begin(),
1552                                      endIt = mClippingDecorationActors.end();
1553         it != endIt;
1554         ++it)
1555     {
1556       self.Add(*it);
1557       it->LowerToBottom();
1558
1559       if(it->GetProperty<std::string>(Dali::Actor::Property::NAME) == "HighlightActor")
1560       {
1561         highlightActor = *it;
1562       }
1563     }
1564     mClippingDecorationActors.clear();
1565
1566     self.Add(mRenderableActor);
1567
1568     if(mBackgroundActor)
1569     {
1570       if(mDecorator && mDecorator->IsHighlightVisible())
1571       {
1572         self.Add(mBackgroundActor);
1573         mBackgroundActor.SetProperty(Actor::Property::POSITION, Vector2(renderableActorPositionX, renderableActorPositionY)); // In text field's coords.
1574         mBackgroundActor.LowerBelow(highlightActor);
1575       }
1576       else
1577       {
1578         mRenderableActor.Add(mBackgroundActor);
1579         mBackgroundActor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f)); // In renderable actor's coords.
1580         mBackgroundActor.LowerToBottom();
1581       }
1582     }
1583   }
1584 }
1585
1586 void TextField::OnKeyInputFocusGained()
1587 {
1588   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::OnKeyInputFocusGained %p\n", mController.Get());
1589   if(mInputMethodContext && IsEditable())
1590   {
1591     // All input panel properties, such as layout, return key type, and input hint, should be set before input panel activates (or shows).
1592     mInputMethodContext.ApplyOptions(mInputMethodOptions);
1593     mInputMethodContext.NotifyTextInputMultiLine(false);
1594
1595     mInputMethodContext.StatusChangedSignal().Connect(this, &TextField::KeyboardStatusChanged);
1596
1597     mInputMethodContext.EventReceivedSignal().Connect(this, &TextField::OnInputMethodContextEvent);
1598
1599     // Notify that the text editing start.
1600     mInputMethodContext.Activate();
1601
1602     // When window gain lost focus, the inputMethodContext is deactivated. Thus when window gain focus again, the inputMethodContext must be activated.
1603     mInputMethodContext.SetRestoreAfterFocusLost(true);
1604   }
1605   ClipboardEventNotifier notifier(ClipboardEventNotifier::Get());
1606
1607   if(notifier)
1608   {
1609     notifier.ContentSelectedSignal().Connect(this, &TextField::OnClipboardTextSelected);
1610   }
1611
1612   mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event
1613
1614   EmitKeyInputFocusSignal(true); // Calls back into the Control hence done last.
1615 }
1616
1617 void TextField::OnKeyInputFocusLost()
1618 {
1619   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField:OnKeyInputFocusLost %p\n", mController.Get());
1620   if(mInputMethodContext)
1621   {
1622     mInputMethodContext.StatusChangedSignal().Disconnect(this, &TextField::KeyboardStatusChanged);
1623     // The text editing is finished. Therefore the inputMethodContext don't have restore activation.
1624     mInputMethodContext.SetRestoreAfterFocusLost(false);
1625
1626     // Notify that the text editing finish.
1627     mInputMethodContext.Deactivate();
1628
1629     mInputMethodContext.EventReceivedSignal().Disconnect(this, &TextField::OnInputMethodContextEvent);
1630   }
1631   ClipboardEventNotifier notifier(ClipboardEventNotifier::Get());
1632
1633   if(notifier)
1634   {
1635     notifier.ContentSelectedSignal().Disconnect(this, &TextField::OnClipboardTextSelected);
1636   }
1637
1638   mController->KeyboardFocusLostEvent();
1639
1640   EmitKeyInputFocusSignal(false); // Calls back into the Control hence done last.
1641 }
1642
1643 bool TextField::OnAccessibilityActivated()
1644 {
1645   SetKeyInputFocus();
1646   return true;
1647 }
1648
1649 void TextField::OnTap(const TapGesture& gesture)
1650 {
1651   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::OnTap %p\n", mController.Get());
1652   if(mInputMethodContext && IsEditable())
1653   {
1654     mInputMethodContext.Activate();
1655   }
1656   // Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures
1657   Extents padding;
1658   padding                   = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
1659   const Vector2& localPoint = gesture.GetLocalPoint();
1660   mController->TapEvent(gesture.GetNumberOfTaps(), localPoint.x - padding.start, localPoint.y - padding.top);
1661   mController->AnchorEvent(localPoint.x - padding.start, localPoint.y - padding.top);
1662
1663   SetKeyInputFocus();
1664 }
1665
1666 void TextField::OnPan(const PanGesture& gesture)
1667 {
1668   mController->PanEvent(gesture.GetState(), gesture.GetDisplacement());
1669 }
1670
1671 void TextField::OnLongPress(const LongPressGesture& gesture)
1672 {
1673   if(mInputMethodContext && IsEditable())
1674   {
1675     mInputMethodContext.Activate();
1676   }
1677   Extents padding;
1678   padding                   = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
1679   const Vector2& localPoint = gesture.GetLocalPoint();
1680   mController->LongPressEvent(gesture.GetState(), localPoint.x - padding.start, localPoint.y - padding.top);
1681
1682   SetKeyInputFocus();
1683 }
1684
1685 bool TextField::OnKeyEvent(const KeyEvent& event)
1686 {
1687   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.GetKeyCode());
1688
1689   if(Dali::DALI_KEY_ESCAPE == event.GetKeyCode() && mController->ShouldClearFocusOnEscape())
1690   {
1691     // Make sure ClearKeyInputFocus when only key is up
1692     if(event.GetState() == KeyEvent::UP)
1693     {
1694       ClearKeyInputFocus();
1695     }
1696
1697     return true;
1698   }
1699   else if(Dali::DevelKey::DALI_KEY_RETURN == event.GetKeyCode())
1700   {
1701     // Do nothing when enter is comming.
1702     return false;
1703   }
1704
1705   return mController->KeyEvent(event);
1706 }
1707
1708 void TextField::RequestTextRelayout()
1709 {
1710   RelayoutRequest();
1711 }
1712
1713 bool TextField::IsEditable() const
1714 {
1715   return mController->IsEditable();
1716 }
1717
1718 void TextField::SetEditable(bool editable)
1719 {
1720   mController->SetEditable(editable);
1721   if(mInputMethodContext && !editable)
1722   {
1723     mInputMethodContext.Deactivate();
1724   }
1725 }
1726
1727 void TextField::TextInserted(unsigned int position, unsigned int length, const std::string& content)
1728 {
1729   if(Accessibility::IsUp())
1730   {
1731     Control::Impl::GetAccessibilityObject(Self())->EmitTextInserted(position, length, content);
1732   }
1733 }
1734
1735 void TextField::TextDeleted(unsigned int position, unsigned int length, const std::string& content)
1736 {
1737   if(Accessibility::IsUp())
1738   {
1739     Control::Impl::GetAccessibilityObject(Self())->EmitTextDeleted(position, length, content);
1740   }
1741 }
1742
1743 void TextField::CursorMoved(unsigned int position)
1744 {
1745   if(Accessibility::IsUp())
1746   {
1747     Control::Impl::GetAccessibilityObject(Self())->EmitTextCursorMoved(position);
1748   }
1749 }
1750
1751 void TextField::TextChanged(bool immediate)
1752 {
1753   if(immediate) // Emits TextChangedSignal immediately
1754   {
1755     EmitTextChangedSignal();
1756   }
1757   else
1758   {
1759     mTextChanged = true;
1760   }
1761 }
1762
1763 void TextField::EmitTextChangedSignal()
1764 {
1765   Dali::Toolkit::TextField handle(GetOwner());
1766   mTextChangedSignal.Emit(handle);
1767   mTextChanged = false;
1768 }
1769
1770 void TextField::MaxLengthReached()
1771 {
1772   Dali::Toolkit::TextField handle(GetOwner());
1773   mMaxLengthReachedSignal.Emit(handle);
1774 }
1775
1776 void TextField::InputStyleChanged(Text::InputStyle::Mask inputStyleMask)
1777 {
1778   Dali::Toolkit::TextField handle(GetOwner());
1779
1780   Toolkit::TextField::InputStyle::Mask fieldInputStyleMask = Toolkit::TextField::InputStyle::NONE;
1781
1782   if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_COLOR))
1783   {
1784     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::COLOR);
1785   }
1786   if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_FAMILY))
1787   {
1788     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_FAMILY);
1789   }
1790   if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_POINT_SIZE))
1791   {
1792     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::POINT_SIZE);
1793   }
1794   if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WEIGHT))
1795   {
1796     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE);
1797   }
1798   if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_WIDTH))
1799   {
1800     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE);
1801   }
1802   if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_FONT_SLANT))
1803   {
1804     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE);
1805   }
1806   if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_UNDERLINE))
1807   {
1808     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::UNDERLINE);
1809   }
1810   if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_SHADOW))
1811   {
1812     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::SHADOW);
1813   }
1814   if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_EMBOSS))
1815   {
1816     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::EMBOSS);
1817   }
1818   if(InputStyle::NONE != static_cast<InputStyle::Mask>(inputStyleMask & InputStyle::INPUT_OUTLINE))
1819   {
1820     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>(fieldInputStyleMask | Toolkit::TextField::InputStyle::OUTLINE);
1821   }
1822
1823   mInputStyleChangedSignal.Emit(handle, fieldInputStyleMask);
1824 }
1825
1826 void TextField::AnchorClicked(const std::string& href)
1827 {
1828   Dali::Toolkit::TextField handle(GetOwner());
1829   mAnchorClickedSignal.Emit(handle, href.c_str(), href.length());
1830 }
1831
1832 void TextField::InputFiltered(Toolkit::InputFilter::Property::Type type)
1833 {
1834   Dali::Toolkit::TextField handle(GetOwner());
1835   mInputFilteredSignal.Emit(handle, type);
1836 }
1837
1838 void TextField::AddDecoration(Actor& actor, bool needsClipping)
1839 {
1840   if(actor)
1841   {
1842     if(needsClipping)
1843     {
1844       mClippingDecorationActors.push_back(actor);
1845     }
1846     else
1847     {
1848       actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
1849       actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1850       Self().Add(actor);
1851       mActiveLayer = actor;
1852     }
1853   }
1854 }
1855
1856 void TextField::GetControlBackgroundColor(Vector4& color) const
1857 {
1858   Property::Value propValue = Self().GetProperty(Toolkit::Control::Property::BACKGROUND);
1859   Property::Map*  resultMap = propValue.GetMap();
1860
1861   Property::Value* colorValue = nullptr;
1862   if(resultMap && (colorValue = resultMap->Find(ColorVisual::Property::MIX_COLOR)))
1863   {
1864     colorValue->Get(color);
1865   }
1866 }
1867
1868 void TextField::OnSceneConnect(Dali::Actor actor)
1869 {
1870   if(mHasBeenStaged)
1871   {
1872     RenderText(static_cast<Text::Controller::UpdateTextType>(Text::Controller::MODEL_UPDATED | Text::Controller::DECORATOR_UPDATED));
1873   }
1874   else
1875   {
1876     mHasBeenStaged = true;
1877   }
1878 }
1879
1880 InputMethodContext::CallbackData TextField::OnInputMethodContextEvent(Dali::InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
1881 {
1882   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::OnInputMethodContextEvent %p eventName %d\n", mController.Get(), inputMethodContextEvent.eventName);
1883   return mController->OnInputMethodContextEvent(inputMethodContext, inputMethodContextEvent);
1884 }
1885
1886 void TextField::GetHandleImagePropertyValue(Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType)
1887 {
1888   if(mDecorator)
1889   {
1890     Property::Map map;
1891     map[IMAGE_MAP_FILENAME_STRING] = mDecorator->GetHandleImage(handleType, handleImageType);
1892     value                          = map;
1893   }
1894 }
1895
1896 void TextField::EnableClipping()
1897 {
1898   if(!mStencil)
1899   {
1900     // Creates an extra control to be used as stencil buffer.
1901     mStencil = Control::New();
1902     mStencil.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
1903     mStencil.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
1904
1905     // Creates a background visual. Even if the color is transparent it updates the stencil.
1906     mStencil.SetProperty(Toolkit::Control::Property::BACKGROUND,
1907                          Property::Map().Add(Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR).Add(ColorVisual::Property::MIX_COLOR, Color::TRANSPARENT));
1908
1909     // Enable the clipping property.
1910     mStencil.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX);
1911     mStencil.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
1912
1913     Self().Add(mStencil);
1914   }
1915 }
1916
1917 void TextField::OnClipboardTextSelected(ClipboardEventNotifier& clipboard)
1918 {
1919   mController->PasteClipboardItemEvent();
1920 }
1921
1922 void TextField::KeyboardStatusChanged(bool keyboardShown)
1923 {
1924   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextField::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown);
1925
1926   // Just hide the grab handle when keyboard is hidden.
1927   if(!keyboardShown)
1928   {
1929     mController->KeyboardFocusLostEvent();
1930   }
1931   else
1932   {
1933     mController->KeyboardFocusGainEvent(); // Initially called by OnKeyInputFocusGained
1934   }
1935 }
1936
1937 void TextField::OnSceneConnection(int depth)
1938 {
1939   // Sets the depth to the visuals inside the text's decorator.
1940   mDecorator->SetTextDepth(depth);
1941
1942   // The depth of the text renderer is set in the RenderText() called from OnRelayout().
1943
1944   // Call the Control::OnSceneConnection() to set the depth of the background.
1945   Control::OnSceneConnection(depth);
1946 }
1947
1948 bool TextField::OnTouched(Actor actor, const TouchEvent& touch)
1949 {
1950   return false;
1951 }
1952
1953 void TextField::OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type)
1954 {
1955   mController->ChangedLayoutDirection();
1956 }
1957
1958 void TextField::OnIdleSignal()
1959 {
1960   // Emits the change of input style signals.
1961   mController->ProcessInputStyleChangedSignals();
1962
1963   // Set the pointer to null as the callback manager deletes the callback after execute it.
1964   mIdleCallback = NULL;
1965 }
1966
1967 TextField::TextField()
1968 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
1969   mIdleCallback(NULL),
1970   mAlignmentOffset(0.f),
1971   mRenderingBackend(DEFAULT_RENDERING_BACKEND),
1972   mExceedPolicy(Dali::Toolkit::TextField::EXCEED_POLICY_CLIP),
1973   mHasBeenStaged(false),
1974   mTextChanged(false)
1975 {
1976 }
1977
1978 TextField::~TextField()
1979 {
1980   UnparentAndReset(mStencil);
1981
1982   if((NULL != mIdleCallback) && Adaptor::IsAvailable())
1983   {
1984     Adaptor::Get().RemoveIdle(mIdleCallback);
1985   }
1986 }
1987
1988 std::string TextField::AccessibleImpl::GetName()
1989 {
1990   auto self = Toolkit::TextField::DownCast(Self());
1991   return self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
1992 }
1993
1994 std::string TextField::AccessibleImpl::GetText(size_t startOffset, size_t endOffset)
1995 {
1996   if(endOffset <= startOffset)
1997   {
1998     return {};
1999   }
2000
2001   auto self = Toolkit::TextField::DownCast(Self());
2002   auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
2003
2004   if(startOffset > text.size() || endOffset > text.size())
2005   {
2006     return {};
2007   }
2008
2009   return text.substr(startOffset, endOffset - startOffset);
2010 }
2011
2012 size_t TextField::AccessibleImpl::GetCharacterCount()
2013 {
2014   auto self = Toolkit::TextField::DownCast(Self());
2015   auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
2016
2017   return text.size();
2018 }
2019
2020 size_t TextField::AccessibleImpl::GetCursorOffset()
2021 {
2022   auto self = Toolkit::TextField::DownCast(Self());
2023   return Dali::Toolkit::GetImpl(self).GetTextController()->GetCursorPosition();
2024 }
2025
2026 bool TextField::AccessibleImpl::SetCursorOffset(size_t offset)
2027 {
2028   auto self = Toolkit::TextField::DownCast(Self());
2029   auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
2030   if(offset > text.size())
2031   {
2032     return false;
2033   }
2034
2035   auto& selfImpl = Dali::Toolkit::GetImpl(self);
2036   selfImpl.GetTextController()->ResetCursorPosition(offset);
2037   selfImpl.RequestTextRelayout();
2038
2039   return true;
2040 }
2041
2042 Dali::Accessibility::Range TextField::AccessibleImpl::GetTextAtOffset(
2043   size_t offset, Dali::Accessibility::TextBoundary boundary)
2044 {
2045   auto self = Toolkit::TextField::DownCast(Self());
2046   auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
2047   auto textSize = text.size();
2048
2049   auto range = Dali::Accessibility::Range{};
2050
2051   switch(boundary)
2052   {
2053     case Dali::Accessibility::TextBoundary::CHARACTER:
2054     {
2055       if(offset < textSize)
2056       {
2057         range.content     = text[offset];
2058         range.startOffset = offset;
2059         range.endOffset   = offset + 1;
2060       }
2061       break;
2062     }
2063     case Dali::Accessibility::TextBoundary::WORD:
2064     case Dali::Accessibility::TextBoundary::LINE:
2065     {
2066       auto textString = text.c_str();
2067       auto breaks = std::vector<char>(textSize, 0);
2068
2069       if(boundary == Dali::Accessibility::TextBoundary::WORD)
2070       {
2071         Accessibility::Accessible::FindWordSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
2072       }
2073       else
2074       {
2075         Accessibility::Accessible::FindLineSeparationsUtf8(reinterpret_cast<const utf8_t*>(textString), textSize, "", breaks.data());
2076       }
2077
2078       auto index   = 0u;
2079       auto counter = 0u;
2080       while(index < textSize && counter <= offset)
2081       {
2082         auto start = index;
2083         if(breaks[index])
2084         {
2085           while(breaks[index])
2086           {
2087             index++;
2088           }
2089           counter++;
2090         }
2091         else
2092         {
2093           if(boundary == Dali::Accessibility::TextBoundary::WORD)
2094           {
2095             index++;
2096           }
2097           if(boundary == Dali::Accessibility::TextBoundary::LINE)
2098           {
2099             counter++;
2100           }
2101         }
2102
2103         if((counter > 0) && ((counter - 1) == offset))
2104         {
2105           range.content     = text.substr(start, index - start + 1);
2106           range.startOffset = start;
2107           range.endOffset   = index + 1;
2108         }
2109
2110         if(boundary == Dali::Accessibility::TextBoundary::LINE)
2111         {
2112           index++;
2113         }
2114       }
2115       break;
2116     }
2117     case Dali::Accessibility::TextBoundary::SENTENCE:
2118     {
2119       /* not supported by default */
2120       break;
2121     }
2122     case Dali::Accessibility::TextBoundary::PARAGRAPH:
2123     {
2124       /* Paragraph is not supported by libunibreak library */
2125       break;
2126     }
2127     default:
2128       break;
2129   }
2130
2131   return range;
2132 }
2133
2134 Dali::Accessibility::Range TextField::AccessibleImpl::GetRangeOfSelection(size_t selectionIndex)
2135 {
2136   // Since DALi supports only one selection indexes higher than 0 are ignored
2137   if(selectionIndex > 0)
2138   {
2139     return {};
2140   }
2141
2142   auto self  = Toolkit::TextField::DownCast(Self());
2143   auto controller = Dali::Toolkit::GetImpl(self).GetTextController();
2144   std::string value{};
2145   controller->RetrieveSelection(value);
2146   auto indices = controller->GetSelectionIndexes();
2147
2148   return {static_cast<size_t>(indices.first), static_cast<size_t>(indices.second), value};
2149 }
2150
2151 bool TextField::AccessibleImpl::RemoveSelection(size_t selectionIndex)
2152 {
2153   // Since DALi supports only one selection indexes higher than 0 are ignored
2154   if(selectionIndex > 0)
2155   {
2156     return false;
2157   }
2158
2159   auto self = Toolkit::TextField::DownCast(Self());
2160   Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(0, 0);
2161   return true;
2162 }
2163
2164 bool TextField::AccessibleImpl::SetRangeOfSelection(size_t selectionIndex, size_t startOffset, size_t endOffset)
2165 {
2166   // Since DALi supports only one selection indexes higher than 0 are ignored
2167   if(selectionIndex > 0)
2168   {
2169     return false;
2170   }
2171
2172   auto self = Toolkit::TextField::DownCast(Self());
2173   Dali::Toolkit::GetImpl(self).GetTextController()->SetSelection(startOffset, endOffset);
2174   return true;
2175 }
2176
2177 bool TextField::AccessibleImpl::CopyText(size_t startPosition, size_t endPosition)
2178 {
2179   if(endPosition <= startPosition)
2180   {
2181     return false;
2182   }
2183
2184   auto self = Toolkit::TextField::DownCast(Self());
2185   auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
2186   Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
2187
2188   return true;
2189 }
2190
2191 bool TextField::AccessibleImpl::CutText(size_t startPosition, size_t endPosition)
2192 {
2193   if(endPosition <= startPosition)
2194   {
2195     return false;
2196   }
2197
2198   auto self = Toolkit::TextField::DownCast(Self());
2199   auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
2200   Dali::Toolkit::GetImpl(self).GetTextController()->CopyStringToClipboard(text.substr(startPosition, endPosition - startPosition));
2201
2202   self.SetProperty(Toolkit::TextField::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
2203
2204   return true;
2205 }
2206
2207 bool TextField::AccessibleImpl::DeleteText(size_t startPosition, size_t endPosition)
2208 {
2209   if(endPosition <= startPosition)
2210   {
2211     return false;
2212   }
2213
2214   auto self = Toolkit::TextField::DownCast(Self());
2215   auto text = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
2216
2217   self.SetProperty(Toolkit::TextField::Property::TEXT, text.substr(0, startPosition) + text.substr(endPosition));
2218
2219   return true;
2220 }
2221
2222 Dali::Accessibility::States TextField::AccessibleImpl::CalculateStates()
2223 {
2224   using namespace Dali::Accessibility;
2225
2226   auto states = DevelControl::AccessibleImpl::CalculateStates();
2227
2228   states[State::EDITABLE]  = true;
2229   states[State::FOCUSABLE] = true;
2230
2231   Toolkit::Control focusControl = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
2232   if(mSelf == focusControl)
2233   {
2234     states[State::FOCUSED] = true;
2235   }
2236
2237   return states;
2238 }
2239
2240 bool TextField::AccessibleImpl::InsertText(size_t startPosition, std::string text)
2241 {
2242   auto self = Toolkit::TextField::DownCast(Self());
2243   auto insertedText = self.GetProperty(Toolkit::TextField::Property::TEXT).Get<std::string>();
2244
2245   insertedText.insert(startPosition, text);
2246
2247   self.SetProperty(Toolkit::TextField::Property::TEXT, std::move(insertedText));
2248
2249   return true;
2250 }
2251
2252 bool TextField::AccessibleImpl::SetTextContents(std::string newContents)
2253 {
2254   auto self = Toolkit::TextField::DownCast(Self());
2255   self.SetProperty(Toolkit::TextField::Property::TEXT, std::move(newContents));
2256   return true;
2257 }
2258
2259 } // namespace Internal
2260
2261 } // namespace Toolkit
2262
2263 } // namespace Dali