Merge "Updating test-suite to match core" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-field-impl.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/controls/text-controls/text-field-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <cstring>
23 #include <dali/public-api/adaptor-framework/key.h>
24 #include <dali/public-api/common/stage.h>
25 #include <dali/public-api/images/resource-image.h>
26 #include <dali/devel-api/adaptor-framework/virtual-keyboard.h>
27 #include <dali/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   // Enables the text input.
1118   mController->EnableTextInput( mDecorator );
1119
1120   // Enables the horizontal scrolling after the text input has been enabled.
1121   mController->SetHorizontalScrollEnabled( true );
1122
1123   // Disables the vertical scrolling.
1124   mController->SetVerticalScrollEnabled( false );
1125
1126   // Disable the smooth handle panning.
1127   mController->SetSmoothHandlePanEnabled( false );
1128
1129   // Forward input events to controller
1130   EnableGestureDetection( static_cast<Gesture::Type>( Gesture::Tap | Gesture::Pan | Gesture::LongPress ) );
1131   GetTapGestureDetector().SetMaximumTapsRequired( 2 );
1132
1133   self.TouchSignal().Connect( this, &TextField::OnTouched );
1134
1135   // Set BoundingBox to stage size if not already set.
1136   Rect<int> boundingBox;
1137   mDecorator->GetBoundingBox( boundingBox );
1138
1139   if( boundingBox.IsEmpty() )
1140   {
1141     Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
1142     mDecorator->SetBoundingBox( Rect<int>( 0.0f, 0.0f, stageSize.width, stageSize.height ) );
1143   }
1144
1145   // Flip vertically the 'left' selection handle
1146   mDecorator->FlipHandleVertically( LEFT_SELECTION_HANDLE, true );
1147
1148   // Fill-parent area by default
1149   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
1150   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
1151   self.OnStageSignal().Connect( this, &TextField::OnStageConnect );
1152 }
1153
1154 void TextField::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
1155 {
1156   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnStyleChange\n");
1157
1158   switch ( change )
1159   {
1160     case StyleChange::DEFAULT_FONT_CHANGE:
1161     {
1162       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnStyleChange DEFAULT_FONT_CHANGE\n");
1163       const std::string& newFont = GetImpl( styleManager ).GetDefaultFontFamily();
1164       // Property system did not set the font so should update it.
1165       mController->UpdateAfterFontChange( newFont );
1166       break;
1167     }
1168
1169     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
1170     {
1171       DALI_LOG_INFO( gLogFilter, Debug::General, "TextField::OnStyleChange StyleChange::DEFAULT_FONT_SIZE_CHANGE (%f)\n", mController->GetDefaultPointSize() );
1172
1173       if ( (mController->GetDefaultPointSize() <= 0.0f) ) // If DefaultPointSize not set by Property system it will be 0.0f
1174       {
1175         // Property system did not set the PointSize so should update it.
1176         // todo instruct text-controller to update model
1177       }
1178       break;
1179     }
1180     case StyleChange::THEME_CHANGE:
1181     {
1182       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
1183       break;
1184     }
1185   }
1186 }
1187
1188 Vector3 TextField::GetNaturalSize()
1189 {
1190   return mController->GetNaturalSize();
1191 }
1192
1193 float TextField::GetHeightForWidth( float width )
1194 {
1195   return mController->GetHeightForWidth( width );
1196 }
1197
1198 void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
1199 {
1200   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField OnRelayout\n");
1201
1202   const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
1203
1204   if( ( Text::Controller::NONE_UPDATED != updateTextType ) ||
1205       !mRenderer )
1206   {
1207     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnRelayout %p Displaying new contents\n", mController.Get() );
1208
1209     if( mDecorator &&
1210         ( Text::Controller::NONE_UPDATED != ( Text::Controller::DECORATOR_UPDATED & updateTextType ) ) )
1211     {
1212       mDecorator->Relayout( size );
1213     }
1214
1215     if( !mRenderer )
1216     {
1217       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
1218     }
1219
1220     EnableClipping( ( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy ), size );
1221     RenderText( updateTextType );
1222   }
1223 }
1224
1225 void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
1226 {
1227   Actor self = Self();
1228   Actor renderableActor;
1229
1230   if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) )
1231   {
1232     if( mRenderer )
1233     {
1234       renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT );
1235     }
1236
1237     if( renderableActor != mRenderableActor )
1238     {
1239       UnparentAndReset( mRenderableActor );
1240       mRenderableActor = renderableActor;
1241     }
1242   }
1243
1244   if( mRenderableActor )
1245   {
1246     const Vector2& scrollOffset = mController->GetScrollPosition();
1247
1248     mRenderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
1249
1250     Actor clipRootActor;
1251     if( mClipper )
1252     {
1253       clipRootActor = mClipper->GetRootActor();
1254     }
1255
1256     for( std::vector<Actor>::const_iterator it = mClippingDecorationActors.begin(),
1257            endIt = mClippingDecorationActors.end();
1258          it != endIt;
1259          ++it )
1260     {
1261       Actor actor = *it;
1262
1263       if( clipRootActor )
1264       {
1265         clipRootActor.Add( actor );
1266       }
1267       else
1268       {
1269         self.Add( actor );
1270       }
1271     }
1272     mClippingDecorationActors.clear();
1273
1274     // Make sure the actor is parented correctly with/without clipping
1275     if( clipRootActor )
1276     {
1277       clipRootActor.Add( mRenderableActor );
1278     }
1279     else
1280     {
1281       self.Add( mRenderableActor );
1282     }
1283   }
1284 }
1285
1286 void TextField::OnKeyInputFocusGained()
1287 {
1288   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyInputFocusGained %p\n", mController.Get() );
1289
1290   VirtualKeyboard::StatusChangedSignal().Connect( this, &TextField::KeyboardStatusChanged );
1291
1292   ImfManager imfManager = ImfManager::Get();
1293
1294   if ( imfManager )
1295   {
1296     imfManager.EventReceivedSignal().Connect( this, &TextField::OnImfEvent );
1297
1298     // Notify that the text editing start.
1299     imfManager.Activate();
1300
1301     // When window gain lost focus, the imf manager is deactivated. Thus when window gain focus again, the imf manager must be activated.
1302     imfManager.SetRestoreAfterFocusLost( true );
1303   }
1304
1305    ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
1306
1307    if ( notifier )
1308    {
1309       notifier.ContentSelectedSignal().Connect( this, &TextField::OnClipboardTextSelected );
1310    }
1311
1312   mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event
1313
1314   EmitKeyInputFocusSignal( true ); // Calls back into the Control hence done last.
1315 }
1316
1317 void TextField::OnKeyInputFocusLost()
1318 {
1319   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField:OnKeyInputFocusLost %p\n", mController.Get() );
1320
1321   VirtualKeyboard::StatusChangedSignal().Disconnect( this, &TextField::KeyboardStatusChanged );
1322
1323   ImfManager imfManager = ImfManager::Get();
1324   if ( imfManager )
1325   {
1326     // The text editing is finished. Therefore the imf manager don't have restore activation.
1327     imfManager.SetRestoreAfterFocusLost( false );
1328
1329     // Notify that the text editing finish.
1330     imfManager.Deactivate();
1331
1332     imfManager.EventReceivedSignal().Disconnect( this, &TextField::OnImfEvent );
1333   }
1334
1335   ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
1336
1337   if ( notifier )
1338   {
1339     notifier.ContentSelectedSignal().Disconnect( this, &TextField::OnClipboardTextSelected );
1340   }
1341
1342   mController->KeyboardFocusLostEvent();
1343
1344   EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
1345 }
1346
1347 void TextField::OnTap( const TapGesture& gesture )
1348 {
1349   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnTap %p\n", mController.Get() );
1350
1351   // Show the keyboard if it was hidden.
1352   if (!VirtualKeyboard::IsVisible())
1353   {
1354     VirtualKeyboard::Show();
1355   }
1356
1357   // Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures
1358   mController->TapEvent( gesture.numberOfTaps, gesture.localPoint.x, gesture.localPoint.y );
1359
1360   SetKeyInputFocus();
1361 }
1362
1363 void TextField::OnPan( const PanGesture& gesture )
1364 {
1365   mController->PanEvent( gesture.state, gesture.displacement );
1366 }
1367
1368 void TextField::OnLongPress( const LongPressGesture& gesture )
1369 {
1370   // Show the keyboard if it was hidden.
1371   if (!VirtualKeyboard::IsVisible())
1372   {
1373     VirtualKeyboard::Show();
1374   }
1375
1376   mController->LongPressEvent( gesture.state, gesture.localPoint.x, gesture.localPoint.y );
1377
1378   SetKeyInputFocus();
1379 }
1380
1381 bool TextField::OnKeyEvent( const KeyEvent& event )
1382 {
1383   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
1384
1385   if( Dali::DALI_KEY_ESCAPE == event.keyCode ||
1386       "Return" == event.keyPressedName ) // Make a Dali key code for this
1387   {
1388     ClearKeyInputFocus();
1389     return true;
1390   }
1391
1392   return mController->KeyEvent( event );
1393 }
1394
1395 void TextField::AddDecoration( Actor& actor, bool needsClipping )
1396 {
1397   if( actor )
1398   {
1399     if( needsClipping )
1400     {
1401       mClippingDecorationActors.push_back( actor );
1402     }
1403     else
1404     {
1405       Self().Add( actor );
1406     }
1407   }
1408 }
1409
1410 void TextField::RequestTextRelayout()
1411 {
1412   RelayoutRequest();
1413 }
1414
1415 void TextField::TextChanged()
1416 {
1417   Dali::Toolkit::TextField handle( GetOwner() );
1418   mTextChangedSignal.Emit( handle );
1419 }
1420
1421 void TextField::OnStageConnect( Dali::Actor actor )
1422 {
1423   if ( mHasBeenStaged )
1424   {
1425     RenderText( static_cast<Text::Controller::UpdateTextType>( Text::Controller::MODEL_UPDATED | Text::Controller::DECORATOR_UPDATED ) );
1426   }
1427   else
1428   {
1429     mHasBeenStaged = true;
1430   }
1431 }
1432
1433 void TextField::MaxLengthReached()
1434 {
1435   Dali::Toolkit::TextField handle( GetOwner() );
1436   mMaxLengthReachedSignal.Emit( handle );
1437 }
1438
1439 ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
1440 {
1441   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
1442   return mController->OnImfEvent( imfManager, imfEvent );
1443 }
1444
1445 void TextField::GetHandleImagePropertyValue(  Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType )
1446 {
1447   if( mDecorator )
1448   {
1449     ResourceImage image = ResourceImage::DownCast( mDecorator->GetHandleImage( handleType, handleImageType ) );
1450
1451     if ( image )
1452     {
1453       Property::Map map;
1454       Scripting::CreatePropertyMap( image, map );
1455       value = map;
1456     }
1457   }
1458 }
1459
1460 void TextField::EnableClipping( bool clipping, const Vector2& size )
1461 {
1462   if( clipping )
1463   {
1464     // Not worth to created clip actor if width or height is equal to zero.
1465     if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
1466     {
1467       if( !mClipper )
1468       {
1469         Actor self = Self();
1470
1471         mClipper = Clipper::New( size );
1472         self.Add( mClipper->GetRootActor() );
1473         self.Add( mClipper->GetImageView() );
1474       }
1475       else if ( mClipper )
1476       {
1477         mClipper->Refresh( size );
1478       }
1479     }
1480   }
1481   else
1482   {
1483     // Note - this will automatically remove the root actor & the image view
1484     mClipper.Reset();
1485   }
1486 }
1487
1488 void TextField::OnClipboardTextSelected( ClipboardEventNotifier& clipboard )
1489 {
1490   mController->PasteClipboardItemEvent();
1491 }
1492
1493 void TextField::KeyboardStatusChanged(bool keyboardShown)
1494 {
1495   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown );
1496
1497   // Just hide the grab handle when keyboard is hidden.
1498   if (!keyboardShown )
1499   {
1500     mController->KeyboardFocusLostEvent();
1501   }
1502   else
1503   {
1504     mController->KeyboardFocusGainEvent(); // Initially called by OnKeyInputFocusGained
1505   }
1506 }
1507
1508 void TextField::OnStageConnection( int depth )
1509 {
1510   // Call the Control::OnStageConnection() to set the depth of the background.
1511   Control::OnStageConnection( depth );
1512
1513   // Sets the depth to the visuals inside the text's decorator.
1514   mDecorator->SetTextDepth( depth );
1515
1516   // The depth of the text renderer is set in the RenderText() called from OnRelayout().
1517 }
1518
1519 bool TextField::OnTouched( Actor actor, const TouchData& touch )
1520 {
1521   return true;
1522 }
1523
1524 TextField::TextField()
1525 : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
1526   mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
1527   mExceedPolicy( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP ),
1528   mHasBeenStaged( false )
1529 {
1530 }
1531
1532 TextField::~TextField()
1533 {
1534   mClipper.Reset();
1535 }
1536
1537 } // namespace Internal
1538
1539 } // namespace Toolkit
1540
1541 } // namespace Dali