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