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