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