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