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