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