Markup procesor. Color
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-field-impl.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/controls/text-controls/text-field-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <cstring>
23 #include <dali/public-api/adaptor-framework/key.h>
24 #include <dali/public-api/common/stage.h>
25 #include <dali/public-api/images/resource-image.h>
26 #include <dali/devel-api/adaptor-framework/virtual-keyboard.h>
27 #include <dali/devel-api/object/type-registry-helper.h>
28 #include <dali/integration-api/debug.h>
29
30 // INTERNAL INCLUDES
31 #include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
32 #include <dali-toolkit/public-api/text/rendering-backend.h>
33 #include <dali-toolkit/internal/controls/text-controls/text-font-style.h>
34 #include <dali-toolkit/internal/text/rendering/text-backend.h>
35 #include <dali-toolkit/internal/text/text-view.h>
36 #include <dali-toolkit/internal/styling/style-manager-impl.h>
37
38 using namespace Dali::Toolkit::Text;
39
40 namespace Dali
41 {
42
43 namespace Toolkit
44 {
45
46 namespace Internal
47 {
48
49 namespace // unnamed namespace
50 {
51
52 #if defined(DEBUG_ENABLED)
53   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
54 #endif
55
56   const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
57 } // unnamed namespace
58
59 namespace
60 {
61
62 const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
63 {
64   { "BEGIN",  Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN  },
65   { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
66   { "END",    Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END    },
67 };
68 const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
69
70 const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
71 {
72   { "TOP",    Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP    },
73   { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
74   { "BOTTOM", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_BOTTOM },
75 };
76 const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
77
78 // Type registration
79 BaseHandle Create()
80 {
81   return Toolkit::TextField::New();
82 }
83
84 // Setup properties, signals and actions using the type-registry.
85 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextField, Toolkit::Control, Create );
86
87 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "renderingBackend",                     INTEGER,   RENDERING_BACKEND                    )
88 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "text",                                 STRING,    TEXT                                 )
89 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholderText",                      STRING,    PLACEHOLDER_TEXT                     )
90 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholderTextFocused",               STRING,    PLACEHOLDER_TEXT_FOCUSED             )
91 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "fontFamily",                           STRING,    FONT_FAMILY                          )
92 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "fontStyle",                            STRING,    FONT_STYLE                           )
93 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "pointSize",                            FLOAT,     POINT_SIZE                           )
94 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "maxLength",                            INTEGER,   MAX_LENGTH                           )
95 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "exceedPolicy",                         INTEGER,   EXCEED_POLICY                        )
96 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "horizontalAlignment",                  STRING,    HORIZONTAL_ALIGNMENT                 )
97 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "verticalAlignment",                    STRING,    VERTICAL_ALIGNMENT                   )
98 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "textColor",                            VECTOR4,   TEXT_COLOR                           )
99 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholderTextColor",                 VECTOR4,   PLACEHOLDER_TEXT_COLOR               )
100 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputColor",                           VECTOR4,   INPUT_COLOR                          )
101 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "shadowOffset",                         VECTOR2,   SHADOW_OFFSET                        )
102 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "shadowColor",                          VECTOR4,   SHADOW_COLOR                         )
103 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "primaryCursorColor",                   VECTOR4,   PRIMARY_CURSOR_COLOR                 )
104 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "secondaryCursorColor",                 VECTOR4,   SECONDARY_CURSOR_COLOR               )
105 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "enableCursorBlink",                    BOOLEAN,   ENABLE_CURSOR_BLINK                  )
106 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "cursorBlinkInterval",                  FLOAT,     CURSOR_BLINK_INTERVAL                )
107 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "cursorBlinkDuration",                  FLOAT,     CURSOR_BLINK_DURATION                )
108 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "cursorWidth",                          INTEGER,   CURSOR_WIDTH                         )
109 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "grabHandleImage",                      STRING,    GRAB_HANDLE_IMAGE                    )
110 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "grabHandlePressedImage",               STRING,    GRAB_HANDLE_PRESSED_IMAGE            )
111 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "scrollThreshold",                      FLOAT,     SCROLL_THRESHOLD                     )
112 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "scrollSpeed",                          FLOAT,     SCROLL_SPEED                         )
113 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandleImageLeft",             MAP,       SELECTION_HANDLE_IMAGE_LEFT          )
114 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandleImageRight",            MAP,       SELECTION_HANDLE_IMAGE_RIGHT         )
115 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandlePressedImageLeft",      MAP,       SELECTION_HANDLE_PRESSED_IMAGE_LEFT  )
116 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandlePressedImageRight",     MAP,       SELECTION_HANDLE_PRESSED_IMAGE_RIGHT )
117 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandleMarkerImageLeft",       MAP,       SELECTION_HANDLE_MARKER_IMAGE_LEFT   )
118 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandleMarkerImageRight",      MAP,       SELECTION_HANDLE_MARKER_IMAGE_RIGHT  )
119 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHighlightColor",              VECTOR4,   SELECTION_HIGHLIGHT_COLOR            )
120 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "decorationBoundingBox",                RECTANGLE, DECORATION_BOUNDING_BOX              )
121 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputMethodSettings",                  MAP,       INPUT_METHOD_SETTINGS                )
122
123 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged",        SIGNAL_TEXT_CHANGED )
124 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached",   SIGNAL_MAX_LENGTH_REACHED )
125
126 DALI_TYPE_REGISTRATION_END()
127
128 } // namespace
129
130 Toolkit::TextField TextField::New()
131 {
132   // Create the implementation, temporarily owned by this handle on stack
133   IntrusivePtr< TextField > impl = new TextField();
134
135   // Pass ownership to CustomActor handle
136   Toolkit::TextField handle( *impl );
137
138   // Second-phase init of the implementation
139   // This can only be done after the CustomActor connection has been made...
140   impl->Initialize();
141
142   return handle;
143 }
144
145 void TextField::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
146 {
147   Toolkit::TextField textField = Toolkit::TextField::DownCast( Dali::BaseHandle( object ) );
148
149   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField SetProperty\n");
150
151
152   if( textField )
153   {
154     TextField& impl( GetImpl( textField ) );
155
156     switch( index )
157     {
158       case Toolkit::TextField::Property::RENDERING_BACKEND:
159       {
160         int backend = value.Get< int >();
161         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend );
162
163         if( impl.mRenderingBackend != backend )
164         {
165           impl.mRenderingBackend = backend;
166           impl.mRenderer.Reset();
167           impl.RequestTextRelayout();
168         }
169         break;
170       }
171       case Toolkit::TextField::Property::TEXT:
172       {
173         if( impl.mController )
174         {
175           const std::string text = value.Get< std::string >();
176           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p TEXT %s\n", impl.mController.Get(), text.c_str() );
177
178           impl.mController->SetText( text );
179         }
180         break;
181       }
182       case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
183       {
184         if( impl.mController )
185         {
186           const std::string text = value.Get< std::string >();
187           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str() );
188
189           impl.mController->SetPlaceholderText( PLACEHOLDER_TYPE_INACTIVE, text );
190         }
191         break;
192       }
193       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_FOCUSED:
194       {
195         if( impl.mController )
196         {
197           const std::string text = value.Get< std::string >();
198           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_FOCUSED %s\n", impl.mController.Get(), text.c_str() );
199
200           impl.mController->SetPlaceholderText( PLACEHOLDER_TYPE_ACTIVE, text );
201         }
202         break;
203       }
204       case Toolkit::TextField::Property::FONT_FAMILY:
205       {
206         if( impl.mController )
207         {
208           const std::string fontFamily = value.Get< std::string >();
209           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
210           impl.mController->SetDefaultFontFamily( fontFamily );
211         }
212         break;
213       }
214       case Toolkit::TextField::Property::FONT_STYLE:
215       {
216         SetFontStyleProperty( impl.mController, value );
217         break;
218       }
219       case Toolkit::TextField::Property::POINT_SIZE:
220       {
221         if( impl.mController )
222         {
223           const float pointSize = value.Get< float >();
224           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p POINT_SIZE %f\n", impl.mController.Get(), pointSize );
225
226           if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
227           {
228             impl.mController->SetDefaultPointSize( pointSize );
229           }
230         }
231         break;
232       }
233       case Toolkit::TextField::Property::MAX_LENGTH:
234       {
235         if( impl.mController )
236         {
237           const int max = value.Get< int >();
238           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p MAX_LENGTH %d\n", impl.mController.Get(), max );
239
240           impl.mController->SetMaximumNumberOfCharacters( max );
241         }
242         break;
243       }
244       case Toolkit::TextField::Property::EXCEED_POLICY:
245       {
246         // TODO
247         break;
248       }
249       case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
250       {
251         if( impl.mController )
252         {
253           const std::string alignStr = value.Get< std::string >();
254           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %s\n", impl.mController.Get(), alignStr.c_str() );
255
256           LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
257           if( Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
258                                                                               HORIZONTAL_ALIGNMENT_STRING_TABLE,
259                                                                               HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
260                                                                               alignment ) )
261           {
262             impl.mController->SetHorizontalAlignment( alignment );
263           }
264         }
265         break;
266       }
267       case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
268       {
269         if( impl.mController )
270         {
271           const std::string alignStr = value.Get< std::string >();
272           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %s\n", impl.mController.Get(), alignStr.c_str() );
273
274           LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
275           if( Scripting::GetEnumeration< LayoutEngine::VerticalAlignment >( alignStr.c_str(),
276                                                                             VERTICAL_ALIGNMENT_STRING_TABLE,
277                                                                             VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
278                                                                             alignment ) )
279           {
280             impl.mController->SetVerticalAlignment( alignment );
281           }
282         }
283         break;
284       }
285       case Toolkit::TextField::Property::TEXT_COLOR:
286       {
287         if( impl.mController )
288         {
289           const Vector4 textColor = value.Get< Vector4 >();
290           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 );
291
292           if( impl.mController->GetTextColor() != textColor )
293           {
294             impl.mController->SetTextColor( textColor );
295             impl.mController->SetInputColor( textColor );
296             impl.mRenderer.Reset();
297           }
298         }
299         break;
300       }
301       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
302       {
303         if( impl.mController )
304         {
305           const Vector4 textColor = value.Get< Vector4 >();
306           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 );
307
308           if( impl.mController->GetPlaceholderTextColor() != textColor )
309           {
310             impl.mController->SetPlaceholderTextColor( textColor );
311             impl.mRenderer.Reset();
312           }
313         }
314         break;
315       }
316       case Toolkit::TextField::Property::INPUT_COLOR:
317       {
318         if( impl.mController )
319         {
320           const Vector4 inputColor = value.Get< Vector4 >();
321           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 );
322
323           impl.mController->SetInputColor( inputColor );
324         }
325         break;
326       }
327       case Toolkit::TextField::Property::SHADOW_OFFSET:
328       {
329         if( impl.mController )
330         {
331           const Vector2 shadowOffset = value.Get< Vector2 >();
332           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SHADOW_OFFSET %f,%f\n", impl.mController.Get(), shadowOffset.x, shadowOffset.y );
333
334           if ( impl.mController->GetShadowOffset() != shadowOffset )
335           {
336             impl.mController->SetShadowOffset( shadowOffset );
337             impl.mRenderer.Reset();
338           }
339         }
340         break;
341       }
342       case Toolkit::TextField::Property::SHADOW_COLOR:
343       {
344         if( impl.mController )
345         {
346           const Vector4 shadowColor = value.Get< Vector4 >();
347           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 );
348
349           if ( impl.mController->GetShadowColor() != shadowColor )
350           {
351             impl.mController->SetShadowColor( shadowColor );
352             impl.mRenderer.Reset();
353           }
354         }
355         break;
356       }
357       case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
358       {
359         if( impl.mDecorator )
360         {
361           const Vector4 color = value.Get< Vector4 >();
362           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 );
363
364           impl.mDecorator->SetCursorColor( PRIMARY_CURSOR, color );
365           impl.RequestTextRelayout();
366         }
367         break;
368       }
369       case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
370       {
371         if( impl.mDecorator )
372         {
373           const Vector4 color = value.Get< Vector4 >();
374           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 );
375
376           impl.mDecorator->SetCursorColor( SECONDARY_CURSOR, color );
377           impl.RequestTextRelayout();
378         }
379         break;
380       }
381       case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
382       {
383         if( impl.mController )
384         {
385           const bool enable = value.Get< bool >();
386           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable );
387
388           impl.mController->SetEnableCursorBlink( enable );
389           impl.RequestTextRelayout();
390         }
391         break;
392       }
393       case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
394       {
395         if( impl.mDecorator )
396         {
397           const float interval = value.Get< float >();
398           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval );
399
400           impl.mDecorator->SetCursorBlinkInterval( interval );
401         }
402         break;
403       }
404       case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
405       {
406         if( impl.mDecorator )
407         {
408           const float duration = value.Get< float >();
409           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration );
410
411           impl.mDecorator->SetCursorBlinkDuration( duration );
412         }
413         break;
414       }
415       case Toolkit::TextField::Property::CURSOR_WIDTH:
416       {
417         if( impl.mDecorator )
418         {
419           const int width = value.Get< int >();
420           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_WIDTH %d\n", impl.mController.Get(), width );
421
422           impl.mDecorator->SetCursorWidth( width );
423           impl.mController->GetLayoutEngine().SetCursorWidth( width );
424         }
425         break;
426       }
427       case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
428       {
429         const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
430         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), image.GetUrl().c_str() );
431
432         if( impl.mDecorator )
433         {
434           impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED, image );
435           impl.RequestTextRelayout();
436         }
437         break;
438       }
439       case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
440       {
441         const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
442         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), image.GetUrl().c_str() );
443
444         if( impl.mDecorator )
445         {
446           impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED, image );
447           impl.RequestTextRelayout();
448         }
449         break;
450       }
451       case Toolkit::TextField::Property::SCROLL_THRESHOLD:
452       {
453         const float threshold = value.Get< float >();
454         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold );
455
456         if( impl.mDecorator )
457         {
458           impl.mDecorator->SetScrollThreshold( threshold );
459         }
460         break;
461       }
462       case Toolkit::TextField::Property::SCROLL_SPEED:
463       {
464         const float speed = value.Get< float >();
465         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SCROLL_SPEED %f\n", impl.mController.Get(), speed );
466
467         if( impl.mDecorator )
468         {
469           impl.mDecorator->SetScrollSpeed( speed );
470         }
471         break;
472       }
473       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
474       {
475         const Image image = Scripting::NewImage( value );
476
477         if( impl.mDecorator && image )
478         {
479           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
480           impl.RequestTextRelayout();
481         }
482         break;
483       }
484       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
485       {
486         const Image image = Scripting::NewImage( value );
487
488         if( impl.mDecorator && image )
489         {
490           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
491           impl.RequestTextRelayout();
492         }
493         break;
494       }
495       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
496       {
497         const Image image = Scripting::NewImage( value );
498
499         if( impl.mDecorator && image )
500         {
501           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, image );
502           impl.RequestTextRelayout();
503         }
504         break;
505       }
506       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
507       {
508         const Image image = Scripting::NewImage( value );
509
510         if( impl.mDecorator && image )
511         {
512           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, image );
513           impl.RequestTextRelayout();
514         }
515         break;
516       }
517       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
518       {
519         const Image image = Scripting::NewImage( value );
520
521         if( impl.mDecorator && image )
522         {
523           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, image );
524           impl.RequestTextRelayout();
525         }
526         break;
527       }
528       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
529       {
530         const Image image = Scripting::NewImage( value );
531
532         if( impl.mDecorator && image )
533         {
534           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, image );
535           impl.RequestTextRelayout();
536         }
537         break;
538       }
539       case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
540       {
541         const Vector4 color = value.Get< Vector4 >();
542         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 );
543
544         if( impl.mDecorator )
545         {
546           impl.mDecorator->SetHighlightColor( color );
547           impl.RequestTextRelayout();
548         }
549         break;
550       }
551       case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
552       {
553         if( impl.mDecorator )
554         {
555           const Rect<int> box = value.Get< Rect<int> >();
556           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 );
557
558           impl.mDecorator->SetBoundingBox( box );
559           impl.RequestTextRelayout();
560         }
561         break;
562       }
563       case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
564       {
565         const Property::Map map = value.Get<Property::Map>();
566         VirtualKeyboard::ApplySettings( map );
567         break;
568       }
569     } // switch
570   } // textfield
571 }
572
573 Property::Value TextField::GetProperty( BaseObject* object, Property::Index index )
574 {
575   Property::Value value;
576
577   Toolkit::TextField textField = Toolkit::TextField::DownCast( Dali::BaseHandle( object ) );
578
579   if( textField )
580   {
581     TextField& impl( GetImpl( textField ) );
582
583     switch( index )
584     {
585       case Toolkit::TextField::Property::RENDERING_BACKEND:
586       {
587         value = impl.mRenderingBackend;
588         break;
589       }
590       case Toolkit::TextField::Property::TEXT:
591       {
592         if( impl.mController )
593         {
594           std::string text;
595           impl.mController->GetText( text );
596           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p returning text: %s\n", impl.mController.Get(), text.c_str() );
597           value = text;
598         }
599         break;
600       }
601       case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
602       {
603         if( impl.mController )
604         {
605           std::string text;
606           impl.mController->GetPlaceholderText( PLACEHOLDER_TYPE_INACTIVE, text );
607           value = text;
608         }
609         break;
610       }
611       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_FOCUSED:
612       {
613         if( impl.mController )
614         {
615           std::string text;
616           impl.mController->GetPlaceholderText( PLACEHOLDER_TYPE_ACTIVE, text );
617           value = text;
618         }
619         break;
620       }
621       case Toolkit::TextField::Property::FONT_FAMILY:
622       {
623         if( impl.mController )
624         {
625           value = impl.mController->GetDefaultFontFamily();
626         }
627         break;
628       }
629       case Toolkit::TextField::Property::FONT_STYLE:
630       {
631         GetFontStyleProperty( impl.mController, value );
632         break;
633       }
634       case Toolkit::TextField::Property::POINT_SIZE:
635       {
636         if( impl.mController )
637         {
638           value = impl.mController->GetDefaultPointSize();
639         }
640         break;
641       }
642       case Toolkit::TextField::Property::MAX_LENGTH:
643       {
644         if( impl.mController )
645         {
646           value = impl.mController->GetMaximumNumberOfCharacters();
647         }
648         break;
649       }
650       case Toolkit::TextField::Property::EXCEED_POLICY:
651       {
652         value = impl.mExceedPolicy;
653         break;
654       }
655       case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
656       {
657         if( impl.mController )
658         {
659           const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
660                                                                                                                 HORIZONTAL_ALIGNMENT_STRING_TABLE,
661                                                                                                                 HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
662           if( name )
663           {
664             value = std::string( name );
665           }
666         }
667         break;
668       }
669       case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
670       {
671         if( impl.mController )
672         {
673           const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetLayoutEngine().GetVerticalAlignment(),
674                                                                                                               VERTICAL_ALIGNMENT_STRING_TABLE,
675                                                                                                               VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
676           if( name )
677           {
678             value = std::string( name );
679           }
680         }
681         break;
682       }
683       case Toolkit::TextField::Property::TEXT_COLOR:
684       {
685         if ( impl.mController )
686         {
687           value = impl.mController->GetTextColor();
688         }
689         break;
690       }
691       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
692       {
693         if ( impl.mController )
694         {
695           value = impl.mController->GetPlaceholderTextColor();
696         }
697         break;
698       }
699       case Toolkit::TextField::Property::INPUT_COLOR:
700       {
701         if( impl.mController )
702         {
703           value = impl.mController->GetInputColor();
704         }
705         break;
706       }
707       case Toolkit::TextField::Property::SHADOW_OFFSET:
708       {
709         if ( impl.mController )
710         {
711           value = impl.mController->GetShadowOffset();
712         }
713         break;
714       }
715       case Toolkit::TextField::Property::SHADOW_COLOR:
716       {
717         if ( impl.mController )
718         {
719           value = impl.mController->GetShadowColor();
720         }
721         break;
722       }
723       case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
724       {
725         if( impl.mDecorator )
726         {
727           value = impl.mDecorator->GetColor( PRIMARY_CURSOR );
728         }
729         break;
730       }
731       case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
732       {
733         if( impl.mDecorator )
734         {
735           value = impl.mDecorator->GetColor( SECONDARY_CURSOR );
736         }
737         break;
738       }
739       case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
740       {
741         value = impl.mController->GetEnableCursorBlink();
742         break;
743       }
744       case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
745       {
746         if( impl.mDecorator )
747         {
748           value = impl.mDecorator->GetCursorBlinkInterval();
749         }
750         break;
751       }
752       case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
753       {
754         if( impl.mDecorator )
755         {
756           value = impl.mDecorator->GetCursorBlinkDuration();
757         }
758         break;
759       }
760       case Toolkit::TextField::Property::CURSOR_WIDTH:
761       {
762         if( impl.mDecorator )
763         {
764           value = impl.mDecorator->GetCursorWidth();
765         }
766         break;
767       }
768       case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
769       {
770         if( impl.mDecorator )
771         {
772           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED ) );
773           if( image )
774           {
775             value = image.GetUrl();
776           }
777         }
778         break;
779       }
780       case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
781       {
782         if( impl.mDecorator )
783         {
784           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED ) );
785           if( image )
786           {
787             value = image.GetUrl();
788           }
789         }
790         break;
791       }
792       case Toolkit::TextField::Property::SCROLL_THRESHOLD:
793       {
794         if( impl.mDecorator )
795         {
796           value = impl.mDecorator->GetScrollThreshold();
797         }
798         break;
799       }
800       case Toolkit::TextField::Property::SCROLL_SPEED:
801       {
802         if( impl.mDecorator )
803         {
804           value = impl.mDecorator->GetScrollSpeed();
805         }
806         break;
807       }
808       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
809       {
810         impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED );
811         break;
812       }
813       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
814       {
815         impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED ) ;
816         break;
817       }
818       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
819       {
820         impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED );
821         break;
822       }
823       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
824       {
825         impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED );
826         break;
827       }
828       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
829       {
830         impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED );
831         break;
832       }
833       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
834       {
835         impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED );
836         break;
837       }
838       case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
839       {
840         if( impl.mDecorator )
841         {
842           value = impl.mDecorator->GetHighlightColor();
843         }
844         break;
845       }
846       case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
847       {
848         if( impl.mDecorator )
849         {
850           Rect<int> boundingBox;
851           impl.mDecorator->GetBoundingBox( boundingBox );
852           value = boundingBox;
853         }
854         break;
855       }
856       case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
857       {
858         break;
859       }
860     } //switch
861   }
862
863   return value;
864 }
865
866 bool TextField::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
867 {
868   Dali::BaseHandle handle( object );
869
870   bool connected( true );
871   Toolkit::TextField field = Toolkit::TextField::DownCast( handle );
872
873   if( 0 == strcmp( signalName.c_str(), SIGNAL_TEXT_CHANGED ) )
874   {
875     field.TextChangedSignal().Connect( tracker, functor );
876   }
877   else if( 0 == strcmp( signalName.c_str(), SIGNAL_MAX_LENGTH_REACHED ) )
878   {
879     field.MaxLengthReachedSignal().Connect( tracker, functor );
880   }
881   else
882   {
883     // signalName does not match any signal
884     connected = false;
885   }
886
887   return connected;
888 }
889
890 Toolkit::TextField::TextChangedSignalType& TextField::TextChangedSignal()
891 {
892   return mTextChangedSignal;
893 }
894
895 Toolkit::TextField::MaxLengthReachedSignalType& TextField::MaxLengthReachedSignal()
896 {
897   return mMaxLengthReachedSignal;
898 }
899
900 void TextField::OnInitialize()
901 {
902   Actor self = Self();
903
904   mController = Text::Controller::New( *this );
905
906   mDecorator = Text::Decorator::New( *mController,
907                                      *mController );
908
909   mController->GetLayoutEngine().SetLayout( LayoutEngine::SINGLE_LINE_BOX );
910
911   mController->EnableTextInput( mDecorator );
912
913   // Forward input events to controller
914   EnableGestureDetection( static_cast<Gesture::Type>( Gesture::Tap | Gesture::Pan | Gesture::LongPress ) );
915   GetTapGestureDetector().SetMaximumTapsRequired( 2 );
916
917   self.TouchedSignal().Connect( this, &TextField::OnTouched );
918
919   // Set BoundingBox to stage size if not already set.
920   Rect<int> boundingBox;
921   mDecorator->GetBoundingBox( boundingBox );
922
923   if( boundingBox.IsEmpty() )
924   {
925     Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
926     mDecorator->SetBoundingBox( Rect<int>( 0.0f, 0.0f, stageSize.width, stageSize.height ) );
927   }
928
929   // Flip vertically the 'left' selection handle
930   mDecorator->FlipHandleVertically( LEFT_SELECTION_HANDLE, true );
931
932   // Fill-parent area by default
933   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
934   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
935   self.OnStageSignal().Connect( this, &TextField::OnStageConnect );
936 }
937
938 void TextField::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
939 {
940   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnStyleChange\n");
941
942    switch ( change )
943    {
944      case StyleChange::DEFAULT_FONT_CHANGE:
945      {
946        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnStyleChange DEFAULT_FONT_CHANGE\n");
947        std::string newFont = styleManager.GetDefaultFontFamily();
948        // Property system did not set the font so should update it.
949        mController->UpdateAfterFontChange( newFont );
950        break;
951      }
952
953      case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
954      {
955        DALI_LOG_INFO( gLogFilter, Debug::General, "TextField::OnStyleChange StyleChange::DEFAULT_FONT_SIZE_CHANGE (%f)\n", mController->GetDefaultPointSize() );
956
957        if ( (mController->GetDefaultPointSize() <= 0.0f) ) // If DefaultPointSize not set by Property system it will be 0.0f
958        {
959          // Property system did not set the PointSize so should update it.
960          // todo instruct text-controller to update model
961        }
962        break;
963      }
964      case StyleChange::THEME_CHANGE:
965      {
966        GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
967        break;
968      }
969    }
970 }
971
972 Vector3 TextField::GetNaturalSize()
973 {
974   return mController->GetNaturalSize();
975 }
976
977 float TextField::GetHeightForWidth( float width )
978 {
979   return mController->GetHeightForWidth( width );
980 }
981
982 void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
983 {
984   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField OnRelayout\n");
985
986   if( mController->Relayout( size ) ||
987       !mRenderer )
988   {
989     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnRelayout %p Displaying new contents\n", mController.Get() );
990
991     if( mDecorator )
992     {
993       mDecorator->Relayout( size );
994     }
995
996     if( !mRenderer )
997     {
998       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
999     }
1000
1001     EnableClipping( (Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy), size );
1002     RenderText();
1003   }
1004 }
1005
1006 void TextField::RenderText()
1007 {
1008   Actor self = Self();
1009   Actor renderableActor;
1010   if( mRenderer )
1011   {
1012     renderableActor = mRenderer->Render( mController->GetView(), TEXT_DEPTH_INDEX );
1013   }
1014
1015   if( renderableActor != mRenderableActor )
1016   {
1017     UnparentAndReset( mRenderableActor );
1018     mRenderableActor = renderableActor;
1019   }
1020
1021   if( mRenderableActor )
1022   {
1023     const Vector2 offset = mController->GetScrollPosition() + mController->GetAlignmentOffset();
1024
1025     mRenderableActor.SetPosition( offset.x, offset.y );
1026
1027     Actor clipRootActor;
1028     if( mClipper )
1029     {
1030       clipRootActor = mClipper->GetRootActor();
1031     }
1032
1033     for( std::vector<Actor>::const_iterator it = mClippingDecorationActors.begin(),
1034            endIt = mClippingDecorationActors.end();
1035          it != endIt;
1036          ++it )
1037     {
1038       Actor actor = *it;
1039
1040       if( clipRootActor )
1041       {
1042         clipRootActor.Add( actor );
1043       }
1044       else
1045       {
1046         self.Add( actor );
1047       }
1048     }
1049     mClippingDecorationActors.clear();
1050
1051     // Make sure the actor is parented correctly with/without clipping
1052     if( clipRootActor )
1053     {
1054       clipRootActor.Add( mRenderableActor );
1055     }
1056     else
1057     {
1058       self.Add( mRenderableActor );
1059     }
1060   }
1061 }
1062
1063 void TextField::OnKeyInputFocusGained()
1064 {
1065   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyInputFocusGained %p\n", mController.Get() );
1066
1067   VirtualKeyboard::StatusChangedSignal().Connect( this, &TextField::KeyboardStatusChanged );
1068
1069   ImfManager imfManager = ImfManager::Get();
1070
1071   if ( imfManager )
1072   {
1073     imfManager.EventReceivedSignal().Connect( this, &TextField::OnImfEvent );
1074
1075     // Notify that the text editing start.
1076     imfManager.Activate();
1077
1078     // When window gain lost focus, the imf manager is deactivated. Thus when window gain focus again, the imf manager must be activated.
1079     imfManager.SetRestoreAfterFocusLost( true );
1080   }
1081
1082    ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
1083
1084    if ( notifier )
1085    {
1086       notifier.ContentSelectedSignal().Connect( this, &TextField::OnClipboardTextSelected );
1087    }
1088
1089   mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event
1090
1091   EmitKeyInputFocusSignal( true ); // Calls back into the Control hence done last.
1092 }
1093
1094 void TextField::OnKeyInputFocusLost()
1095 {
1096   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField:OnKeyInputFocusLost %p\n", mController.Get() );
1097
1098   VirtualKeyboard::StatusChangedSignal().Disconnect( this, &TextField::KeyboardStatusChanged );
1099
1100   ImfManager imfManager = ImfManager::Get();
1101   if ( imfManager )
1102   {
1103     // The text editing is finished. Therefore the imf manager don't have restore activation.
1104     imfManager.SetRestoreAfterFocusLost( false );
1105
1106     // Notify that the text editing finish.
1107     imfManager.Deactivate();
1108
1109     imfManager.EventReceivedSignal().Disconnect( this, &TextField::OnImfEvent );
1110   }
1111
1112   ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
1113
1114   if ( notifier )
1115   {
1116     notifier.ContentSelectedSignal().Disconnect( this, &TextField::OnClipboardTextSelected );
1117   }
1118
1119   mController->KeyboardFocusLostEvent();
1120
1121   EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
1122 }
1123
1124 void TextField::OnTap( const TapGesture& gesture )
1125 {
1126   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnTap %p\n", mController.Get() );
1127
1128   // Show the keyboard if it was hidden.
1129   if (!VirtualKeyboard::IsVisible())
1130   {
1131     VirtualKeyboard::Show();
1132   }
1133
1134   // Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures
1135   mController->TapEvent( gesture.numberOfTaps, gesture.localPoint.x, gesture.localPoint.y );
1136
1137   SetKeyInputFocus();
1138 }
1139
1140 void TextField::OnPan( const PanGesture& gesture )
1141 {
1142   mController->PanEvent( gesture.state, gesture.displacement );
1143 }
1144
1145 void TextField::OnLongPress( const LongPressGesture& gesture )
1146 {
1147   // Show the keyboard if it was hidden.
1148   if (!VirtualKeyboard::IsVisible())
1149   {
1150     VirtualKeyboard::Show();
1151   }
1152
1153   mController->LongPressEvent( gesture.state, gesture.localPoint.x, gesture.localPoint.y );
1154
1155   SetKeyInputFocus();
1156 }
1157
1158 bool TextField::OnKeyEvent( const KeyEvent& event )
1159 {
1160   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
1161
1162   if( Dali::DALI_KEY_ESCAPE == event.keyCode ||
1163       "Return" == event.keyPressedName ) // Make a Dali key code for this
1164   {
1165     ClearKeyInputFocus();
1166     return true;
1167   }
1168
1169   return mController->KeyEvent( event );
1170 }
1171
1172 void TextField::AddDecoration( Actor& actor, bool needsClipping )
1173 {
1174   if( actor )
1175   {
1176     if( needsClipping )
1177     {
1178       mClippingDecorationActors.push_back( actor );
1179     }
1180     else
1181     {
1182       Self().Add( actor );
1183     }
1184   }
1185 }
1186
1187 void TextField::RequestTextRelayout()
1188 {
1189   RelayoutRequest();
1190 }
1191
1192 void TextField::TextChanged()
1193 {
1194   Dali::Toolkit::TextField handle( GetOwner() );
1195   mTextChangedSignal.Emit( handle );
1196 }
1197
1198 void TextField::OnStageConnect( Dali::Actor actor )
1199 {
1200   if ( mHasBeenStaged )
1201   {
1202     RenderText();
1203   }
1204   else
1205   {
1206     mHasBeenStaged = true;
1207   }
1208 }
1209
1210 void TextField::MaxLengthReached()
1211 {
1212   Dali::Toolkit::TextField handle( GetOwner() );
1213   mMaxLengthReachedSignal.Emit( handle );
1214 }
1215
1216 ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
1217 {
1218   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
1219   return mController->OnImfEvent( imfManager, imfEvent );
1220 }
1221
1222 void TextField::GetHandleImagePropertyValue(  Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType )
1223 {
1224   if( mDecorator )
1225   {
1226     ResourceImage image = ResourceImage::DownCast( mDecorator->GetHandleImage( handleType, handleImageType ) );
1227
1228     if ( image )
1229     {
1230       Property::Map map;
1231       Scripting::CreatePropertyMap( image, map );
1232       value = map;
1233     }
1234   }
1235 }
1236
1237 void TextField::EnableClipping( bool clipping, const Vector2& size )
1238 {
1239   if( clipping )
1240   {
1241     // Not worth to created clip actor if width or height is equal to zero.
1242     if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
1243     {
1244       if( !mClipper )
1245       {
1246         Actor self = Self();
1247
1248         mClipper = Clipper::New( size );
1249         self.Add( mClipper->GetRootActor() );
1250         self.Add( mClipper->GetImageActor() );
1251       }
1252       else if ( mClipper )
1253       {
1254         mClipper->Refresh( size );
1255       }
1256     }
1257   }
1258   else
1259   {
1260     // Note - this will automatically remove the root & image actors
1261     mClipper.Reset();
1262   }
1263 }
1264
1265 void TextField::OnClipboardTextSelected( ClipboardEventNotifier& clipboard )
1266 {
1267   mController->PasteClipboardItemEvent();
1268 }
1269
1270 void TextField::KeyboardStatusChanged(bool keyboardShown)
1271 {
1272   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown );
1273
1274   // Just hide the grab handle when keyboard is hidden.
1275   if (!keyboardShown )
1276   {
1277     mController->KeyboardFocusLostEvent();
1278   }
1279   else
1280   {
1281     mController->KeyboardFocusGainEvent(); // Initially called by OnKeyInputFocusGained
1282   }
1283 }
1284
1285 void TextField::OnStageConnection( int depth )
1286 {
1287   // Call the Control::OnStageConnection() to set the depth of the background.
1288   Control::OnStageConnection( depth );
1289
1290   // Sets the depth to the renderers inside the text's decorator.
1291   mDecorator->SetTextDepth( depth );
1292
1293   // The depth of the text renderer is set in the RenderText() called from OnRelayout().
1294 }
1295
1296 bool TextField::OnTouched( Actor actor, const TouchEvent& event )
1297 {
1298   return true;
1299 }
1300
1301 TextField::TextField()
1302 : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
1303   mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
1304   mExceedPolicy( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP ),
1305   mHasBeenStaged( false )
1306 {
1307 }
1308
1309 TextField::~TextField()
1310 {
1311   mClipper.Reset();
1312 }
1313
1314 } // namespace Internal
1315
1316 } // namespace Toolkit
1317
1318 } // namespace Dali