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