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