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