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