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