Merge "Changed text controls to re-apply style after system font size change" into...
[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       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
1172       break;
1173     }
1174     case StyleChange::THEME_CHANGE:
1175     {
1176       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
1177       break;
1178     }
1179   }
1180 }
1181
1182 Vector3 TextField::GetNaturalSize()
1183 {
1184   return mController->GetNaturalSize();
1185 }
1186
1187 float TextField::GetHeightForWidth( float width )
1188 {
1189   return mController->GetHeightForWidth( width );
1190 }
1191
1192 void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
1193 {
1194   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField OnRelayout\n");
1195
1196   const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
1197
1198   if( ( Text::Controller::NONE_UPDATED != updateTextType ) ||
1199       !mRenderer )
1200   {
1201     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnRelayout %p Displaying new contents\n", mController.Get() );
1202
1203     if( mDecorator &&
1204         ( Text::Controller::NONE_UPDATED != ( Text::Controller::DECORATOR_UPDATED & updateTextType ) ) )
1205     {
1206       mDecorator->Relayout( size );
1207     }
1208
1209     if( !mRenderer )
1210     {
1211       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
1212     }
1213
1214     EnableClipping( ( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy ), size );
1215     RenderText( updateTextType );
1216   }
1217 }
1218
1219 void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
1220 {
1221   Actor self = Self();
1222   Actor renderableActor;
1223
1224   if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) )
1225   {
1226     if( mRenderer )
1227     {
1228       renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT );
1229     }
1230
1231     if( renderableActor != mRenderableActor )
1232     {
1233       UnparentAndReset( mRenderableActor );
1234       mRenderableActor = renderableActor;
1235     }
1236   }
1237
1238   if( mRenderableActor )
1239   {
1240     const Vector2& scrollOffset = mController->GetScrollPosition();
1241
1242     mRenderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
1243
1244     Actor clipRootActor;
1245     if( mClipper )
1246     {
1247       clipRootActor = mClipper->GetRootActor();
1248     }
1249
1250     for( std::vector<Actor>::const_iterator it = mClippingDecorationActors.begin(),
1251            endIt = mClippingDecorationActors.end();
1252          it != endIt;
1253          ++it )
1254     {
1255       Actor actor = *it;
1256
1257       if( clipRootActor )
1258       {
1259         clipRootActor.Add( actor );
1260       }
1261       else
1262       {
1263         self.Add( actor );
1264       }
1265     }
1266     mClippingDecorationActors.clear();
1267
1268     // Make sure the actor is parented correctly with/without clipping
1269     if( clipRootActor )
1270     {
1271       clipRootActor.Add( mRenderableActor );
1272     }
1273     else
1274     {
1275       self.Add( mRenderableActor );
1276     }
1277   }
1278 }
1279
1280 void TextField::OnKeyInputFocusGained()
1281 {
1282   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyInputFocusGained %p\n", mController.Get() );
1283
1284   VirtualKeyboard::StatusChangedSignal().Connect( this, &TextField::KeyboardStatusChanged );
1285
1286   ImfManager imfManager = ImfManager::Get();
1287
1288   if ( imfManager )
1289   {
1290     imfManager.EventReceivedSignal().Connect( this, &TextField::OnImfEvent );
1291
1292     // Notify that the text editing start.
1293     imfManager.Activate();
1294
1295     // When window gain lost focus, the imf manager is deactivated. Thus when window gain focus again, the imf manager must be activated.
1296     imfManager.SetRestoreAfterFocusLost( true );
1297   }
1298
1299    ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
1300
1301    if ( notifier )
1302    {
1303       notifier.ContentSelectedSignal().Connect( this, &TextField::OnClipboardTextSelected );
1304    }
1305
1306   mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event
1307
1308   EmitKeyInputFocusSignal( true ); // Calls back into the Control hence done last.
1309 }
1310
1311 void TextField::OnKeyInputFocusLost()
1312 {
1313   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField:OnKeyInputFocusLost %p\n", mController.Get() );
1314
1315   VirtualKeyboard::StatusChangedSignal().Disconnect( this, &TextField::KeyboardStatusChanged );
1316
1317   ImfManager imfManager = ImfManager::Get();
1318   if ( imfManager )
1319   {
1320     // The text editing is finished. Therefore the imf manager don't have restore activation.
1321     imfManager.SetRestoreAfterFocusLost( false );
1322
1323     // Notify that the text editing finish.
1324     imfManager.Deactivate();
1325
1326     imfManager.EventReceivedSignal().Disconnect( this, &TextField::OnImfEvent );
1327   }
1328
1329   ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
1330
1331   if ( notifier )
1332   {
1333     notifier.ContentSelectedSignal().Disconnect( this, &TextField::OnClipboardTextSelected );
1334   }
1335
1336   mController->KeyboardFocusLostEvent();
1337
1338   EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
1339 }
1340
1341 void TextField::OnTap( const TapGesture& gesture )
1342 {
1343   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnTap %p\n", mController.Get() );
1344
1345   // Show the keyboard if it was hidden.
1346   if (!VirtualKeyboard::IsVisible())
1347   {
1348     VirtualKeyboard::Show();
1349   }
1350
1351   // Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures
1352   mController->TapEvent( gesture.numberOfTaps, gesture.localPoint.x, gesture.localPoint.y );
1353
1354   SetKeyInputFocus();
1355 }
1356
1357 void TextField::OnPan( const PanGesture& gesture )
1358 {
1359   mController->PanEvent( gesture.state, gesture.displacement );
1360 }
1361
1362 void TextField::OnLongPress( const LongPressGesture& gesture )
1363 {
1364   // Show the keyboard if it was hidden.
1365   if (!VirtualKeyboard::IsVisible())
1366   {
1367     VirtualKeyboard::Show();
1368   }
1369
1370   mController->LongPressEvent( gesture.state, gesture.localPoint.x, gesture.localPoint.y );
1371
1372   SetKeyInputFocus();
1373 }
1374
1375 bool TextField::OnKeyEvent( const KeyEvent& event )
1376 {
1377   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
1378
1379   if( Dali::DALI_KEY_ESCAPE == event.keyCode ||
1380       "Return" == event.keyPressedName ) // Make a Dali key code for this
1381   {
1382     ClearKeyInputFocus();
1383     return true;
1384   }
1385
1386   return mController->KeyEvent( event );
1387 }
1388
1389 void TextField::AddDecoration( Actor& actor, bool needsClipping )
1390 {
1391   if( actor )
1392   {
1393     if( needsClipping )
1394     {
1395       mClippingDecorationActors.push_back( actor );
1396     }
1397     else
1398     {
1399       Self().Add( actor );
1400     }
1401   }
1402 }
1403
1404 void TextField::RequestTextRelayout()
1405 {
1406   RelayoutRequest();
1407 }
1408
1409 void TextField::TextChanged()
1410 {
1411   Dali::Toolkit::TextField handle( GetOwner() );
1412   mTextChangedSignal.Emit( handle );
1413 }
1414
1415 void TextField::OnStageConnect( Dali::Actor actor )
1416 {
1417   if ( mHasBeenStaged )
1418   {
1419     RenderText( static_cast<Text::Controller::UpdateTextType>( Text::Controller::MODEL_UPDATED | Text::Controller::DECORATOR_UPDATED ) );
1420   }
1421   else
1422   {
1423     mHasBeenStaged = true;
1424   }
1425 }
1426
1427 void TextField::MaxLengthReached()
1428 {
1429   Dali::Toolkit::TextField handle( GetOwner() );
1430   mMaxLengthReachedSignal.Emit( handle );
1431 }
1432
1433 ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
1434 {
1435   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
1436   return mController->OnImfEvent( imfManager, imfEvent );
1437 }
1438
1439 void TextField::GetHandleImagePropertyValue(  Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType )
1440 {
1441   if( mDecorator )
1442   {
1443     ResourceImage image = ResourceImage::DownCast( mDecorator->GetHandleImage( handleType, handleImageType ) );
1444
1445     if ( image )
1446     {
1447       Property::Map map;
1448       Scripting::CreatePropertyMap( image, map );
1449       value = map;
1450     }
1451   }
1452 }
1453
1454 void TextField::EnableClipping( bool clipping, const Vector2& size )
1455 {
1456   if( clipping )
1457   {
1458     // Not worth to created clip actor if width or height is equal to zero.
1459     if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
1460     {
1461       if( !mClipper )
1462       {
1463         Actor self = Self();
1464
1465         mClipper = Clipper::New( size );
1466         self.Add( mClipper->GetRootActor() );
1467         self.Add( mClipper->GetImageView() );
1468       }
1469       else if ( mClipper )
1470       {
1471         mClipper->Refresh( size );
1472       }
1473     }
1474   }
1475   else
1476   {
1477     // Note - this will automatically remove the root actor & the image view
1478     mClipper.Reset();
1479   }
1480 }
1481
1482 void TextField::OnClipboardTextSelected( ClipboardEventNotifier& clipboard )
1483 {
1484   mController->PasteClipboardItemEvent();
1485 }
1486
1487 void TextField::KeyboardStatusChanged(bool keyboardShown)
1488 {
1489   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown );
1490
1491   // Just hide the grab handle when keyboard is hidden.
1492   if (!keyboardShown )
1493   {
1494     mController->KeyboardFocusLostEvent();
1495   }
1496   else
1497   {
1498     mController->KeyboardFocusGainEvent(); // Initially called by OnKeyInputFocusGained
1499   }
1500 }
1501
1502 void TextField::OnStageConnection( int depth )
1503 {
1504   // Call the Control::OnStageConnection() to set the depth of the background.
1505   Control::OnStageConnection( depth );
1506
1507   // Sets the depth to the visuals inside the text's decorator.
1508   mDecorator->SetTextDepth( depth );
1509
1510   // The depth of the text renderer is set in the RenderText() called from OnRelayout().
1511 }
1512
1513 bool TextField::OnTouched( Actor actor, const TouchData& touch )
1514 {
1515   return true;
1516 }
1517
1518 TextField::TextField()
1519 : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
1520   mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
1521   mExceedPolicy( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP ),
1522   mHasBeenStaged( false )
1523 {
1524 }
1525
1526 TextField::~TextField()
1527 {
1528   mClipper.Reset();
1529 }
1530
1531 } // namespace Internal
1532
1533 } // namespace Toolkit
1534
1535 } // namespace Dali