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