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