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