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