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