Revert "[Tizen] Revert "Changes after touch consumed behaviour change""
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-field-impl.cpp
1 /*
2  * Copyright (c) 2020 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/devel-api/adaptor-framework/key-devel.h>
25 #include <dali/devel-api/adaptor-framework/window-devel.h>
26 #include <dali/devel-api/common/stage.h>
27 #include <dali/devel-api/object/property-helper-devel.h>
28 #include <dali/devel-api/actors/actor-devel.h>
29 #include <dali/public-api/object/type-registry-helper.h>
30 #include <dali/integration-api/debug.h>
31
32 // INTERNAL INCLUDES
33 #include <dali-toolkit/public-api/text/text-enumerations.h>
34 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
35 #include <dali-toolkit/devel-api/text/rendering-backend.h>
36 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
37 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
38 #include <dali-toolkit/devel-api/controls/text-controls/text-field-devel.h>
39 #include <dali-toolkit/public-api/visuals/visual-properties.h>
40 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
41 #include <dali-toolkit/internal/controls/text-controls/autofill-container-impl.h>
42 #include <dali-toolkit/internal/text/text-enumerations-impl.h>
43 #include <dali-toolkit/internal/text/rendering/text-backend.h>
44 #include <dali-toolkit/internal/text/text-effects-style.h>
45 #include <dali-toolkit/internal/text/text-font-style.h>
46 #include <dali-toolkit/internal/text/text-view.h>
47 #include <dali-toolkit/internal/styling/style-manager-impl.h>
48 #include <dali-toolkit/devel-api/controls/control-devel.h>
49 #include <dali/integration-api/adaptor-framework/adaptor.h>
50
51 using namespace Dali::Toolkit::Text;
52
53 namespace Dali
54 {
55
56 namespace Toolkit
57 {
58
59 namespace Internal
60 {
61
62 namespace // unnamed namespace
63 {
64
65 #if defined(DEBUG_ENABLED)
66   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
67 #endif
68
69   const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::DevelText::DEFAULT_RENDERING_BACKEND;
70 } // unnamed namespace
71
72 namespace
73 {
74 // Type registration
75 BaseHandle Create()
76 {
77   return Toolkit::TextField::New();
78 }
79
80 // Setup properties, signals and actions using the type-registry.
81 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextField, Toolkit::Control, Create );
82
83 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "text",                                 STRING,    TEXT                                 )
84 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholderText",                      STRING,    PLACEHOLDER_TEXT                     )
85 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholderTextFocused",               STRING,    PLACEHOLDER_TEXT_FOCUSED             )
86 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "fontFamily",                           STRING,    FONT_FAMILY                          )
87 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "fontStyle",                            MAP,       FONT_STYLE                           )
88 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "pointSize",                            FLOAT,     POINT_SIZE                           )
89 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "maxLength",                            INTEGER,   MAX_LENGTH                           )
90 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "exceedPolicy",                         INTEGER,   EXCEED_POLICY                        )
91 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "horizontalAlignment",                  STRING,    HORIZONTAL_ALIGNMENT                 )
92 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "verticalAlignment",                    STRING,    VERTICAL_ALIGNMENT                   )
93 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "textColor",                            VECTOR4,   TEXT_COLOR                           )
94 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholderTextColor",                 VECTOR4,   PLACEHOLDER_TEXT_COLOR               )
95 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "primaryCursorColor",                   VECTOR4,   PRIMARY_CURSOR_COLOR                 )
96 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "secondaryCursorColor",                 VECTOR4,   SECONDARY_CURSOR_COLOR               )
97 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "enableCursorBlink",                    BOOLEAN,   ENABLE_CURSOR_BLINK                  )
98 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "cursorBlinkInterval",                  FLOAT,     CURSOR_BLINK_INTERVAL                )
99 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "cursorBlinkDuration",                  FLOAT,     CURSOR_BLINK_DURATION                )
100 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "cursorWidth",                          INTEGER,   CURSOR_WIDTH                         )
101 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "grabHandleImage",                      STRING,    GRAB_HANDLE_IMAGE                    )
102 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "grabHandlePressedImage",               STRING,    GRAB_HANDLE_PRESSED_IMAGE            )
103 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "scrollThreshold",                      FLOAT,     SCROLL_THRESHOLD                     )
104 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "scrollSpeed",                          FLOAT,     SCROLL_SPEED                         )
105 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandleImageLeft",             MAP,       SELECTION_HANDLE_IMAGE_LEFT          )
106 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandleImageRight",            MAP,       SELECTION_HANDLE_IMAGE_RIGHT         )
107 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandlePressedImageLeft",      MAP,       SELECTION_HANDLE_PRESSED_IMAGE_LEFT  )
108 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandlePressedImageRight",     MAP,       SELECTION_HANDLE_PRESSED_IMAGE_RIGHT )
109 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandleMarkerImageLeft",       MAP,       SELECTION_HANDLE_MARKER_IMAGE_LEFT   )
110 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHandleMarkerImageRight",      MAP,       SELECTION_HANDLE_MARKER_IMAGE_RIGHT  )
111 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selectionHighlightColor",              VECTOR4,   SELECTION_HIGHLIGHT_COLOR            )
112 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "decorationBoundingBox",                RECTANGLE, DECORATION_BOUNDING_BOX              )
113 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputMethodSettings",                  MAP,       INPUT_METHOD_SETTINGS                )
114 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputColor",                           VECTOR4,   INPUT_COLOR                          )
115 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "enableMarkup",                         BOOLEAN,   ENABLE_MARKUP                        )
116 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputFontFamily",                      STRING,    INPUT_FONT_FAMILY                    )
117 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputFontStyle",                       MAP,       INPUT_FONT_STYLE                     )
118 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputPointSize",                       FLOAT,     INPUT_POINT_SIZE                     )
119 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "underline",                            MAP,       UNDERLINE                            )
120 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputUnderline",                       MAP,       INPUT_UNDERLINE                      )
121 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "shadow",                               MAP,       SHADOW                               )
122 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputShadow",                          MAP,       INPUT_SHADOW                         )
123 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "emboss",                               MAP,       EMBOSS                               )
124 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputEmboss",                          MAP,       INPUT_EMBOSS                         )
125 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "outline",                              MAP,       OUTLINE                              )
126 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "inputOutline",                         MAP,       INPUT_OUTLINE                        )
127 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "hiddenInputSettings",                  MAP,       HIDDEN_INPUT_SETTINGS                )
128 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "pixelSize",                            FLOAT,     PIXEL_SIZE                           )
129 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "enableSelection",                      BOOLEAN,   ENABLE_SELECTION                     )
130 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholder",                          MAP,       PLACEHOLDER                          )
131 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "ellipsis",                             BOOLEAN,   ELLIPSIS                             )
132 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableShiftSelection",           BOOLEAN,   ENABLE_SHIFT_SELECTION               )
133 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableGrabHandle",               BOOLEAN,   ENABLE_GRAB_HANDLE                   )
134 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "matchSystemLanguageDirection",   BOOLEAN,   MATCH_SYSTEM_LANGUAGE_DIRECTION      )
135 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "enableGrabHandlePopup",          BOOLEAN,   ENABLE_GRAB_HANDLE_POPUP             )
136 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "textBackground",                 VECTOR4,   BACKGROUND                           )
137 DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextField, "selectedText",         STRING,    SELECTED_TEXT                        )
138 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextField, "renderingBackend",               INTEGER,   RENDERING_BACKEND                    )
139
140 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "textChanged",        SIGNAL_TEXT_CHANGED )
141 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "maxLengthReached",   SIGNAL_MAX_LENGTH_REACHED )
142 DALI_SIGNAL_REGISTRATION( Toolkit, TextField, "inputStyleChanged",  SIGNAL_INPUT_STYLE_CHANGED )
143
144 DALI_TYPE_REGISTRATION_END()
145
146 const char * const IMAGE_MAP_FILENAME_STRING = "filename";
147
148 /// Retrieves a filename from a value that is a Property::Map
149 std::string GetImageFileNameFromPropertyValue( const Property::Value& value )
150 {
151   std::string filename;
152   const Property::Map* map = value.GetMap();
153   if( map )
154   {
155     const Property::Value* filenameValue = map->Find( IMAGE_MAP_FILENAME_STRING );
156     if( filenameValue )
157     {
158       filenameValue->Get( filename );
159     }
160   }
161   return filename;
162 }
163
164 } // namespace
165
166 Toolkit::TextField TextField::New()
167 {
168   // Create the implementation, temporarily owned by this handle on stack
169   IntrusivePtr< TextField > impl = new TextField();
170
171   // Pass ownership to CustomActor handle
172   Toolkit::TextField handle( *impl );
173
174   // Second-phase init of the implementation
175   // This can only be done after the CustomActor connection has been made...
176   impl->Initialize();
177
178   return handle;
179 }
180
181 void TextField::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
182 {
183   Toolkit::TextField textField = Toolkit::TextField::DownCast( Dali::BaseHandle( object ) );
184
185   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField SetProperty\n");
186
187
188   if( textField )
189   {
190     TextField& impl( GetImpl( textField ) );
191
192     switch( index )
193     {
194       case Toolkit::DevelTextField::Property::RENDERING_BACKEND:
195       {
196         int backend = value.Get< int >();
197         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend );
198
199 #ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
200         if( DevelText::RENDERING_VECTOR_BASED == backend )
201         {
202           backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering
203         }
204 #endif
205         if( impl.mRenderingBackend != backend )
206         {
207           impl.mRenderingBackend = backend;
208           impl.mRenderer.Reset();
209
210           if( impl.mController )
211           {
212             // When using the vector-based rendering, the size of the GLyphs are different
213             TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
214             impl.mController->SetGlyphType( glyphType );
215           }
216         }
217         break;
218       }
219       case Toolkit::TextField::Property::TEXT:
220       {
221         if( impl.mController )
222         {
223           const std::string& text = value.Get< std::string >();
224           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p TEXT %s\n", impl.mController.Get(), text.c_str() );
225
226           impl.mController->SetText( text );
227         }
228         break;
229       }
230       case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
231       {
232         if( impl.mController )
233         {
234           const std::string& text = value.Get< std::string >();
235           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str() );
236
237           impl.mController->SetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
238         }
239         break;
240       }
241       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_FOCUSED:
242       {
243         if( impl.mController )
244         {
245           const std::string& text = value.Get< std::string >();
246           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_FOCUSED %s\n", impl.mController.Get(), text.c_str() );
247
248           impl.mController->SetPlaceholderText( Controller::PLACEHOLDER_TYPE_ACTIVE, text );
249         }
250         break;
251       }
252       case Toolkit::TextField::Property::FONT_FAMILY:
253       {
254         if( impl.mController )
255         {
256           const std::string& fontFamily = value.Get< std::string >();
257           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
258           impl.mController->SetDefaultFontFamily( fontFamily );
259         }
260         break;
261       }
262       case Toolkit::TextField::Property::FONT_STYLE:
263       {
264         SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
265         break;
266       }
267       case Toolkit::TextField::Property::POINT_SIZE:
268       {
269         if( impl.mController )
270         {
271           const float pointSize = value.Get< float >();
272           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p POINT_SIZE %f\n", impl.mController.Get(), pointSize );
273
274           if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE ), pointSize ) )
275           {
276             impl.mController->SetDefaultFontSize( pointSize, Text::Controller::POINT_SIZE );
277           }
278         }
279         break;
280       }
281       case Toolkit::TextField::Property::MAX_LENGTH:
282       {
283         if( impl.mController )
284         {
285           const int max = value.Get< int >();
286           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p MAX_LENGTH %d\n", impl.mController.Get(), max );
287
288           impl.mController->SetMaximumNumberOfCharacters( max );
289         }
290         break;
291       }
292       case Toolkit::TextField::Property::EXCEED_POLICY:
293       {
294         impl.mExceedPolicy = value.Get<int>();
295
296         if( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == impl.mExceedPolicy )
297         {
298           impl.EnableClipping();
299         }
300         else
301         {
302           UnparentAndReset( impl.mStencil );
303         }
304         impl.RequestTextRelayout();
305         break;
306       }
307       case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
308       {
309         if( impl.mController )
310         {
311           Text::HorizontalAlignment::Type alignment( static_cast< Text::HorizontalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
312           if( GetHorizontalAlignmentEnumeration( value, alignment ) )
313           {
314             DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %d\n", impl.mController.Get(), alignment );
315             impl.mController->SetHorizontalAlignment( alignment );
316           }
317         }
318         break;
319       }
320       case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
321       {
322         if( impl.mController )
323         {
324           Toolkit::Text::VerticalAlignment::Type alignment( static_cast< Text::VerticalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
325           if( GetVerticalAlignmentEnumeration( value, alignment ) )
326           {
327             impl.mController->SetVerticalAlignment( alignment );
328             DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %d\n", impl.mController.Get(), alignment );
329           }
330         }
331         break;
332       }
333       case Toolkit::TextField::Property::TEXT_COLOR:
334       {
335         if( impl.mController )
336         {
337           const Vector4& textColor = value.Get< Vector4 >();
338           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 );
339
340           if( impl.mController->GetDefaultColor() != textColor )
341           {
342             impl.mController->SetDefaultColor( textColor );
343             impl.mController->SetInputColor( textColor );
344             impl.mRenderer.Reset();
345           }
346         }
347         break;
348       }
349       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
350       {
351         if( impl.mController )
352         {
353           const Vector4& textColor = value.Get< Vector4 >();
354           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 );
355
356           if( impl.mController->GetPlaceholderTextColor() != textColor )
357           {
358             impl.mController->SetPlaceholderTextColor( textColor );
359             impl.mRenderer.Reset();
360           }
361         }
362         break;
363       }
364       case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
365       {
366         if( impl.mDecorator )
367         {
368           const Vector4& color = value.Get< Vector4 >();
369           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 );
370
371           impl.mDecorator->SetCursorColor( PRIMARY_CURSOR, color );
372           impl.RequestTextRelayout();
373         }
374         break;
375       }
376       case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
377       {
378         if( impl.mDecorator )
379         {
380           const Vector4& color = value.Get< Vector4 >();
381           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 );
382
383           impl.mDecorator->SetCursorColor( SECONDARY_CURSOR, color );
384           impl.RequestTextRelayout();
385         }
386         break;
387       }
388       case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
389       {
390         if( impl.mController )
391         {
392           const bool enable = value.Get< bool >();
393           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable );
394
395           impl.mController->SetEnableCursorBlink( enable );
396           impl.RequestTextRelayout();
397         }
398         break;
399       }
400       case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
401       {
402         if( impl.mDecorator )
403         {
404           const float interval = value.Get< float >();
405           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval );
406
407           impl.mDecorator->SetCursorBlinkInterval( interval );
408         }
409         break;
410       }
411       case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
412       {
413         if( impl.mDecorator )
414         {
415           const float duration = value.Get< float >();
416           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration );
417
418           impl.mDecorator->SetCursorBlinkDuration( duration );
419         }
420         break;
421       }
422       case Toolkit::TextField::Property::CURSOR_WIDTH:
423       {
424         if( impl.mDecorator )
425         {
426           const int width = value.Get< int >();
427           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_WIDTH %d\n", impl.mController.Get(), width );
428
429           impl.mDecorator->SetCursorWidth( width );
430           impl.mController->GetLayoutEngine().SetCursorWidth( width );
431         }
432         break;
433       }
434       case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
435       {
436         const std::string imageFileName = value.Get< std::string >();
437         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str() );
438
439         if( impl.mDecorator && imageFileName.size() )
440         {
441           impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED, imageFileName );
442           impl.RequestTextRelayout();
443         }
444         break;
445       }
446       case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
447       {
448         const std::string imageFileName = value.Get< std::string >();
449         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), imageFileName.c_str() );
450
451         if( impl.mDecorator && imageFileName.size() )
452         {
453           impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED, imageFileName );
454           impl.RequestTextRelayout();
455         }
456         break;
457       }
458       case Toolkit::TextField::Property::SCROLL_THRESHOLD:
459       {
460         const float threshold = value.Get< float >();
461         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold );
462
463         if( impl.mDecorator )
464         {
465           impl.mDecorator->SetScrollThreshold( threshold );
466         }
467         break;
468       }
469       case Toolkit::TextField::Property::SCROLL_SPEED:
470       {
471         const float speed = value.Get< float >();
472         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SCROLL_SPEED %f\n", impl.mController.Get(), speed );
473
474         if( impl.mDecorator )
475         {
476           impl.mDecorator->SetScrollSpeed( speed );
477         }
478         break;
479       }
480       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
481       {
482         const std::string filename = GetImageFileNameFromPropertyValue( value );
483
484         if( impl.mDecorator && filename.size() )
485         {
486           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename );
487           impl.RequestTextRelayout();
488         }
489         break;
490       }
491       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
492       {
493         const std::string filename = GetImageFileNameFromPropertyValue( value );
494
495         if( impl.mDecorator && filename.size() )
496         {
497           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, filename );
498           impl.RequestTextRelayout();
499         }
500         break;
501       }
502       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
503       {
504         const std::string filename = GetImageFileNameFromPropertyValue( value );
505
506         if( impl.mDecorator && filename.size() )
507         {
508           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename );
509           impl.RequestTextRelayout();
510         }
511         break;
512       }
513       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
514       {
515         const std::string filename = GetImageFileNameFromPropertyValue( value );
516
517         if( impl.mDecorator && filename.size() )
518         {
519           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, filename );
520           impl.RequestTextRelayout();
521         }
522         break;
523       }
524       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
525       {
526         const std::string filename = GetImageFileNameFromPropertyValue( value );
527
528         if( impl.mDecorator && filename.size() )
529         {
530           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename );
531           impl.RequestTextRelayout();
532         }
533         break;
534       }
535       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
536       {
537         const std::string filename = GetImageFileNameFromPropertyValue( value );
538
539         if( impl.mDecorator && filename.size() )
540         {
541           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, filename );
542           impl.RequestTextRelayout();
543         }
544         break;
545       }
546       case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
547       {
548         const Vector4 color = value.Get< Vector4 >();
549         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 );
550
551         if( impl.mDecorator )
552         {
553           impl.mDecorator->SetHighlightColor( color );
554           impl.RequestTextRelayout();
555         }
556         break;
557       }
558       case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
559       {
560         if( impl.mDecorator )
561         {
562           const Rect<int> box = value.Get< Rect<int> >();
563           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 );
564
565           impl.mDecorator->SetBoundingBox( box );
566           impl.RequestTextRelayout();
567         }
568         break;
569       }
570       case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
571       {
572         const Property::Map* map = value.GetMap();
573         if (map)
574         {
575           impl.mInputMethodOptions.ApplyProperty( *map );
576         }
577         impl.mController->SetInputModePassword( impl.mInputMethodOptions.IsPassword() );
578
579         Toolkit::Control control = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
580         if (control == textField)
581         {
582           impl.mInputMethodContext.ApplyOptions( impl.mInputMethodOptions );
583         }
584         break;
585       }
586       case Toolkit::TextField::Property::INPUT_COLOR:
587       {
588         if( impl.mController )
589         {
590           const Vector4 inputColor = value.Get< Vector4 >();
591           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 );
592
593           impl.mController->SetInputColor( inputColor );
594         }
595         break;
596       }
597       case Toolkit::TextField::Property::ENABLE_MARKUP:
598       {
599         if( impl.mController )
600         {
601           const bool enableMarkup = value.Get<bool>();
602           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup );
603
604           impl.mController->SetMarkupProcessorEnabled( enableMarkup );
605         }
606         break;
607       }
608       case Toolkit::TextField::Property::INPUT_FONT_FAMILY:
609       {
610         if( impl.mController )
611         {
612           const std::string& fontFamily = value.Get< std::string >();
613           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
614           impl.mController->SetInputFontFamily( fontFamily );
615         }
616         break;
617       }
618       case Toolkit::TextField::Property::INPUT_FONT_STYLE:
619       {
620         SetFontStyleProperty( impl.mController, value, Text::FontStyle::INPUT );
621         break;
622       }
623       case Toolkit::TextField::Property::INPUT_POINT_SIZE:
624       {
625         if( impl.mController )
626         {
627           const float pointSize = value.Get< float >();
628           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize );
629           impl.mController->SetInputFontPointSize( pointSize );
630         }
631         break;
632       }
633       case Toolkit::TextField::Property::UNDERLINE:
634       {
635         const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
636         if( update )
637         {
638           impl.mRenderer.Reset();
639         }
640         break;
641       }
642       case Toolkit::TextField::Property::INPUT_UNDERLINE:
643       {
644         const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::INPUT );
645         if( update )
646         {
647           impl.mRenderer.Reset();
648         }
649         break;
650       }
651       case Toolkit::TextField::Property::SHADOW:
652       {
653         const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
654         if( update )
655         {
656           impl.mRenderer.Reset();
657         }
658         break;
659       }
660       case Toolkit::TextField::Property::INPUT_SHADOW:
661       {
662         const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::INPUT );
663         if( update )
664         {
665           impl.mRenderer.Reset();
666         }
667         break;
668       }
669       case Toolkit::TextField::Property::EMBOSS:
670       {
671         const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
672         if( update )
673         {
674           impl.mRenderer.Reset();
675         }
676         break;
677       }
678       case Toolkit::TextField::Property::INPUT_EMBOSS:
679       {
680         const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::INPUT );
681         if( update )
682         {
683           impl.mRenderer.Reset();
684         }
685         break;
686       }
687       case Toolkit::TextField::Property::OUTLINE:
688       {
689         const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
690         if( update )
691         {
692           impl.mRenderer.Reset();
693         }
694         break;
695       }
696       case Toolkit::TextField::Property::INPUT_OUTLINE:
697       {
698         const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::INPUT );
699         if( update )
700         {
701           impl.mRenderer.Reset();
702         }
703         break;
704       }
705       case Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS:
706       {
707         const Property::Map* map = value.GetMap();
708         if (map)
709         {
710           impl.mController->SetHiddenInputOption(*map);
711         }
712         break;
713       }
714       case Toolkit::TextField::Property::PIXEL_SIZE:
715       {
716         if( impl.mController )
717         {
718           const float pixelSize = value.Get< float >();
719           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize );
720
721           if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE ), pixelSize ) )
722           {
723             impl.mController->SetDefaultFontSize( pixelSize, Text::Controller::PIXEL_SIZE );
724           }
725         }
726         break;
727       }
728       case Toolkit::TextField::Property::ENABLE_SELECTION:
729       {
730         if( impl.mController )
731         {
732           const bool enableSelection = value.Get< bool >();
733            DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_SELECTION %d\n", impl.mController.Get(), enableSelection );
734           impl.mController->SetSelectionEnabled( enableSelection );
735         }
736         break;
737       }
738       case Toolkit::TextField::Property::PLACEHOLDER:
739       {
740         const Property::Map* map = value.GetMap();
741         if( map )
742         {
743           impl.mController->SetPlaceholderProperty( *map );
744         }
745         break;
746       }
747       case Toolkit::TextField::Property::ELLIPSIS:
748       {
749         if( impl.mController )
750         {
751           const bool ellipsis = value.Get<bool>();
752           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis );
753
754           impl.mController->SetTextElideEnabled( ellipsis );
755         }
756         break;
757       }
758       case Toolkit::DevelTextField::Property::ENABLE_SHIFT_SELECTION:
759       {
760         if( impl.mController )
761         {
762           const bool shiftSelection = value.Get<bool>();
763           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_SHIFT_SELECTION %d\n", impl.mController.Get(), shiftSelection );
764
765           impl.mController->SetShiftSelectionEnabled( shiftSelection );
766         }
767         break;
768       }
769       case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE:
770       {
771         if( impl.mController )
772         {
773           const bool grabHandleEnabled = value.Get<bool>();
774           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE %d\n", impl.mController.Get(), grabHandleEnabled );
775
776           impl.mController->SetGrabHandleEnabled( grabHandleEnabled );
777         }
778         break;
779       }
780       case Toolkit::DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
781       {
782         if( impl.mController )
783         {
784           impl.mController->SetMatchSystemLanguageDirection(value.Get< bool >());
785         }
786         break;
787       }
788       case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
789       {
790         if( impl.mController )
791         {
792           const bool grabHandlePopupEnabled = value.Get<bool>();
793           DALI_LOG_INFO(gLogFilter, Debug::General, "TextField %p ENABLE_GRAB_HANDLE_POPUP %d\n", impl.mController.Get(), grabHandlePopupEnabled);
794
795           impl.mController->SetGrabHandlePopupEnabled(grabHandlePopupEnabled);
796           break;
797         }
798       }
799       case Toolkit::DevelTextField::Property::BACKGROUND:
800       {
801         if( impl.mController )
802         {
803           const Vector4 backgroundColor = value.Get< Vector4 >();
804           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p BACKGROUND %f,%f,%f,%f\n", impl.mController.Get(), backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a );
805
806           impl.mController->SetBackgroundEnabled( true );
807           impl.mController->SetBackgroundColor( backgroundColor );
808         }
809         break;
810       }
811     } // switch
812   } // textfield
813 }
814
815 Property::Value TextField::GetProperty( BaseObject* object, Property::Index index )
816 {
817   Property::Value value;
818
819   Toolkit::TextField textField = Toolkit::TextField::DownCast( Dali::BaseHandle( object ) );
820
821   if( textField )
822   {
823     TextField& impl( GetImpl( textField ) );
824
825     switch( index )
826     {
827       case Toolkit::DevelTextField::Property::RENDERING_BACKEND:
828       {
829         value = impl.mRenderingBackend;
830         break;
831       }
832       case Toolkit::TextField::Property::TEXT:
833       {
834         if( impl.mController )
835         {
836           std::string text;
837           impl.mController->GetText( text );
838           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p returning text: %s\n", impl.mController.Get(), text.c_str() );
839           value = text;
840         }
841         break;
842       }
843       case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
844       {
845         if( impl.mController )
846         {
847           std::string text;
848           impl.mController->GetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
849           value = text;
850         }
851         break;
852       }
853       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_FOCUSED:
854       {
855         if( impl.mController )
856         {
857           std::string text;
858           impl.mController->GetPlaceholderText( Controller::PLACEHOLDER_TYPE_ACTIVE, text );
859           value = text;
860         }
861         break;
862       }
863       case Toolkit::TextField::Property::FONT_FAMILY:
864       {
865         if( impl.mController )
866         {
867           value = impl.mController->GetDefaultFontFamily();
868         }
869         break;
870       }
871       case Toolkit::TextField::Property::FONT_STYLE:
872       {
873         GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
874         break;
875       }
876       case Toolkit::TextField::Property::POINT_SIZE:
877       {
878         if( impl.mController )
879         {
880           value = impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE );
881         }
882         break;
883       }
884       case Toolkit::TextField::Property::MAX_LENGTH:
885       {
886         if( impl.mController )
887         {
888           value = impl.mController->GetMaximumNumberOfCharacters();
889         }
890         break;
891       }
892       case Toolkit::TextField::Property::EXCEED_POLICY:
893       {
894         value = impl.mExceedPolicy;
895         break;
896       }
897       case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
898       {
899         if( impl.mController )
900         {
901           const char* name = Text::GetHorizontalAlignmentString( impl.mController->GetHorizontalAlignment() );
902
903           if ( name )
904           {
905             value = std::string( name );
906           }
907         }
908         break;
909       }
910       case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
911       {
912         if( impl.mController )
913         {
914           const char* name = Text::GetVerticalAlignmentString( impl.mController->GetVerticalAlignment() );
915
916           if( name )
917           {
918             value = std::string( name );
919           }
920         }
921         break;
922       }
923       case Toolkit::TextField::Property::TEXT_COLOR:
924       {
925         if ( impl.mController )
926         {
927           value = impl.mController->GetDefaultColor();
928         }
929         break;
930       }
931       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
932       {
933         if ( impl.mController )
934         {
935           value = impl.mController->GetPlaceholderTextColor();
936         }
937         break;
938       }
939       case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
940       {
941         if( impl.mDecorator )
942         {
943           value = impl.mDecorator->GetColor( PRIMARY_CURSOR );
944         }
945         break;
946       }
947       case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
948       {
949         if( impl.mDecorator )
950         {
951           value = impl.mDecorator->GetColor( SECONDARY_CURSOR );
952         }
953         break;
954       }
955       case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
956       {
957         value = impl.mController->GetEnableCursorBlink();
958         break;
959       }
960       case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
961       {
962         if( impl.mDecorator )
963         {
964           value = impl.mDecorator->GetCursorBlinkInterval();
965         }
966         break;
967       }
968       case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
969       {
970         if( impl.mDecorator )
971         {
972           value = impl.mDecorator->GetCursorBlinkDuration();
973         }
974         break;
975       }
976       case Toolkit::TextField::Property::CURSOR_WIDTH:
977       {
978         if( impl.mDecorator )
979         {
980           value = impl.mDecorator->GetCursorWidth();
981         }
982         break;
983       }
984       case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
985       {
986         if( impl.mDecorator )
987         {
988           value = impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED );
989         }
990         break;
991       }
992       case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
993       {
994         if( impl.mDecorator )
995         {
996           value = impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED );
997         }
998         break;
999       }
1000       case Toolkit::TextField::Property::SCROLL_THRESHOLD:
1001       {
1002         if( impl.mDecorator )
1003         {
1004           value = impl.mDecorator->GetScrollThreshold();
1005         }
1006         break;
1007       }
1008       case Toolkit::TextField::Property::SCROLL_SPEED:
1009       {
1010         if( impl.mDecorator )
1011         {
1012           value = impl.mDecorator->GetScrollSpeed();
1013         }
1014         break;
1015       }
1016       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
1017       {
1018         impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED );
1019         break;
1020       }
1021       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
1022       {
1023         impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED ) ;
1024         break;
1025       }
1026       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
1027       {
1028         impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED );
1029         break;
1030       }
1031       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
1032       {
1033         impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED );
1034         break;
1035       }
1036       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
1037       {
1038         impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED );
1039         break;
1040       }
1041       case Toolkit::TextField::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
1042       {
1043         impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED );
1044         break;
1045       }
1046       case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
1047       {
1048         if( impl.mDecorator )
1049         {
1050           value = impl.mDecorator->GetHighlightColor();
1051         }
1052         break;
1053       }
1054       case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
1055       {
1056         if( impl.mDecorator )
1057         {
1058           Rect<int> boundingBox;
1059           impl.mDecorator->GetBoundingBox( boundingBox );
1060           value = boundingBox;
1061         }
1062         break;
1063       }
1064       case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
1065       {
1066         Property::Map map;
1067         impl.mInputMethodOptions.RetrieveProperty( map );
1068         value = map;
1069         break;
1070       }
1071       case Toolkit::TextField::Property::INPUT_COLOR:
1072       {
1073         if( impl.mController )
1074         {
1075           value = impl.mController->GetInputColor();
1076         }
1077         break;
1078       }
1079       case Toolkit::TextField::Property::ENABLE_MARKUP:
1080       {
1081         if( impl.mController )
1082         {
1083           value = impl.mController->IsMarkupProcessorEnabled();
1084         }
1085         break;
1086       }
1087       case Toolkit::TextField::Property::INPUT_FONT_FAMILY:
1088       {
1089         if( impl.mController )
1090         {
1091           value = impl.mController->GetInputFontFamily();
1092         }
1093         break;
1094       }
1095       case Toolkit::TextField::Property::INPUT_FONT_STYLE:
1096       {
1097         GetFontStyleProperty( impl.mController, value, Text::FontStyle::INPUT );
1098         break;
1099       }
1100       case Toolkit::TextField::Property::INPUT_POINT_SIZE:
1101       {
1102         if( impl.mController )
1103         {
1104           value = impl.mController->GetInputFontPointSize();
1105         }
1106         break;
1107       }
1108       case Toolkit::TextField::Property::UNDERLINE:
1109       {
1110         GetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
1111         break;
1112       }
1113       case Toolkit::TextField::Property::INPUT_UNDERLINE:
1114       {
1115         GetUnderlineProperties( impl.mController, value, Text::EffectStyle::INPUT );
1116         break;
1117       }
1118       case Toolkit::TextField::Property::SHADOW:
1119       {
1120         GetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
1121         break;
1122       }
1123       case Toolkit::TextField::Property::INPUT_SHADOW:
1124       {
1125         GetShadowProperties( impl.mController, value, Text::EffectStyle::INPUT );
1126         break;
1127       }
1128       case Toolkit::TextField::Property::EMBOSS:
1129       {
1130         GetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
1131         break;
1132       }
1133       case Toolkit::TextField::Property::INPUT_EMBOSS:
1134       {
1135         GetEmbossProperties( impl.mController, value, Text::EffectStyle::INPUT );
1136         break;
1137       }
1138       case Toolkit::TextField::Property::OUTLINE:
1139       {
1140         GetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
1141         break;
1142       }
1143       case Toolkit::TextField::Property::INPUT_OUTLINE:
1144       {
1145         GetOutlineProperties( impl.mController, value, Text::EffectStyle::INPUT );
1146         break;
1147       }
1148       case Toolkit::TextField::Property::HIDDEN_INPUT_SETTINGS:
1149       {
1150         Property::Map map;
1151         impl.mController->GetHiddenInputOption(map);
1152         value = map;
1153         break;
1154       }
1155       case Toolkit::TextField::Property::PIXEL_SIZE:
1156       {
1157         if( impl.mController )
1158         {
1159           value = impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE );
1160         }
1161         break;
1162       }
1163       case Toolkit::TextField::Property::ENABLE_SELECTION:
1164       {
1165         if( impl.mController )
1166         {
1167           value = impl.mController->IsSelectionEnabled();
1168         }
1169         break;
1170       }
1171       case Toolkit::TextField::Property::PLACEHOLDER:
1172       {
1173         Property::Map map;
1174         impl.mController->GetPlaceholderProperty( map );
1175         value = map;
1176         break;
1177       }
1178       case Toolkit::TextField::Property::ELLIPSIS:
1179       {
1180         if( impl.mController )
1181         {
1182           value = impl.mController->IsTextElideEnabled();
1183         }
1184         break;
1185       }
1186       case Toolkit::DevelTextField::Property::ENABLE_SHIFT_SELECTION:
1187       {
1188         if( impl.mController )
1189         {
1190           value = impl.mController->IsShiftSelectionEnabled();
1191         }
1192         break;
1193       }
1194       case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE:
1195       {
1196         if( impl.mController )
1197         {
1198           value = impl.mController->IsGrabHandleEnabled();
1199         }
1200         break;
1201       }
1202       case Toolkit::DevelTextField::Property::MATCH_SYSTEM_LANGUAGE_DIRECTION:
1203       {
1204         if( impl.mController )
1205         {
1206           value = impl.mController->IsMatchSystemLanguageDirection();
1207         }
1208         break;
1209       }
1210       case Toolkit::DevelTextField::Property::ENABLE_GRAB_HANDLE_POPUP:
1211       {
1212         if( impl.mController )
1213         {
1214           value = impl.mController->IsGrabHandlePopupEnabled();
1215         }
1216         break;
1217       }
1218       case Toolkit::DevelTextField::Property::BACKGROUND:
1219       {
1220         if( impl.mController )
1221         {
1222           value = impl.mController->GetBackgroundColor();
1223         }
1224         break;
1225       }
1226       case Toolkit::DevelTextField::Property::SELECTED_TEXT:
1227       {
1228         if( impl.mController )
1229         {
1230           value = impl.mController->GetSelectedText( );
1231         }
1232         break;
1233       }
1234     } //switch
1235   }
1236
1237   return value;
1238 }
1239
1240 void TextField::SelectWholeText()
1241 {
1242   if( mController && mController->IsShowingRealText() )
1243   {
1244     mController->SelectEvent( 0.f, 0.f, SelectionType::ALL );
1245     SetKeyInputFocus();
1246   }
1247 }
1248
1249 void TextField::SelectNone()
1250 {
1251   if( mController && mController->IsShowingRealText() )
1252   {
1253     mController->SelectEvent( 0.f, 0.f, SelectionType::NONE );
1254     SetKeyInputFocus();
1255   }
1256 }
1257
1258 InputMethodContext TextField::GetInputMethodContext()
1259 {
1260   return mInputMethodContext;
1261 }
1262
1263 bool TextField::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
1264 {
1265   Dali::BaseHandle handle( object );
1266
1267   bool connected( true );
1268   Toolkit::TextField field = Toolkit::TextField::DownCast( handle );
1269
1270   if( 0 == strcmp( signalName.c_str(), SIGNAL_TEXT_CHANGED ) )
1271   {
1272     field.TextChangedSignal().Connect( tracker, functor );
1273   }
1274   else if( 0 == strcmp( signalName.c_str(), SIGNAL_MAX_LENGTH_REACHED ) )
1275   {
1276     field.MaxLengthReachedSignal().Connect( tracker, functor );
1277   }
1278   else if( 0 == strcmp( signalName.c_str(), SIGNAL_INPUT_STYLE_CHANGED ) )
1279   {
1280     field.InputStyleChangedSignal().Connect( tracker, functor );
1281   }
1282   else
1283   {
1284     // signalName does not match any signal
1285     connected = false;
1286   }
1287
1288   return connected;
1289 }
1290
1291 Toolkit::TextField::TextChangedSignalType& TextField::TextChangedSignal()
1292 {
1293   return mTextChangedSignal;
1294 }
1295
1296 Toolkit::TextField::MaxLengthReachedSignalType& TextField::MaxLengthReachedSignal()
1297 {
1298   return mMaxLengthReachedSignal;
1299 }
1300
1301 Toolkit::TextField::InputStyleChangedSignalType& TextField::InputStyleChangedSignal()
1302 {
1303   return mInputStyleChangedSignal;
1304 }
1305
1306 void TextField::OnInitialize()
1307 {
1308   Actor self = Self();
1309
1310   mController = Text::Controller::New( this, this );
1311
1312   // When using the vector-based rendering, the size of the GLyphs are different
1313   TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
1314   mController->SetGlyphType( glyphType );
1315
1316   mDecorator = Text::Decorator::New( *mController,
1317                                      *mController );
1318
1319   mInputMethodContext = InputMethodContext::New( self );
1320
1321   mController->GetLayoutEngine().SetLayout( Layout::Engine::SINGLE_LINE_BOX );
1322
1323   // Enables the text input.
1324   mController->EnableTextInput( mDecorator, mInputMethodContext );
1325
1326   // Enables the horizontal scrolling after the text input has been enabled.
1327   mController->SetHorizontalScrollEnabled( true );
1328
1329   // Disables the vertical scrolling.
1330   mController->SetVerticalScrollEnabled( false );
1331
1332   // Disable the smooth handle panning.
1333   mController->SetSmoothHandlePanEnabled( false );
1334
1335   mController->SetNoTextDoubleTapAction( Controller::NoTextTap::HIGHLIGHT );
1336   mController->SetNoTextLongPressAction( Controller::NoTextTap::HIGHLIGHT );
1337
1338   // Sets layoutDirection value
1339   Dali::Stage stage = Dali::Stage::GetCurrent();
1340   Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>( stage.GetRootLayer().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
1341   mController->SetLayoutDirection( layoutDirection );
1342
1343   // Forward input events to controller
1344   EnableGestureDetection( static_cast<GestureType::Value>( GestureType::TAP | GestureType::PAN | GestureType::LONG_PRESS ) );
1345   GetTapGestureDetector().SetMaximumTapsRequired( 2 );
1346
1347   self.TouchedSignal().Connect( this, &TextField::OnTouched );
1348
1349   // Set BoundingBox to stage size if not already set.
1350   Rect<int> boundingBox;
1351   mDecorator->GetBoundingBox( boundingBox );
1352
1353   if( boundingBox.IsEmpty() )
1354   {
1355     Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
1356     mDecorator->SetBoundingBox( Rect<int>( 0.0f, 0.0f, stageSize.width, stageSize.height ) );
1357   }
1358
1359   // Flip vertically the 'left' selection handle
1360   mDecorator->FlipHandleVertically( LEFT_SELECTION_HANDLE, true );
1361
1362   // Fill-parent area by default
1363   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
1364   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
1365   self.OnSceneSignal().Connect( this, &TextField::OnSceneConnect );
1366
1367   DevelControl::SetInputMethodContext( *this, mInputMethodContext );
1368
1369   if( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy )
1370   {
1371     EnableClipping();
1372   }
1373 }
1374
1375 void TextField::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
1376 {
1377   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnStyleChange\n");
1378
1379   switch ( change )
1380   {
1381     case StyleChange::DEFAULT_FONT_CHANGE:
1382     {
1383       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnStyleChange DEFAULT_FONT_CHANGE\n");
1384       const std::string& newFont = GetImpl( styleManager ).GetDefaultFontFamily();
1385       // Property system did not set the font so should update it.
1386       mController->UpdateAfterFontChange( newFont );
1387       RelayoutRequest();
1388       break;
1389     }
1390
1391     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
1392     {
1393       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
1394       RelayoutRequest();
1395       break;
1396     }
1397     case StyleChange::THEME_CHANGE:
1398     {
1399       // Nothing to do, let control base class handle this
1400       break;
1401     }
1402   }
1403
1404   // Up call to Control
1405   Control::OnStyleChange( styleManager, change );
1406 }
1407
1408 Vector3 TextField::GetNaturalSize()
1409 {
1410   Extents padding;
1411   padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
1412
1413   Vector3 naturalSize = mController->GetNaturalSize();
1414   naturalSize.width += ( padding.start + padding.end );
1415   naturalSize.height += ( padding.top + padding.bottom );
1416
1417   return naturalSize;
1418 }
1419
1420 float TextField::GetHeightForWidth( float width )
1421 {
1422   Extents padding;
1423   padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
1424   return mController->GetHeightForWidth( width ) + padding.top + padding.bottom;
1425 }
1426
1427 void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
1428 {
1429   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField OnRelayout\n");
1430
1431   Actor self = Self();
1432
1433   Extents padding;
1434   padding = self.GetProperty<Extents>( Toolkit::Control::Property::PADDING );
1435
1436   Vector2 contentSize( size.x - ( padding.start + padding.end ), size.y - ( padding.top + padding.bottom ) );
1437
1438   // Support Right-To-Left of padding
1439   Dali::LayoutDirection::Type layoutDirection;
1440   if( mController->IsMatchSystemLanguageDirection() )
1441   {
1442     layoutDirection = static_cast<Dali::LayoutDirection::Type>( DevelWindow::Get( self ).GetRootLayer().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
1443   }
1444   else
1445   {
1446     layoutDirection = static_cast<Dali::LayoutDirection::Type>( self.GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
1447   }
1448   if( Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection )
1449   {
1450     std::swap( padding.start, padding.end );
1451   }
1452
1453   if( mStencil )
1454   {
1455     mStencil.SetProperty( Actor::Property::POSITION, Vector2( padding.start, padding.top ));
1456   }
1457   if( mActiveLayer )
1458   {
1459     mActiveLayer.SetProperty( Actor::Property::POSITION, Vector2( padding.start, padding.top ));
1460   }
1461
1462   const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize, layoutDirection );
1463
1464   if( ( Text::Controller::NONE_UPDATED != updateTextType ) ||
1465       !mRenderer )
1466   {
1467     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnRelayout %p Displaying new contents\n", mController.Get() );
1468
1469     if( mDecorator &&
1470         ( Text::Controller::NONE_UPDATED != ( Text::Controller::DECORATOR_UPDATED & updateTextType ) ) )
1471     {
1472       mDecorator->Relayout( size );
1473     }
1474
1475     if( !mRenderer )
1476     {
1477       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
1478     }
1479
1480     RenderText( updateTextType );
1481
1482   }
1483
1484   // The text-field emits signals when the input style changes. These changes of style are
1485   // detected during the relayout process (size negotiation), i.e after the cursor has been moved. Signals
1486   // can't be emitted during the size negotiation as the callbacks may update the UI.
1487   // The text-field adds an idle callback to the adaptor to emit the signals after the size negotiation.
1488   if( !mController->IsInputStyleChangedSignalsQueueEmpty() )
1489   {
1490     if( Adaptor::IsAvailable() )
1491     {
1492       Adaptor& adaptor = Adaptor::Get();
1493
1494       if( NULL == mIdleCallback )
1495       {
1496         // @note: The callback manager takes the ownership of the callback object.
1497         mIdleCallback = MakeCallback( this, &TextField::OnIdleSignal );
1498         adaptor.AddIdle( mIdleCallback, false );
1499       }
1500     }
1501   }
1502 }
1503
1504 void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
1505 {
1506   Actor renderableActor;
1507
1508   if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) )
1509   {
1510     if( mRenderer )
1511     {
1512       Dali::Toolkit::TextField handle = Dali::Toolkit::TextField( GetOwner() );
1513
1514       renderableActor = mRenderer->Render( mController->GetView(),
1515                                            handle,
1516                                            Property::INVALID_INDEX, // Animatable property not supported
1517                                            mAlignmentOffset,
1518                                            DepthIndex::CONTENT );
1519     }
1520
1521     if( renderableActor != mRenderableActor )
1522     {
1523       UnparentAndReset( mBackgroundActor );
1524       UnparentAndReset( mRenderableActor );
1525       mRenderableActor = renderableActor;
1526
1527       if ( mRenderableActor )
1528       {
1529         mBackgroundActor = mController->CreateBackgroundActor();
1530       }
1531     }
1532   }
1533
1534   if( mRenderableActor )
1535   {
1536     const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition();
1537
1538     float renderableActorPositionX, renderableActorPositionY;
1539
1540     if( mStencil )
1541     {
1542       renderableActorPositionX = scrollOffset.x + mAlignmentOffset;
1543       renderableActorPositionY = scrollOffset.y;
1544     }
1545     else
1546     {
1547       Extents padding;
1548       padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
1549
1550       // Support Right-To-Left of padding
1551       Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>( Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
1552       if( Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection )
1553       {
1554         std::swap( padding.start, padding.end );
1555       }
1556
1557       renderableActorPositionX = scrollOffset.x + mAlignmentOffset + padding.start;
1558       renderableActorPositionY = scrollOffset.y + padding.top;
1559     }
1560
1561     mRenderableActor.SetProperty( Actor::Property::POSITION, Vector2( renderableActorPositionX, renderableActorPositionY ));
1562
1563     // Make sure the actors are parented correctly with/without clipping
1564     Actor self = mStencil ? mStencil : Self();
1565
1566     Actor highlightActor;
1567
1568     for( std::vector<Actor>::iterator it = mClippingDecorationActors.begin(),
1569            endIt = mClippingDecorationActors.end();
1570          it != endIt;
1571          ++it )
1572     {
1573       self.Add( *it );
1574       it->LowerToBottom();
1575
1576       if ( it->GetProperty< std::string >( Dali::Actor::Property::NAME ) == "HighlightActor" )
1577       {
1578         highlightActor = *it;
1579       }
1580     }
1581     mClippingDecorationActors.clear();
1582
1583     self.Add( mRenderableActor );
1584
1585     if ( mBackgroundActor )
1586     {
1587       if ( mDecorator && mDecorator->IsHighlightVisible() )
1588       {
1589         self.Add( mBackgroundActor );
1590         mBackgroundActor.SetProperty( Actor::Property::POSITION, Vector2( renderableActorPositionX, renderableActorPositionY) ); // In text field's coords.
1591         mBackgroundActor.LowerBelow( highlightActor );
1592       }
1593       else
1594       {
1595         mRenderableActor.Add( mBackgroundActor );
1596         mBackgroundActor.SetProperty( Actor::Property::POSITION, Vector2( 0.0f, 0.0f ) ); // In renderable actor's coords.
1597         mBackgroundActor.LowerToBottom();
1598       }
1599     }
1600   }
1601 }
1602
1603 void TextField::OnKeyInputFocusGained()
1604 {
1605   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyInputFocusGained %p\n", mController.Get() );
1606   if( mInputMethodContext )
1607   {
1608     mInputMethodContext.ApplyOptions( mInputMethodOptions );
1609
1610     mInputMethodContext.StatusChangedSignal().Connect( this, &TextField::KeyboardStatusChanged );
1611
1612     mInputMethodContext.EventReceivedSignal().Connect( this, &TextField::OnInputMethodContextEvent );
1613
1614     // Notify that the text editing start.
1615     mInputMethodContext.Activate();
1616
1617     // When window gain lost focus, the inputMethodContext is deactivated. Thus when window gain focus again, the inputMethodContext must be activated.
1618     mInputMethodContext.SetRestoreAfterFocusLost( true );
1619   }
1620
1621   ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
1622   if( notifier )
1623   {
1624     notifier.ContentSelectedSignal().Connect( this, &TextField::OnClipboardTextSelected );
1625   }
1626
1627   Toolkit::Control control = Toolkit::Control::DownCast( Self() );
1628   Internal::Control& controlImpl = GetImplementation( control );
1629   Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get( controlImpl );
1630   bool enableAutofill = controlDataImpl.IsAutofillEnabled();
1631   if( enableAutofill )
1632   {
1633     Toolkit::AutofillContainer container = controlDataImpl.GetAutofillContainer();
1634     container.SetFocusedControl( control );
1635
1636     Internal::AutofillContainer& containerImpl = GetImpl( container );
1637     Dali::AutofillGroup containerGroup = containerImpl.GetAutofillGroup();
1638     if( containerGroup != nullptr )
1639     {
1640       containerGroup.RequestAuthentication();
1641     }
1642
1643   }
1644   mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event
1645
1646   EmitKeyInputFocusSignal( true ); // Calls back into the Control hence done last.
1647 }
1648
1649 void TextField::OnKeyInputFocusLost()
1650 {
1651   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField:OnKeyInputFocusLost %p\n", mController.Get() );
1652   if ( mInputMethodContext )
1653   {
1654     mInputMethodContext.StatusChangedSignal().Disconnect( this, &TextField::KeyboardStatusChanged );
1655     // The text editing is finished. Therefore the inputMethodContext don't have restore activation.
1656     mInputMethodContext.SetRestoreAfterFocusLost( false );
1657
1658     // Notify that the text editing finish.
1659     mInputMethodContext.Deactivate();
1660
1661     mInputMethodContext.EventReceivedSignal().Disconnect( this, &TextField::OnInputMethodContextEvent );
1662   }
1663   ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
1664
1665   if ( notifier )
1666   {
1667     notifier.ContentSelectedSignal().Disconnect( this, &TextField::OnClipboardTextSelected );
1668   }
1669
1670   mController->KeyboardFocusLostEvent();
1671
1672   EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
1673 }
1674
1675 void TextField::OnTap( const TapGesture& gesture )
1676 {
1677   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnTap %p\n", mController.Get() );
1678   if ( mInputMethodContext )
1679   {
1680     mInputMethodContext.Activate();
1681   }
1682   // Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures
1683   Extents padding;
1684   padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
1685   const Vector2& localPoint = gesture.GetLocalPoint();
1686   mController->TapEvent( gesture.GetNumberOfTaps(), localPoint.x - padding.start, localPoint.y - padding.top );
1687
1688   SetKeyInputFocus();
1689 }
1690
1691 void TextField::OnPan( const PanGesture& gesture )
1692 {
1693   mController->PanEvent( gesture.GetState(), gesture.GetDisplacement() );
1694 }
1695
1696 void TextField::OnLongPress( const LongPressGesture& gesture )
1697 {
1698   if ( mInputMethodContext )
1699   {
1700     mInputMethodContext.Activate();
1701   }
1702   Extents padding;
1703   padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
1704   const Vector2& localPoint = gesture.GetLocalPoint();
1705   mController->LongPressEvent( gesture.GetState(), localPoint.x - padding.start, localPoint.y - padding.top );
1706
1707   SetKeyInputFocus();
1708 }
1709
1710 bool TextField::OnKeyEvent( const KeyEvent& event )
1711 {
1712   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.GetKeyCode() );
1713
1714   if( Dali::DALI_KEY_ESCAPE == event.GetKeyCode() && mController->ShouldClearFocusOnEscape() )
1715   {
1716     // Make sure ClearKeyInputFocus when only key is up
1717     if( event.GetState() == KeyEvent::UP )
1718     {
1719       ClearKeyInputFocus();
1720     }
1721
1722     return true;
1723   }
1724   else if( Dali::DevelKey::DALI_KEY_RETURN == event.GetKeyCode() )
1725   {
1726     // Do nothing when enter is comming.
1727     return false;
1728   }
1729
1730   return mController->KeyEvent( event );
1731 }
1732
1733 void TextField::RequestTextRelayout()
1734 {
1735   RelayoutRequest();
1736 }
1737
1738 void TextField::TextChanged()
1739 {
1740   Dali::Toolkit::TextField handle( GetOwner() );
1741   mTextChangedSignal.Emit( handle );
1742 }
1743
1744 void TextField::MaxLengthReached()
1745 {
1746   Dali::Toolkit::TextField handle( GetOwner() );
1747   mMaxLengthReachedSignal.Emit( handle );
1748 }
1749
1750 void TextField::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
1751 {
1752   Dali::Toolkit::TextField handle( GetOwner() );
1753
1754   Toolkit::TextField::InputStyle::Mask fieldInputStyleMask = Toolkit::TextField::InputStyle::NONE;
1755
1756   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_COLOR ) )
1757   {
1758     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::COLOR );
1759   }
1760   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_FAMILY ) )
1761   {
1762     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_FAMILY );
1763   }
1764   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_POINT_SIZE ) )
1765   {
1766     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::POINT_SIZE );
1767   }
1768   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_WEIGHT ) )
1769   {
1770     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE );
1771   }
1772   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_WIDTH ) )
1773   {
1774     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE );
1775   }
1776   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_FONT_SLANT ) )
1777   {
1778     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::FONT_STYLE );
1779   }
1780   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_UNDERLINE ) )
1781   {
1782     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::UNDERLINE );
1783   }
1784   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_SHADOW ) )
1785   {
1786     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::SHADOW );
1787   }
1788   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_EMBOSS ) )
1789   {
1790     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::EMBOSS );
1791   }
1792   if( InputStyle::NONE != static_cast<InputStyle::Mask>( inputStyleMask & InputStyle::INPUT_OUTLINE ) )
1793   {
1794     fieldInputStyleMask = static_cast<Toolkit::TextField::InputStyle::Mask>( fieldInputStyleMask | Toolkit::TextField::InputStyle::OUTLINE );
1795   }
1796
1797   mInputStyleChangedSignal.Emit( handle, fieldInputStyleMask );
1798 }
1799
1800 void TextField::AddDecoration( Actor& actor, bool needsClipping )
1801 {
1802   if( actor )
1803   {
1804     if( needsClipping )
1805     {
1806       mClippingDecorationActors.push_back( actor );
1807     }
1808     else
1809     {
1810       actor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
1811       actor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
1812       Self().Add( actor );
1813       mActiveLayer = actor;
1814     }
1815   }
1816 }
1817
1818 void TextField::OnSceneConnect( Dali::Actor actor )
1819 {
1820   if ( mHasBeenStaged )
1821   {
1822     RenderText( static_cast<Text::Controller::UpdateTextType>( Text::Controller::MODEL_UPDATED | Text::Controller::DECORATOR_UPDATED ) );
1823   }
1824   else
1825   {
1826     mHasBeenStaged = true;
1827   }
1828 }
1829
1830 InputMethodContext::CallbackData TextField::OnInputMethodContextEvent( Dali::InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent )
1831 {
1832   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnInputMethodContextEvent %p eventName %d\n", mController.Get(), inputMethodContextEvent.eventName );
1833   return mController->OnInputMethodContextEvent( inputMethodContext, inputMethodContextEvent );
1834 }
1835
1836 void TextField::GetHandleImagePropertyValue(  Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType )
1837 {
1838   if( mDecorator )
1839   {
1840     Property::Map map;
1841     map[ IMAGE_MAP_FILENAME_STRING ] = mDecorator->GetHandleImage( handleType, handleImageType );
1842     value = map;
1843   }
1844 }
1845
1846 void TextField::EnableClipping()
1847 {
1848   if( !mStencil )
1849   {
1850     // Creates an extra control to be used as stencil buffer.
1851     mStencil = Control::New();
1852     mStencil.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
1853     mStencil.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
1854
1855     // Creates a background visual. Even if the color is transparent it updates the stencil.
1856     mStencil.SetProperty( Toolkit::Control::Property::BACKGROUND,
1857                           Property::Map().Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR ).
1858                           Add( ColorVisual::Property::MIX_COLOR, Color::TRANSPARENT ) );
1859
1860     // Enable the clipping property.
1861     mStencil.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX );
1862     mStencil.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
1863
1864     Self().Add( mStencil );
1865   }
1866 }
1867
1868 void TextField::OnClipboardTextSelected( ClipboardEventNotifier& clipboard )
1869 {
1870   mController->PasteClipboardItemEvent();
1871 }
1872
1873 void TextField::KeyboardStatusChanged(bool keyboardShown)
1874 {
1875   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown );
1876
1877   // Just hide the grab handle when keyboard is hidden.
1878   if (!keyboardShown )
1879   {
1880     mController->KeyboardFocusLostEvent();
1881   }
1882   else
1883   {
1884     mController->KeyboardFocusGainEvent(); // Initially called by OnKeyInputFocusGained
1885   }
1886 }
1887
1888 void TextField::OnSceneConnection( int depth )
1889 {
1890   // Sets the depth to the visuals inside the text's decorator.
1891   mDecorator->SetTextDepth( depth );
1892
1893   // The depth of the text renderer is set in the RenderText() called from OnRelayout().
1894
1895   // Call the Control::OnSceneConnection() to set the depth of the background.
1896   Control::OnSceneConnection( depth );
1897 }
1898
1899 bool TextField::OnTouched( Actor actor, const TouchEvent& touch )
1900 {
1901   return false;
1902 }
1903
1904 void TextField::OnIdleSignal()
1905 {
1906   // Emits the change of input style signals.
1907   mController->ProcessInputStyleChangedSignals();
1908
1909   // Set the pointer to null as the callback manager deletes the callback after execute it.
1910   mIdleCallback = NULL;
1911 }
1912
1913 TextField::TextField()
1914 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
1915   mIdleCallback( NULL ),
1916   mAlignmentOffset( 0.f ),
1917   mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
1918   mExceedPolicy( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP ),
1919   mHasBeenStaged( false )
1920 {
1921 }
1922
1923 TextField::~TextField()
1924 {
1925   UnparentAndReset( mStencil );
1926
1927   if( ( NULL != mIdleCallback ) && Adaptor::IsAvailable() )
1928   {
1929     Adaptor::Get().RemoveIdle( mIdleCallback );
1930   }
1931 }
1932
1933 } // namespace Internal
1934
1935 } // namespace Toolkit
1936
1937 } // namespace Dali