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