Merge "Added code for stylable transitions" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-field-impl.cpp
1 /*
2  * Copyright (c) 2016 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/public-api/common/stage.h>
25 #include <dali/public-api/images/resource-image.h>
26 #include <dali/devel-api/adaptor-framework/virtual-keyboard.h>
27 #include <dali/public-api/object/type-registry-helper.h>
28 #include <dali/integration-api/adaptors/adaptor.h>
29 #include <dali/integration-api/debug.h>
30
31 // INTERNAL INCLUDES
32 #include <dali-toolkit/public-api/text/rendering-backend.h>
33 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
34 #include <dali-toolkit/internal/text/rendering/text-backend.h>
35 #include <dali-toolkit/internal/text/text-effects-style.h>
36 #include <dali-toolkit/internal/text/text-font-style.h>
37 #include <dali-toolkit/internal/text/text-view.h>
38 #include <dali-toolkit/internal/styling/style-manager-impl.h>
39
40 using namespace Dali::Toolkit::Text;
41
42 namespace Dali
43 {
44
45 namespace Toolkit
46 {
47
48 namespace Internal
49 {
50
51 namespace // unnamed namespace
52 {
53
54 #if defined(DEBUG_ENABLED)
55   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
56 #endif
57
58   const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
59 } // unnamed namespace
60
61 namespace
62 {
63
64 const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
65 {
66   { "BEGIN",  Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN  },
67   { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
68   { "END",    Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END    },
69 };
70 const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
71
72 const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
73 {
74   { "TOP",    Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP    },
75   { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
76   { "BOTTOM", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_BOTTOM },
77 };
78 const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
79
80 // Type registration
81 BaseHandle Create()
82 {
83   return Toolkit::TextField::New();
84 }
85
86 // Setup properties, signals and actions using the type-registry.
87 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextField, Toolkit::Control, Create );
88
89 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "renderingBackend",                     INTEGER,   RENDERING_BACKEND                    )
90 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "text",                                 STRING,    TEXT                                 )
91 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholderText",                      STRING,    PLACEHOLDER_TEXT                     )
92 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholderTextFocused",               STRING,    PLACEHOLDER_TEXT_FOCUSED             )
93 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "fontFamily",                           STRING,    FONT_FAMILY                          )
94 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "fontStyle",                            STRING,    FONT_STYLE                           )
95 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "pointSize",                            FLOAT,     POINT_SIZE                           )
96 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "maxLength",                            INTEGER,   MAX_LENGTH                           )
97 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "exceedPolicy",                         INTEGER,   EXCEED_POLICY                        )
98 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "horizontalAlignment",                  STRING,    HORIZONTAL_ALIGNMENT                 )
99 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "verticalAlignment",                    STRING,    VERTICAL_ALIGNMENT                   )
100 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "textColor",                            VECTOR4,   TEXT_COLOR                           )
101 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholderTextColor",                 VECTOR4,   PLACEHOLDER_TEXT_COLOR               )
102 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "shadowOffset",                         VECTOR2,   SHADOW_OFFSET                        )
103 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "shadowColor",                          VECTOR4,   SHADOW_COLOR                         )
104 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "primaryCursorColor",                   VECTOR4,   PRIMARY_CURSOR_COLOR                 )
105 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "secondaryCursorColor",                 VECTOR4,   SECONDARY_CURSOR_COLOR               )
106 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "enableCursorBlink",                    BOOLEAN,   ENABLE_CURSOR_BLINK                  )
107 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "cursorBlinkInterval",                  FLOAT,     CURSOR_BLINK_INTERVAL                )
108 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "cursorBlinkDuration",                  FLOAT,     CURSOR_BLINK_DURATION                )
109 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "cursorWidth",                          INTEGER,   CURSOR_WIDTH                         )
110 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "grabHandleImage",                      STRING,    GRAB_HANDLE_IMAGE                    )
111 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "grabHandlePressedImage",               STRING,    GRAB_HANDLE_PRESSED_IMAGE            )
112 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "scrollThreshold",                      FLOAT,     SCROLL_THRESHOLD                     )
113 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "scrollSpeed",                          FLOAT,     SCROLL_SPEED                         )
114 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandleImageLeft",             MAP,       SELECTION_HANDLE_IMAGE_LEFT          )
115 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandleImageRight",            MAP,       SELECTION_HANDLE_IMAGE_RIGHT         )
116 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandlePressedImageLeft",      MAP,       SELECTION_HANDLE_PRESSED_IMAGE_LEFT  )
117 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandlePressedImageRight",     MAP,       SELECTION_HANDLE_PRESSED_IMAGE_RIGHT )
118 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandleMarkerImageLeft",       MAP,       SELECTION_HANDLE_MARKER_IMAGE_LEFT   )
119 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandleMarkerImageRight",      MAP,       SELECTION_HANDLE_MARKER_IMAGE_RIGHT  )
120 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHighlightColor",              VECTOR4,   SELECTION_HIGHLIGHT_COLOR            )
121 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "decorationBoundingBox",                RECTANGLE, DECORATION_BOUNDING_BOX              )
122 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputMethodSettings",                  MAP,       INPUT_METHOD_SETTINGS                )
123 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputColor",                           VECTOR4,   INPUT_COLOR                          )
124 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "enableMarkup",                         BOOLEAN,   ENABLE_MARKUP                        )
125 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputFontFamily",                      STRING,    INPUT_FONT_FAMILY                    )
126 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputFontStyle",                       STRING,    INPUT_FONT_STYLE                     )
127 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputPointSize",                       FLOAT,     INPUT_POINT_SIZE                     )
128 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "underline",                            STRING,    UNDERLINE                            )
129 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputUnderline",                       STRING,    INPUT_UNDERLINE                      )
130 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "shadow",                               STRING,    SHADOW                               )
131 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputShadow",                          STRING,    INPUT_SHADOW                         )
132 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "emboss",                               STRING,    EMBOSS                               )
133 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputEmboss",                          STRING,    INPUT_EMBOSS                         )
134 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "outline",                              STRING,    OUTLINE                              )
135 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputOutline",                         STRING,    INPUT_OUTLINE                        )
136
137 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged",        SIGNAL_TEXT_CHANGED )
138 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached",   SIGNAL_MAX_LENGTH_REACHED )
139 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "inputStyleChanged",  SIGNAL_INPUT_STYLE_CHANGED )
140
141 DALI_TYPE_REGISTRATION_END()
142
143 } // namespace
144
145 Toolkit::TextField TextField::New()
146 {
147   // Create the implementation, temporarily owned by this handle on stack
148   IntrusivePtr< TextField > impl = new TextField();
149
150   // Pass ownership to CustomActor handle
151   Toolkit::TextField handle( *impl );
152
153   // Second-phase init of the implementation
154   // This can only be done after the CustomActor connection has been made...
155   impl->Initialize();
156
157   return handle;
158 }
159
160 void TextField::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
161 {
162   Toolkit::TextField textField = Toolkit::TextField::DownCast( Dali::BaseHandle( object ) );
163
164   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField SetProperty\n");
165
166
167   if( textField )
168   {
169     TextField& impl( GetImpl( textField ) );
170
171     switch( index )
172     {
173       case Toolkit::TextField::Property::RENDERING_BACKEND:
174       {
175         int backend = value.Get< int >();
176         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend );
177
178 #ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
179         if( Text::RENDERING_VECTOR_BASED == backend )
180         {
181           backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering
182         }
183 #endif
184         if( impl.mRenderingBackend != backend )
185         {
186           impl.mRenderingBackend = backend;
187           impl.mRenderer.Reset();
188
189           if( impl.mController )
190           {
191             // When using the vector-based rendering, the size of the GLyphs are different
192             TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
193             impl.mController->SetGlyphType( glyphType );
194           }
195         }
196         break;
197       }
198       case Toolkit::TextField::Property::TEXT:
199       {
200         if( impl.mController )
201         {
202           const std::string text = value.Get< std::string >();
203           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p TEXT %s\n", impl.mController.Get(), text.c_str() );
204
205           impl.mController->SetText( text );
206         }
207         break;
208       }
209       case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
210       {
211         if( impl.mController )
212         {
213           const std::string text = value.Get< std::string >();
214           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str() );
215
216           impl.mController->SetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
217         }
218         break;
219       }
220       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_FOCUSED:
221       {
222         if( impl.mController )
223         {
224           const std::string text = value.Get< std::string >();
225           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_FOCUSED %s\n", impl.mController.Get(), text.c_str() );
226
227           impl.mController->SetPlaceholderText( Controller::PLACEHOLDER_TYPE_ACTIVE, text );
228         }
229         break;
230       }
231       case Toolkit::TextField::Property::FONT_FAMILY:
232       {
233         if( impl.mController )
234         {
235           const std::string fontFamily = value.Get< std::string >();
236           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
237           impl.mController->SetDefaultFontFamily( fontFamily );
238         }
239         break;
240       }
241       case Toolkit::TextField::Property::FONT_STYLE:
242       {
243         SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
244         break;
245       }
246       case Toolkit::TextField::Property::POINT_SIZE:
247       {
248         if( impl.mController )
249         {
250           const float pointSize = value.Get< float >();
251           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p POINT_SIZE %f\n", impl.mController.Get(), pointSize );
252
253           if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
254           {
255             impl.mController->SetDefaultPointSize( pointSize );
256           }
257         }
258         break;
259       }
260       case Toolkit::TextField::Property::MAX_LENGTH:
261       {
262         if( impl.mController )
263         {
264           const int max = value.Get< int >();
265           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p MAX_LENGTH %d\n", impl.mController.Get(), max );
266
267           impl.mController->SetMaximumNumberOfCharacters( max );
268         }
269         break;
270       }
271       case Toolkit::TextField::Property::EXCEED_POLICY:
272       {
273         // TODO
274         break;
275       }
276       case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
277       {
278         if( impl.mController )
279         {
280           const std::string alignStr = value.Get< std::string >();
281           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %s\n", impl.mController.Get(), alignStr.c_str() );
282
283           LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
284           if( Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
285                                                                               HORIZONTAL_ALIGNMENT_STRING_TABLE,
286                                                                               HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
287                                                                               alignment ) )
288           {
289             impl.mController->SetHorizontalAlignment( alignment );
290           }
291         }
292         break;
293       }
294       case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
295       {
296         if( impl.mController )
297         {
298           const std::string alignStr = value.Get< std::string >();
299           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %s\n", impl.mController.Get(), alignStr.c_str() );
300
301           LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
302           if( Scripting::GetEnumeration< LayoutEngine::VerticalAlignment >( alignStr.c_str(),
303                                                                             VERTICAL_ALIGNMENT_STRING_TABLE,
304                                                                             VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
305                                                                             alignment ) )
306           {
307             impl.mController->SetVerticalAlignment( alignment );
308           }
309         }
310         break;
311       }
312       case Toolkit::TextField::Property::TEXT_COLOR:
313       {
314         if( impl.mController )
315         {
316           const Vector4 textColor = value.Get< Vector4 >();
317           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 );
318
319           if( impl.mController->GetTextColor() != textColor )
320           {
321             impl.mController->SetTextColor( textColor );
322             impl.mController->SetInputColor( textColor );
323             impl.mRenderer.Reset();
324           }
325         }
326         break;
327       }
328       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
329       {
330         if( impl.mController )
331         {
332           const Vector4 textColor = value.Get< Vector4 >();
333           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 );
334
335           if( impl.mController->GetPlaceholderTextColor() != textColor )
336           {
337             impl.mController->SetPlaceholderTextColor( textColor );
338             impl.mRenderer.Reset();
339           }
340         }
341         break;
342       }
343       case Toolkit::TextField::Property::SHADOW_OFFSET:
344       {
345         if( impl.mController )
346         {
347           const Vector2 shadowOffset = value.Get< Vector2 >();
348           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SHADOW_OFFSET %f,%f\n", impl.mController.Get(), shadowOffset.x, shadowOffset.y );
349
350           if ( impl.mController->GetShadowOffset() != shadowOffset )
351           {
352             impl.mController->SetShadowOffset( shadowOffset );
353             impl.mRenderer.Reset();
354           }
355         }
356         break;
357       }
358       case Toolkit::TextField::Property::SHADOW_COLOR:
359       {
360         if( impl.mController )
361         {
362           const Vector4 shadowColor = value.Get< Vector4 >();
363           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SHADOW_COLOR %f,%f,%f,%f\n", impl.mController.Get(), shadowColor.r, shadowColor.g, shadowColor.b, shadowColor.a );
364
365           if ( impl.mController->GetShadowColor() != shadowColor )
366           {
367             impl.mController->SetShadowColor( shadowColor );
368             impl.mRenderer.Reset();
369           }
370         }
371         break;
372       }
373       case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
374       {
375         if( impl.mDecorator )
376         {
377           const Vector4 color = value.Get< Vector4 >();
378           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 );
379
380           impl.mDecorator->SetCursorColor( PRIMARY_CURSOR, color );
381           impl.RequestTextRelayout();
382         }
383         break;
384       }
385       case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
386       {
387         if( impl.mDecorator )
388         {
389           const Vector4 color = value.Get< Vector4 >();
390           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 );
391
392           impl.mDecorator->SetCursorColor( SECONDARY_CURSOR, color );
393           impl.RequestTextRelayout();
394         }
395         break;
396       }
397       case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
398       {
399         if( impl.mController )
400         {
401           const bool enable = value.Get< bool >();
402           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable );
403
404           impl.mController->SetEnableCursorBlink( enable );
405           impl.RequestTextRelayout();
406         }
407         break;
408       }
409       case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
410       {
411         if( impl.mDecorator )
412         {
413           const float interval = value.Get< float >();
414           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval );
415
416           impl.mDecorator->SetCursorBlinkInterval( interval );
417         }
418         break;
419       }
420       case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
421       {
422         if( impl.mDecorator )
423         {
424           const float duration = value.Get< float >();
425           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration );
426
427           impl.mDecorator->SetCursorBlinkDuration( duration );
428         }
429         break;
430       }
431       case Toolkit::TextField::Property::CURSOR_WIDTH:
432       {
433         if( impl.mDecorator )
434         {
435           const int width = value.Get< int >();
436           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_WIDTH %d\n", impl.mController.Get(), width );
437
438           impl.mDecorator->SetCursorWidth( width );
439           impl.mController->GetLayoutEngine().SetCursorWidth( width );
440         }
441         break;
442       }
443       case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
444       {
445         const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
446         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), image.GetUrl().c_str() );
447
448         if( impl.mDecorator )
449         {
450           impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED, image );
451           impl.RequestTextRelayout();
452         }
453         break;
454       }
455       case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
456       {
457         const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
458         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), image.GetUrl().c_str() );
459
460         if( impl.mDecorator )
461         {
462           impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED, image );
463           impl.RequestTextRelayout();
464         }
465         break;
466       }
467       case Toolkit::TextField::Property::SCROLL_THRESHOLD:
468       {
469         const float threshold = value.Get< float >();
470         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold );
471
472         if( impl.mDecorator )
473         {
474           impl.mDecorator->SetScrollThreshold( threshold );
475         }
476         break;
477       }
478       case Toolkit::TextField::Property::SCROLL_SPEED:
479       {
480         const float speed = value.Get< float >();
481         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SCROLL_SPEED %f\n", impl.mController.Get(), speed );
482
483         if( impl.mDecorator )
484         {
485           impl.mDecorator->SetScrollSpeed( speed );
486         }
487         break;
488       }
489       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
490       {
491         const Image image = Scripting::NewImage( value );
492
493         if( impl.mDecorator && image )
494         {
495           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
496           impl.RequestTextRelayout();
497         }
498         break;
499       }
500       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
501       {
502         const Image image = Scripting::NewImage( value );
503
504         if( impl.mDecorator && image )
505         {
506           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
507           impl.RequestTextRelayout();
508         }
509         break;
510       }
511       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
512       {
513         const Image image = Scripting::NewImage( value );
514
515         if( impl.mDecorator && image )
516         {
517           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, image );
518           impl.RequestTextRelayout();
519         }
520         break;
521       }
522       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
523       {
524         const Image image = Scripting::NewImage( value );
525
526         if( impl.mDecorator && image )
527         {
528           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, image );
529           impl.RequestTextRelayout();
530         }
531         break;
532       }
533       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
534       {
535         const Image image = Scripting::NewImage( value );
536
537         if( impl.mDecorator && image )
538         {
539           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, image );
540           impl.RequestTextRelayout();
541         }
542         break;
543       }
544       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
545       {
546         const Image image = Scripting::NewImage( value );
547
548         if( impl.mDecorator && image )
549         {
550           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, image );
551           impl.RequestTextRelayout();
552         }
553         break;
554       }
555       case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
556       {
557         const Vector4 color = value.Get< Vector4 >();
558         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 );
559
560         if( impl.mDecorator )
561         {
562           impl.mDecorator->SetHighlightColor( color );
563           impl.RequestTextRelayout();
564         }
565         break;
566       }
567       case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
568       {
569         if( impl.mDecorator )
570         {
571           const Rect<int> box = value.Get< Rect<int> >();
572           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 );
573
574           impl.mDecorator->SetBoundingBox( box );
575           impl.RequestTextRelayout();
576         }
577         break;
578       }
579       case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
580       {
581         const Property::Map map = value.Get<Property::Map>();
582         VirtualKeyboard::ApplySettings( map );
583         break;
584       }
585       case Toolkit::TextField::Property::INPUT_COLOR:
586       {
587         if( impl.mController )
588         {
589           const Vector4 inputColor = value.Get< Vector4 >();
590           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 );
591
592           impl.mController->SetInputColor( inputColor );
593         }
594         break;
595       }
596       case Toolkit::TextField::Property::ENABLE_MARKUP:
597       {
598         if( impl.mController )
599         {
600           const bool enableMarkup = value.Get<bool>();
601           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup );
602
603           impl.mController->SetMarkupProcessorEnabled( enableMarkup );
604         }
605         break;
606       }
607       case Toolkit::TextField::Property::INPUT_FONT_FAMILY:
608       {
609         if( impl.mController )
610         {
611           const std::string fontFamily = value.Get< std::string >();
612           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
613           impl.mController->SetInputFontFamily( fontFamily );
614         }
615         break;
616       }
617       case Toolkit::TextField::Property::INPUT_FONT_STYLE:
618       {
619         SetFontStyleProperty( impl.mController, value, Text::FontStyle::INPUT );
620         break;
621       }
622       case Toolkit::TextField::Property::INPUT_POINT_SIZE:
623       {
624         if( impl.mController )
625         {
626           const float pointSize = value.Get< float >();
627           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize );
628           impl.mController->SetInputFontPointSize( pointSize );
629         }
630         break;
631       }
632       case Toolkit::TextField::Property::UNDERLINE:
633       {
634         const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
635         if( update )
636         {
637           impl.mRenderer.Reset();
638         }
639         break;
640       }
641       case Toolkit::TextField::Property::INPUT_UNDERLINE:
642       {
643         const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::INPUT );
644         if( update )
645         {
646           impl.mRenderer.Reset();
647         }
648         break;
649       }
650       case Toolkit::TextField::Property::SHADOW:
651       {
652         const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
653         if( update )
654         {
655           impl.mRenderer.Reset();
656         }
657         break;
658       }
659       case Toolkit::TextField::Property::INPUT_SHADOW:
660       {
661         const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::INPUT );
662         if( update )
663         {
664           impl.mRenderer.Reset();
665         }
666         break;
667       }
668       case Toolkit::TextField::Property::EMBOSS:
669       {
670         const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
671         if( update )
672         {
673           impl.mRenderer.Reset();
674         }
675         break;
676       }
677       case Toolkit::TextField::Property::INPUT_EMBOSS:
678       {
679         const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::INPUT );
680         if( update )
681         {
682           impl.mRenderer.Reset();
683         }
684         break;
685       }
686       case Toolkit::TextField::Property::OUTLINE:
687       {
688         const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
689         if( update )
690         {
691           impl.mRenderer.Reset();
692         }
693         break;
694       }
695       case Toolkit::TextField::Property::INPUT_OUTLINE:
696       {
697         const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::INPUT );
698         if( update )
699         {
700           impl.mRenderer.Reset();
701         }
702         break;
703       }
704     } // switch
705   } // textfield
706 }
707
708 Property::Value TextField::GetProperty( BaseObject* object, Property::Index index )
709 {
710   Property::Value value;
711
712   Toolkit::TextField textField = Toolkit::TextField::DownCast( Dali::BaseHandle( object ) );
713
714   if( textField )
715   {
716     TextField& impl( GetImpl( textField ) );
717
718     switch( index )
719     {
720       case Toolkit::TextField::Property::RENDERING_BACKEND:
721       {
722         value = impl.mRenderingBackend;
723         break;
724       }
725       case Toolkit::TextField::Property::TEXT:
726       {
727         if( impl.mController )
728         {
729           std::string text;
730           impl.mController->GetText( text );
731           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p returning text: %s\n", impl.mController.Get(), text.c_str() );
732           value = text;
733         }
734         break;
735       }
736       case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
737       {
738         if( impl.mController )
739         {
740           std::string text;
741           impl.mController->GetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
742           value = text;
743         }
744         break;
745       }
746       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_FOCUSED:
747       {
748         if( impl.mController )
749         {
750           std::string text;
751           impl.mController->GetPlaceholderText( Controller::PLACEHOLDER_TYPE_ACTIVE, text );
752           value = text;
753         }
754         break;
755       }
756       case Toolkit::TextField::Property::FONT_FAMILY:
757       {
758         if( impl.mController )
759         {
760           value = impl.mController->GetDefaultFontFamily();
761         }
762         break;
763       }
764       case Toolkit::TextField::Property::FONT_STYLE:
765       {
766         GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
767         break;
768       }
769       case Toolkit::TextField::Property::POINT_SIZE:
770       {
771         if( impl.mController )
772         {
773           value = impl.mController->GetDefaultPointSize();
774         }
775         break;
776       }
777       case Toolkit::TextField::Property::MAX_LENGTH:
778       {
779         if( impl.mController )
780         {
781           value = impl.mController->GetMaximumNumberOfCharacters();
782         }
783         break;
784       }
785       case Toolkit::TextField::Property::EXCEED_POLICY:
786       {
787         value = impl.mExceedPolicy;
788         break;
789       }
790       case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
791       {
792         if( impl.mController )
793         {
794           const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
795                                                                                                                 HORIZONTAL_ALIGNMENT_STRING_TABLE,
796                                                                                                                 HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
797           if( name )
798           {
799             value = std::string( name );
800           }
801         }
802         break;
803       }
804       case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
805       {
806         if( impl.mController )
807         {
808           const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetLayoutEngine().GetVerticalAlignment(),
809                                                                                                               VERTICAL_ALIGNMENT_STRING_TABLE,
810                                                                                                               VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
811           if( name )
812           {
813             value = std::string( name );
814           }
815         }
816         break;
817       }
818       case Toolkit::TextField::Property::TEXT_COLOR:
819       {
820         if ( impl.mController )
821         {
822           value = impl.mController->GetTextColor();
823         }
824         break;
825       }
826       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
827       {
828         if ( impl.mController )
829         {
830           value = impl.mController->GetPlaceholderTextColor();
831         }
832         break;
833       }
834       case Toolkit::TextField::Property::SHADOW_OFFSET:
835       {
836         if ( impl.mController )
837         {
838           value = impl.mController->GetShadowOffset();
839         }
840         break;
841       }
842       case Toolkit::TextField::Property::SHADOW_COLOR:
843       {
844         if ( impl.mController )
845         {
846           value = impl.mController->GetShadowColor();
847         }
848         break;
849       }
850       case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
851       {
852         if( impl.mDecorator )
853         {
854           value = impl.mDecorator->GetColor( PRIMARY_CURSOR );
855         }
856         break;
857       }
858       case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
859       {
860         if( impl.mDecorator )
861         {
862           value = impl.mDecorator->GetColor( SECONDARY_CURSOR );
863         }
864         break;
865       }
866       case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
867       {
868         value = impl.mController->GetEnableCursorBlink();
869         break;
870       }
871       case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
872       {
873         if( impl.mDecorator )
874         {
875           value = impl.mDecorator->GetCursorBlinkInterval();
876         }
877         break;
878       }
879       case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
880       {
881         if( impl.mDecorator )
882         {
883           value = impl.mDecorator->GetCursorBlinkDuration();
884         }
885         break;
886       }
887       case Toolkit::TextField::Property::CURSOR_WIDTH:
888       {
889         if( impl.mDecorator )
890         {
891           value = impl.mDecorator->GetCursorWidth();
892         }
893         break;
894       }
895       case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
896       {
897         if( impl.mDecorator )
898         {
899           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED ) );
900           if( image )
901           {
902             value = image.GetUrl();
903           }
904         }
905         break;
906       }
907       case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
908       {
909         if( impl.mDecorator )
910         {
911           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED ) );
912           if( image )
913           {
914             value = image.GetUrl();
915           }
916         }
917         break;
918       }
919       case Toolkit::TextField::Property::SCROLL_THRESHOLD:
920       {
921         if( impl.mDecorator )
922         {
923           value = impl.mDecorator->GetScrollThreshold();
924         }
925         break;
926       }
927       case Toolkit::TextField::Property::SCROLL_SPEED:
928       {
929         if( impl.mDecorator )
930         {
931           value = impl.mDecorator->GetScrollSpeed();
932         }
933         break;
934       }
935       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
936       {
937         impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED );
938         break;
939       }
940       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
941       {
942         impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED ) ;
943         break;
944       }
945       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
946       {
947         impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED );
948         break;
949       }
950       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
951       {
952         impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED );
953         break;
954       }
955       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
956       {
957         impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED );
958         break;
959       }
960       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
961       {
962         impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED );
963         break;
964       }
965       case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
966       {
967         if( impl.mDecorator )
968         {
969           value = impl.mDecorator->GetHighlightColor();
970         }
971         break;
972       }
973       case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
974       {
975         if( impl.mDecorator )
976         {
977           Rect<int> boundingBox;
978           impl.mDecorator->GetBoundingBox( boundingBox );
979           value = boundingBox;
980         }
981         break;
982       }
983       case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
984       {
985         break;
986       }
987       case Toolkit::TextField::Property::INPUT_COLOR:
988       {
989         if( impl.mController )
990         {
991           value = impl.mController->GetInputColor();
992         }
993         break;
994       }
995       case Toolkit::TextField::Property::ENABLE_MARKUP:
996       {
997         if( impl.mController )
998         {
999           value = impl.mController->IsMarkupProcessorEnabled();
1000         }
1001         break;
1002       }
1003       case Toolkit::TextField::Property::INPUT_FONT_FAMILY:
1004       {
1005         if( impl.mController )
1006         {
1007           value = impl.mController->GetInputFontFamily();
1008         }
1009         break;
1010       }
1011       case Toolkit::TextField::Property::INPUT_FONT_STYLE:
1012       {
1013         GetFontStyleProperty( impl.mController, value, Text::FontStyle::INPUT );
1014         break;
1015       }
1016       case Toolkit::TextField::Property::INPUT_POINT_SIZE:
1017       {
1018         if( impl.mController )
1019         {
1020           value = impl.mController->GetInputFontPointSize();
1021         }
1022         break;
1023       }
1024       case Toolkit::TextField::Property::UNDERLINE:
1025       {
1026         GetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
1027         break;
1028       }
1029       case Toolkit::TextField::Property::INPUT_UNDERLINE:
1030       {
1031         GetUnderlineProperties( impl.mController, value, Text::EffectStyle::INPUT );
1032         break;
1033       }
1034       case Toolkit::TextField::Property::SHADOW:
1035       {
1036         GetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
1037         break;
1038       }
1039       case Toolkit::TextField::Property::INPUT_SHADOW:
1040       {
1041         GetShadowProperties( impl.mController, value, Text::EffectStyle::INPUT );
1042         break;
1043       }
1044       case Toolkit::TextField::Property::EMBOSS:
1045       {
1046         GetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
1047         break;
1048       }
1049       case Toolkit::TextField::Property::INPUT_EMBOSS:
1050       {
1051         GetEmbossProperties( impl.mController, value, Text::EffectStyle::INPUT );
1052         break;
1053       }
1054       case Toolkit::TextField::Property::OUTLINE:
1055       {
1056         GetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
1057         break;
1058       }
1059       case Toolkit::TextField::Property::INPUT_OUTLINE:
1060       {
1061         GetOutlineProperties( impl.mController, value, Text::EffectStyle::INPUT );
1062         break;
1063       }
1064     } //switch
1065   }
1066
1067   return value;
1068 }
1069
1070 bool TextField::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1071 {
1072   Dali::BaseHandle handle( object );
1073
1074   bool connected( true );
1075   Toolkit::TextField field = Toolkit::TextField::DownCast( handle );
1076
1077   if( 0 == strcmp( signalName.c_str(), SIGNAL_TEXT_CHANGED ) )
1078   {
1079     field.TextChangedSignal().Connect( tracker, functor );
1080   }
1081   else if( 0 == strcmp( signalName.c_str(), SIGNAL_MAX_LENGTH_REACHED ) )
1082   {
1083     field.MaxLengthReachedSignal().Connect( tracker, functor );
1084   }
1085   else if( 0 == strcmp( signalName.c_str(), SIGNAL_INPUT_STYLE_CHANGED ) )
1086   {
1087     field.InputStyleChangedSignal().Connect( tracker, functor );
1088   }
1089   else
1090   {
1091     // signalName does not match any signal
1092     connected = false;
1093   }
1094
1095   return connected;
1096 }
1097
1098 Toolkit::TextField::TextChangedSignalType& TextField::TextChangedSignal()
1099 {
1100   return mTextChangedSignal;
1101 }
1102
1103 Toolkit::TextField::MaxLengthReachedSignalType& TextField::MaxLengthReachedSignal()
1104 {
1105   return mMaxLengthReachedSignal;
1106 }
1107
1108 Toolkit::TextField::InputStyleChangedSignalType& TextField::InputStyleChangedSignal()
1109 {
1110   return mInputStyleChangedSignal;
1111 }
1112
1113 void TextField::OnInitialize()
1114 {
1115   Actor self = Self();
1116
1117   mController = Text::Controller::New( this, this );
1118
1119   // When using the vector-based rendering, the size of the GLyphs are different
1120   TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
1121   mController->SetGlyphType( glyphType );
1122
1123   mDecorator = Text::Decorator::New( *mController,
1124                                      *mController );
1125
1126   mController->GetLayoutEngine().SetLayout( LayoutEngine::SINGLE_LINE_BOX );
1127
1128   // Enables the text input.
1129   mController->EnableTextInput( mDecorator );
1130
1131   // Enables the horizontal scrolling after the text input has been enabled.
1132   mController->SetHorizontalScrollEnabled( true );
1133
1134   // Disables the vertical scrolling.
1135   mController->SetVerticalScrollEnabled( false );
1136
1137   // Disable the smooth handle panning.
1138   mController->SetSmoothHandlePanEnabled( false );
1139
1140   // Forward input events to controller
1141   EnableGestureDetection( static_cast<Gesture::Type>( Gesture::Tap | Gesture::Pan | Gesture::LongPress ) );
1142   GetTapGestureDetector().SetMaximumTapsRequired( 2 );
1143
1144   self.TouchSignal().Connect( this, &TextField::OnTouched );
1145
1146   // Set BoundingBox to stage size if not already set.
1147   Rect<int> boundingBox;
1148   mDecorator->GetBoundingBox( boundingBox );
1149
1150   if( boundingBox.IsEmpty() )
1151   {
1152     Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
1153     mDecorator->SetBoundingBox( Rect<int>( 0.0f, 0.0f, stageSize.width, stageSize.height ) );
1154   }
1155
1156   // Flip vertically the 'left' selection handle
1157   mDecorator->FlipHandleVertically( LEFT_SELECTION_HANDLE, true );
1158
1159   // Fill-parent area by default
1160   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
1161   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
1162   self.OnStageSignal().Connect( this, &TextField::OnStageConnect );
1163 }
1164
1165 void TextField::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
1166 {
1167   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnStyleChange\n");
1168
1169   switch ( change )
1170   {
1171     case StyleChange::DEFAULT_FONT_CHANGE:
1172     {
1173       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnStyleChange DEFAULT_FONT_CHANGE\n");
1174       const std::string& newFont = GetImpl( styleManager ).GetDefaultFontFamily();
1175       // Property system did not set the font so should update it.
1176       mController->UpdateAfterFontChange( newFont );
1177       break;
1178     }
1179
1180     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
1181     {
1182       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
1183       break;
1184     }
1185     case StyleChange::THEME_CHANGE:
1186     {
1187       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
1188       break;
1189     }
1190   }
1191 }
1192
1193 Vector3 TextField::GetNaturalSize()
1194 {
1195   return mController->GetNaturalSize();
1196 }
1197
1198 float TextField::GetHeightForWidth( float width )
1199 {
1200   return mController->GetHeightForWidth( width );
1201 }
1202
1203 void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
1204 {
1205   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField OnRelayout\n");
1206
1207   const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
1208
1209   if( ( Text::Controller::NONE_UPDATED != updateTextType ) ||
1210       !mRenderer )
1211   {
1212     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnRelayout %p Displaying new contents\n", mController.Get() );
1213
1214     if( mDecorator &&
1215         ( Text::Controller::NONE_UPDATED != ( Text::Controller::DECORATOR_UPDATED & updateTextType ) ) )
1216     {
1217       mDecorator->Relayout( size );
1218     }
1219
1220     if( !mRenderer )
1221     {
1222       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
1223     }
1224
1225     EnableClipping( size );
1226     RenderText( updateTextType );
1227   }
1228
1229   // The text-field emits signals when the input style changes. These changes of style are
1230   // detected during the relayout process (size negotiation), i.e after the cursor has been moved. Signals
1231   // can't be emitted during the size negotiation as the callbacks may update the UI.
1232   // The text-field adds an idle callback to the adaptor to emit the signals after the size negotiation.
1233   if( !mController->IsInputStyleChangedSignalsQueueEmpty() )
1234   {
1235     if( Adaptor::IsAvailable() )
1236     {
1237       Adaptor& adaptor = Adaptor::Get();
1238
1239       if( NULL == mIdleCallback )
1240       {
1241         // @note: The callback manager takes the ownership of the callback object.
1242         mIdleCallback = MakeCallback( this, &TextField::OnIdleSignal );
1243         adaptor.AddIdle( mIdleCallback );
1244       }
1245     }
1246   }
1247 }
1248
1249 void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
1250 {
1251   Actor self = Self();
1252   Actor renderableActor;
1253
1254   if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) )
1255   {
1256     if( mRenderer )
1257     {
1258       renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT );
1259     }
1260
1261     if( renderableActor != mRenderableActor )
1262     {
1263       UnparentAndReset( mRenderableActor );
1264       mRenderableActor = renderableActor;
1265     }
1266   }
1267
1268   if( mRenderableActor )
1269   {
1270     const Vector2& scrollOffset = mController->GetScrollPosition();
1271
1272     mRenderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
1273
1274     Actor clipRootActor;
1275     if( mClipper )
1276     {
1277       clipRootActor = mClipper->GetRootActor();
1278     }
1279
1280     for( std::vector<Actor>::const_iterator it = mClippingDecorationActors.begin(),
1281            endIt = mClippingDecorationActors.end();
1282          it != endIt;
1283          ++it )
1284     {
1285       Actor actor = *it;
1286
1287       if( clipRootActor )
1288       {
1289         clipRootActor.Add( actor );
1290       }
1291       else
1292       {
1293         self.Add( actor );
1294       }
1295     }
1296     mClippingDecorationActors.clear();
1297
1298     // Make sure the actor is parented correctly with/without clipping
1299     if( clipRootActor )
1300     {
1301       clipRootActor.Add( mRenderableActor );
1302     }
1303     else
1304     {
1305       self.Add( mRenderableActor );
1306     }
1307   }
1308 }
1309
1310 void TextField::OnKeyInputFocusGained()
1311 {
1312   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyInputFocusGained %p\n", mController.Get() );
1313
1314   VirtualKeyboard::StatusChangedSignal().Connect( this, &TextField::KeyboardStatusChanged );
1315
1316   ImfManager imfManager = ImfManager::Get();
1317
1318   if ( imfManager )
1319   {
1320     imfManager.EventReceivedSignal().Connect( this, &TextField::OnImfEvent );
1321
1322     // Notify that the text editing start.
1323     imfManager.Activate();
1324
1325     // When window gain lost focus, the imf manager is deactivated. Thus when window gain focus again, the imf manager must be activated.
1326     imfManager.SetRestoreAfterFocusLost( true );
1327   }
1328
1329    ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
1330
1331    if ( notifier )
1332    {
1333       notifier.ContentSelectedSignal().Connect( this, &TextField::OnClipboardTextSelected );
1334    }
1335
1336   mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event
1337
1338   EmitKeyInputFocusSignal( true ); // Calls back into the Control hence done last.
1339 }
1340
1341 void TextField::OnKeyInputFocusLost()
1342 {
1343   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField:OnKeyInputFocusLost %p\n", mController.Get() );
1344
1345   VirtualKeyboard::StatusChangedSignal().Disconnect( this, &TextField::KeyboardStatusChanged );
1346
1347   ImfManager imfManager = ImfManager::Get();
1348   if ( imfManager )
1349   {
1350     // The text editing is finished. Therefore the imf manager don't have restore activation.
1351     imfManager.SetRestoreAfterFocusLost( false );
1352
1353     // Notify that the text editing finish.
1354     imfManager.Deactivate();
1355
1356     imfManager.EventReceivedSignal().Disconnect( this, &TextField::OnImfEvent );
1357   }
1358
1359   ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
1360
1361   if ( notifier )
1362   {
1363     notifier.ContentSelectedSignal().Disconnect( this, &TextField::OnClipboardTextSelected );
1364   }
1365
1366   mController->KeyboardFocusLostEvent();
1367
1368   EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
1369 }
1370
1371 void TextField::OnTap( const TapGesture& gesture )
1372 {
1373   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnTap %p\n", mController.Get() );
1374
1375   // Show the keyboard if it was hidden.
1376   if (!VirtualKeyboard::IsVisible())
1377   {
1378     VirtualKeyboard::Show();
1379   }
1380
1381   // Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures
1382   mController->TapEvent( gesture.numberOfTaps, gesture.localPoint.x, gesture.localPoint.y );
1383
1384   SetKeyInputFocus();
1385 }
1386
1387 void TextField::OnPan( const PanGesture& gesture )
1388 {
1389   mController->PanEvent( gesture.state, gesture.displacement );
1390 }
1391
1392 void TextField::OnLongPress( const LongPressGesture& gesture )
1393 {
1394   // Show the keyboard if it was hidden.
1395   if (!VirtualKeyboard::IsVisible())
1396   {
1397     VirtualKeyboard::Show();
1398   }
1399
1400   mController->LongPressEvent( gesture.state, gesture.localPoint.x, gesture.localPoint.y );
1401
1402   SetKeyInputFocus();
1403 }
1404
1405 bool TextField::OnKeyEvent( const KeyEvent& event )
1406 {
1407   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
1408
1409   if( Dali::DALI_KEY_ESCAPE == event.keyCode ||
1410       "Return" == event.keyPressedName ) // Make a Dali key code for this
1411   {
1412     ClearKeyInputFocus();
1413     return true;
1414   }
1415
1416   return mController->KeyEvent( event );
1417 }
1418
1419 void TextField::RequestTextRelayout()
1420 {
1421   RelayoutRequest();
1422 }
1423
1424 void TextField::TextChanged()
1425 {
1426   Dali::Toolkit::TextField handle( GetOwner() );
1427   mTextChangedSignal.Emit( handle );
1428 }
1429
1430 void TextField::MaxLengthReached()
1431 {
1432   Dali::Toolkit::TextField handle( GetOwner() );
1433   mMaxLengthReachedSignal.Emit( handle );
1434 }
1435
1436 void TextField::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
1437 {
1438   Dali::Toolkit::TextField handle( GetOwner() );
1439
1440   Toolkit::TextField::InputStyle::Mask fieldInputStyleMask = Toolkit::TextField::InputStyle::NONE;
1441
1442   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_COLOR ) )
1443   {
1444     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::COLOR );
1445   }
1446   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_FAMILY ) )
1447   {
1448     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_FAMILY );
1449   }
1450   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_POINT_SIZE ) )
1451   {
1452     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::POINT_SIZE );
1453   }
1454   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_WEIGHT ) )
1455   {
1456     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE );
1457   }
1458   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_WIDTH ) )
1459   {
1460     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE );
1461   }
1462   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_SLANT ) )
1463   {
1464     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE );
1465   }
1466   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_UNDERLINE ) )
1467   {
1468     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::UNDERLINE );
1469   }
1470   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_SHADOW ) )
1471   {
1472     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::SHADOW );
1473   }
1474   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_EMBOSS ) )
1475   {
1476     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::EMBOSS );
1477   }
1478   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_OUTLINE ) )
1479   {
1480     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::OUTLINE );
1481   }
1482
1483   mInputStyleChangedSignal.Emit( handle, fieldInputStyleMask );
1484 }
1485
1486 void TextField::AddDecoration( Actor& actor, bool needsClipping )
1487 {
1488   if( actor )
1489   {
1490     if( needsClipping )
1491     {
1492       mClippingDecorationActors.push_back( actor );
1493     }
1494     else
1495     {
1496       Self().Add( actor );
1497     }
1498   }
1499 }
1500
1501 void TextField::OnStageConnect( Dali::Actor actor )
1502 {
1503   if ( mHasBeenStaged )
1504   {
1505     RenderText( static_cast<Text::Controller::UpdateTextType>( Text::Controller::MODEL_UPDATED | Text::Controller::DECORATOR_UPDATED ) );
1506   }
1507   else
1508   {
1509     mHasBeenStaged = true;
1510   }
1511 }
1512
1513 ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
1514 {
1515   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
1516   return mController->OnImfEvent( imfManager, imfEvent );
1517 }
1518
1519 void TextField::GetHandleImagePropertyValue(  Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType )
1520 {
1521   if( mDecorator )
1522   {
1523     ResourceImage image = ResourceImage::DownCast( mDecorator->GetHandleImage( handleType, handleImageType ) );
1524
1525     if ( image )
1526     {
1527       Property::Map map;
1528       Scripting::CreatePropertyMap( image, map );
1529       value = map;
1530     }
1531   }
1532 }
1533
1534 void TextField::EnableClipping( const Vector2& size )
1535 {
1536   if( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy )
1537   {
1538     // Not worth to created clip actor if width or height is equal to zero.
1539     if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
1540     {
1541       if( !mClipper )
1542       {
1543         Actor self = Self();
1544
1545         mClipper = Clipper::New( size );
1546         self.Add( mClipper->GetRootActor() );
1547         self.Add( mClipper->GetImageView() );
1548       }
1549       else if ( mClipper )
1550       {
1551         mClipper->Refresh( size );
1552       }
1553     }
1554   }
1555   else
1556   {
1557     // Note - this will automatically remove the root actor & the image view
1558     mClipper.Reset();
1559   }
1560 }
1561
1562 void TextField::OnClipboardTextSelected( ClipboardEventNotifier& clipboard )
1563 {
1564   mController->PasteClipboardItemEvent();
1565 }
1566
1567 void TextField::KeyboardStatusChanged(bool keyboardShown)
1568 {
1569   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown );
1570
1571   // Just hide the grab handle when keyboard is hidden.
1572   if (!keyboardShown )
1573   {
1574     mController->KeyboardFocusLostEvent();
1575   }
1576   else
1577   {
1578     mController->KeyboardFocusGainEvent(); // Initially called by OnKeyInputFocusGained
1579   }
1580 }
1581
1582 void TextField::OnStageConnection( int depth )
1583 {
1584   // Call the Control::OnStageConnection() to set the depth of the background.
1585   Control::OnStageConnection( depth );
1586
1587   // Sets the depth to the visuals inside the text's decorator.
1588   mDecorator->SetTextDepth( depth );
1589
1590   // The depth of the text renderer is set in the RenderText() called from OnRelayout().
1591 }
1592
1593 bool TextField::OnTouched( Actor actor, const TouchData& touch )
1594 {
1595   return true;
1596 }
1597
1598 void TextField::OnIdleSignal()
1599 {
1600   // Emits the change of input style signals.
1601   mController->ProcessInputStyleChangedSignals();
1602
1603   // Set the pointer to null as the callback manager deletes the callback after execute it.
1604   mIdleCallback = NULL;
1605 }
1606
1607 TextField::TextField()
1608 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
1609   mIdleCallback( NULL ),
1610   mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
1611   mExceedPolicy( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP ),
1612   mHasBeenStaged( false )
1613 {
1614 }
1615
1616 TextField::~TextField()
1617 {
1618   mClipper.Reset();
1619
1620   if( ( NULL != mIdleCallback ) && Adaptor::IsAvailable() )
1621   {
1622     Adaptor::Get().RemoveIdle( mIdleCallback );
1623   }
1624 }
1625
1626 } // namespace Internal
1627
1628 } // namespace Toolkit
1629
1630 } // namespace Dali