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