9bbce3b9ac7cdf3a34587e99a94d0da4139950b0
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-editor-impl.cpp
1 /*
2  * Copyright (c) 2016 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/adaptor-framework/virtual-keyboard.h>
28 #include <dali/public-api/object/type-registry-helper.h>
29 #include <dali/integration-api/debug.h>
30
31 // INTERNAL INCLUDES
32 #include <dali-toolkit/public-api/text/rendering-backend.h>
33 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
34 #include <dali-toolkit/internal/text/rendering/text-backend.h>
35 #include <dali-toolkit/internal/text/text-effects-style.h>
36 #include <dali-toolkit/internal/text/text-font-style.h>
37 #include <dali-toolkit/internal/text/text-view.h>
38 #include <dali-toolkit/internal/styling/style-manager-impl.h>
39
40 using namespace Dali::Toolkit::Text;
41
42 namespace Dali
43 {
44
45 namespace Toolkit
46 {
47
48 namespace Internal
49 {
50
51 namespace // unnamed namespace
52 {
53
54 #if defined(DEBUG_ENABLED)
55 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
56 #endif
57
58 const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
59 const float DEFAULT_SCROLL_SPEED = 1200.f; ///< The default scroll speed for the text editor in pixels/second.
60 } // unnamed namespace
61
62 namespace
63 {
64
65 const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
66 {
67   { "BEGIN",  Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN  },
68   { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
69   { "END",    Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END    },
70 };
71 const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
72
73 // Type registration
74 BaseHandle Create()
75 {
76   return Toolkit::TextEditor::New();
77 }
78
79 // Setup properties, signals and actions using the type-registry.
80 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextEditor, Toolkit::Control, Create );
81
82 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "renderingBackend",                     INTEGER,   RENDERING_BACKEND                    )
83 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "text",                                 STRING,    TEXT                                 )
84 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "textColor",                            VECTOR4,   TEXT_COLOR                           )
85 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "fontFamily",                           STRING,    FONT_FAMILY                          )
86 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "fontStyle",                            STRING,    FONT_STYLE                           )
87 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "pointSize",                            FLOAT,     POINT_SIZE                           )
88 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "horizontalAlignment",                  STRING,    HORIZONTAL_ALIGNMENT                 )
89 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "scrollThreshold",                      FLOAT,     SCROLL_THRESHOLD                     )
90 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "scrollSpeed",                          FLOAT,     SCROLL_SPEED                         )
91 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "primaryCursorColor",                   VECTOR4,   PRIMARY_CURSOR_COLOR                 )
92 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "secondaryCursorColor",                 VECTOR4,   SECONDARY_CURSOR_COLOR               )
93 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableCursorBlink",                    BOOLEAN,   ENABLE_CURSOR_BLINK                  )
94 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "cursorBlinkInterval",                  FLOAT,     CURSOR_BLINK_INTERVAL                )
95 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "cursorBlinkDuration",                  FLOAT,     CURSOR_BLINK_DURATION                )
96 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "cursorWidth",                          INTEGER,   CURSOR_WIDTH                         )
97 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "grabHandleImage",                      STRING,    GRAB_HANDLE_IMAGE                    )
98 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "grabHandlePressedImage",               STRING,    GRAB_HANDLE_PRESSED_IMAGE            )
99 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandleImageLeft",             MAP,       SELECTION_HANDLE_IMAGE_LEFT          )
100 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandleImageRight",            MAP,       SELECTION_HANDLE_IMAGE_RIGHT         )
101 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandlePressedImageLeft",      MAP,       SELECTION_HANDLE_PRESSED_IMAGE_LEFT  )
102 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandlePressedImageRight",     MAP,       SELECTION_HANDLE_PRESSED_IMAGE_RIGHT )
103 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandleMarkerImageLeft",       MAP,       SELECTION_HANDLE_MARKER_IMAGE_LEFT   )
104 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandleMarkerImageRight",      MAP,       SELECTION_HANDLE_MARKER_IMAGE_RIGHT  )
105 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHighlightColor",              VECTOR4,   SELECTION_HIGHLIGHT_COLOR            )
106 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "decorationBoundingBox",                RECTANGLE, DECORATION_BOUNDING_BOX              )
107 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableMarkup",                         BOOLEAN,   ENABLE_MARKUP                        )
108 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputColor",                           VECTOR4,   INPUT_COLOR                          )
109 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputFontFamily",                      STRING,    INPUT_FONT_FAMILY                    )
110 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputFontStyle",                       STRING,    INPUT_FONT_STYLE                     )
111 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputPointSize",                       FLOAT,     INPUT_POINT_SIZE                     )
112 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "lineSpacing",                          FLOAT,     LINE_SPACING                         )
113 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputLineSpacing",                     FLOAT,     INPUT_LINE_SPACING                   )
114 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "underline",                            STRING,    UNDERLINE                            )
115 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputUnderline",                       STRING,    INPUT_UNDERLINE                      )
116 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "shadow",                               STRING,    SHADOW                               )
117 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputShadow",                          STRING,    INPUT_SHADOW                         )
118 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "emboss",                               STRING,    EMBOSS                               )
119 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputEmboss",                          STRING,    INPUT_EMBOSS                         )
120 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "outline",                              STRING,    OUTLINE                              )
121 DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputOutline",                         STRING,    INPUT_OUTLINE                        )
122
123 DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "textChanged",        SIGNAL_TEXT_CHANGED )
124
125 DALI_TYPE_REGISTRATION_END()
126
127 } // namespace
128
129 Toolkit::TextEditor TextEditor::New()
130 {
131   // Create the implementation, temporarily owned by this handle on stack
132   IntrusivePtr< TextEditor > impl = new TextEditor();
133
134   // Pass ownership to CustomActor handle
135   Toolkit::TextEditor handle( *impl );
136
137   // Second-phase init of the implementation
138   // This can only be done after the CustomActor connection has been made...
139   impl->Initialize();
140
141   return handle;
142 }
143
144 void TextEditor::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
145 {
146   Toolkit::TextEditor textEditor = Toolkit::TextEditor::DownCast( Dali::BaseHandle( object ) );
147
148   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor SetProperty\n");
149
150
151   if( textEditor )
152   {
153     TextEditor& impl( GetImpl( textEditor ) );
154
155     switch( index )
156     {
157       case Toolkit::TextEditor::Property::RENDERING_BACKEND:
158       {
159         int backend = value.Get< int >();
160         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend );
161
162         if( impl.mRenderingBackend != backend )
163         {
164           impl.mRenderingBackend = backend;
165           impl.mRenderer.Reset();
166           impl.RequestTextRelayout();
167         }
168         break;
169       }
170       case Toolkit::TextEditor::Property::TEXT:
171       {
172         if( impl.mController )
173         {
174           const std::string text = value.Get< std::string >();
175           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p TEXT %s\n", impl.mController.Get(), text.c_str() );
176
177           impl.mController->SetText( text );
178         }
179         break;
180       }
181       case Toolkit::TextEditor::Property::TEXT_COLOR:
182       {
183         if( impl.mController )
184         {
185           const Vector4 textColor = value.Get< Vector4 >();
186           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 );
187
188           if( impl.mController->GetTextColor() != textColor )
189           {
190             impl.mController->SetTextColor( textColor );
191             impl.mController->SetInputColor( textColor );
192             impl.mRenderer.Reset();
193           }
194         }
195         break;
196       }
197       case Toolkit::TextEditor::Property::FONT_FAMILY:
198       {
199         if( impl.mController )
200         {
201           const std::string fontFamily = value.Get< std::string >();
202           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
203           impl.mController->SetDefaultFontFamily( fontFamily );
204         }
205         break;
206       }
207       case Toolkit::TextEditor::Property::FONT_STYLE:
208       {
209         SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
210         break;
211       }
212       case Toolkit::TextEditor::Property::POINT_SIZE:
213       {
214         if( impl.mController )
215         {
216           const float pointSize = value.Get< float >();
217           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p POINT_SIZE %f\n", impl.mController.Get(), pointSize );
218
219           if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
220           {
221             impl.mController->SetDefaultPointSize( pointSize );
222           }
223         }
224         break;
225       }
226       case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
227       {
228         if( impl.mController )
229         {
230           const std::string alignStr = value.Get< std::string >();
231           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p HORIZONTAL_ALIGNMENT %s\n", impl.mController.Get(), alignStr.c_str() );
232
233           LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
234           if( Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
235                                                                               HORIZONTAL_ALIGNMENT_STRING_TABLE,
236                                                                               HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
237                                                                               alignment ) )
238           {
239             impl.mController->SetHorizontalAlignment( alignment );
240           }
241         }
242         break;
243       }
244       case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
245       {
246         const float threshold = value.Get< float >();
247         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold );
248
249         if( impl.mDecorator )
250         {
251           impl.mDecorator->SetScrollThreshold( threshold );
252         }
253         break;
254       }
255       case Toolkit::TextEditor::Property::SCROLL_SPEED:
256       {
257         const float speed = value.Get< float >();
258         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p SCROLL_SPEED %f\n", impl.mController.Get(), speed );
259
260         if( impl.mDecorator )
261         {
262           impl.mDecorator->SetScrollSpeed( speed );
263         }
264         break;
265       }
266       case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
267       {
268         if( impl.mDecorator )
269         {
270           const Vector4 color = value.Get< Vector4 >();
271           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 );
272
273           impl.mDecorator->SetCursorColor( PRIMARY_CURSOR, color );
274           impl.RequestTextRelayout();
275         }
276         break;
277       }
278       case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
279       {
280         if( impl.mDecorator )
281         {
282           const Vector4 color = value.Get< Vector4 >();
283           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 );
284
285           impl.mDecorator->SetCursorColor( SECONDARY_CURSOR, color );
286           impl.RequestTextRelayout();
287         }
288         break;
289       }
290       case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
291       {
292         if( impl.mController )
293         {
294           const bool enable = value.Get< bool >();
295           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable );
296
297           impl.mController->SetEnableCursorBlink( enable );
298           impl.RequestTextRelayout();
299         }
300         break;
301       }
302       case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
303       {
304         if( impl.mDecorator )
305         {
306           const float interval = value.Get< float >();
307           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval );
308
309           impl.mDecorator->SetCursorBlinkInterval( interval );
310         }
311         break;
312       }
313       case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
314       {
315         if( impl.mDecorator )
316         {
317           const float duration = value.Get< float >();
318           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration );
319
320           impl.mDecorator->SetCursorBlinkDuration( duration );
321         }
322         break;
323       }
324       case Toolkit::TextEditor::Property::CURSOR_WIDTH:
325       {
326         if( impl.mDecorator )
327         {
328           const int width = value.Get< int >();
329           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_WIDTH %d\n", impl.mController.Get(), width );
330
331           impl.mDecorator->SetCursorWidth( width );
332           impl.mController->GetLayoutEngine().SetCursorWidth( width );
333         }
334         break;
335       }
336       case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
337       {
338         const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
339         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), image.GetUrl().c_str() );
340
341         if( impl.mDecorator )
342         {
343           impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED, image );
344           impl.RequestTextRelayout();
345         }
346         break;
347       }
348       case Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE:
349       {
350         const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
351         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), image.GetUrl().c_str() );
352
353         if( impl.mDecorator )
354         {
355           impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED, image );
356           impl.RequestTextRelayout();
357         }
358         break;
359       }
360       case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
361       {
362         const Image image = Scripting::NewImage( value );
363
364         if( impl.mDecorator && image )
365         {
366           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
367           impl.RequestTextRelayout();
368         }
369         break;
370       }
371       case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT:
372       {
373         const Image image = Scripting::NewImage( value );
374
375         if( impl.mDecorator && image )
376         {
377           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
378           impl.RequestTextRelayout();
379         }
380         break;
381       }
382       case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_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_PRESSED, image );
389           impl.RequestTextRelayout();
390         }
391         break;
392       }
393       case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_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_PRESSED, image );
400           impl.RequestTextRelayout();
401         }
402         break;
403       }
404       case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
405       {
406         const Image image = Scripting::NewImage( value );
407
408         if( impl.mDecorator && image )
409         {
410           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, image );
411           impl.RequestTextRelayout();
412         }
413         break;
414       }
415       case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
416       {
417         const Image image = Scripting::NewImage( value );
418
419         if( impl.mDecorator && image )
420         {
421           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, image );
422           impl.RequestTextRelayout();
423         }
424         break;
425       }
426       case Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR:
427       {
428         const Vector4 color = value.Get< Vector4 >();
429         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 );
430
431         if( impl.mDecorator )
432         {
433           impl.mDecorator->SetHighlightColor( color );
434           impl.RequestTextRelayout();
435         }
436         break;
437       }
438       case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
439       {
440         if( impl.mDecorator )
441         {
442           const Rect<int> box = value.Get< Rect<int> >();
443           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 );
444
445           impl.mDecorator->SetBoundingBox( box );
446           impl.RequestTextRelayout();
447         }
448         break;
449       }
450       case Toolkit::TextEditor::Property::ENABLE_MARKUP:
451       {
452         if( impl.mController )
453         {
454           const bool enableMarkup = value.Get<bool>();
455           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup );
456
457           impl.mController->SetMarkupProcessorEnabled( enableMarkup );
458         }
459         break;
460       }
461       case Toolkit::TextEditor::Property::INPUT_COLOR:
462       {
463         if( impl.mController )
464         {
465           const Vector4 inputColor = value.Get< Vector4 >();
466           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 );
467
468           impl.mController->SetInputColor( inputColor );
469         }
470         break;
471       }
472       case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
473       {
474         if( impl.mController )
475         {
476           const std::string fontFamily = value.Get< std::string >();
477           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
478           impl.mController->SetInputFontFamily( fontFamily );
479         }
480         break;
481       }
482       case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
483       {
484         SetFontStyleProperty( impl.mController, value, Text::FontStyle::INPUT );
485         break;
486       }
487       case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
488       {
489         if( impl.mController )
490         {
491           const float pointSize = value.Get< float >();
492           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize );
493           impl.mController->SetInputFontPointSize( pointSize );
494         }
495         break;
496       }
497       case Toolkit::TextEditor::Property::LINE_SPACING:
498       {
499         if( impl.mController )
500         {
501           const float lineSpacing = value.Get<float>();
502           impl.mController->SetDefaultLineSpacing( lineSpacing );
503           impl.mRenderer.Reset();
504         }
505         break;
506       }
507       case Toolkit::TextEditor::Property::INPUT_LINE_SPACING:
508       {
509         if( impl.mController )
510         {
511           const float lineSpacing = value.Get<float>();
512           impl.mController->SetInputLineSpacing( lineSpacing );
513           impl.mRenderer.Reset();
514         }
515         break;
516       }
517       case Toolkit::TextEditor::Property::UNDERLINE:
518       {
519         const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
520         if( update )
521         {
522           impl.mRenderer.Reset();
523         }
524         break;
525       }
526       case Toolkit::TextEditor::Property::INPUT_UNDERLINE:
527       {
528         const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::INPUT );
529         if( update )
530         {
531           impl.mRenderer.Reset();
532         }
533         break;
534       }
535       case Toolkit::TextEditor::Property::SHADOW:
536       {
537         const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
538         if( update )
539         {
540           impl.mRenderer.Reset();
541         }
542         break;
543       }
544       case Toolkit::TextEditor::Property::INPUT_SHADOW:
545       {
546         const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::INPUT );
547         if( update )
548         {
549           impl.mRenderer.Reset();
550         }
551         break;
552       }
553       case Toolkit::TextEditor::Property::EMBOSS:
554       {
555         const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
556         if( update )
557         {
558           impl.mRenderer.Reset();
559         }
560         break;
561       }
562       case Toolkit::TextEditor::Property::INPUT_EMBOSS:
563       {
564         const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::INPUT );
565         if( update )
566         {
567           impl.mRenderer.Reset();
568         }
569         break;
570       }
571       case Toolkit::TextEditor::Property::OUTLINE:
572       {
573         const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
574         if( update )
575         {
576           impl.mRenderer.Reset();
577         }
578         break;
579       }
580       case Toolkit::TextEditor::Property::INPUT_OUTLINE:
581       {
582         const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::INPUT );
583         if( update )
584         {
585           impl.mRenderer.Reset();
586         }
587         break;
588       }
589     } // switch
590   } // texteditor
591 }
592
593 Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index index )
594 {
595   Property::Value value;
596
597   Toolkit::TextEditor textEditor = Toolkit::TextEditor::DownCast( Dali::BaseHandle( object ) );
598
599   if( textEditor )
600   {
601     TextEditor& impl( GetImpl( textEditor ) );
602
603     switch( index )
604     {
605       case Toolkit::TextEditor::Property::RENDERING_BACKEND:
606       {
607         value = impl.mRenderingBackend;
608         break;
609       }
610       case Toolkit::TextEditor::Property::TEXT:
611       {
612         if( impl.mController )
613         {
614           std::string text;
615           impl.mController->GetText( text );
616           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p returning text: %s\n", impl.mController.Get(), text.c_str() );
617           value = text;
618         }
619         break;
620       }
621       case Toolkit::TextEditor::Property::TEXT_COLOR:
622       {
623         if ( impl.mController )
624         {
625           value = impl.mController->GetTextColor();
626         }
627         break;
628       }
629       case Toolkit::TextEditor::Property::FONT_FAMILY:
630       {
631         if( impl.mController )
632         {
633           value = impl.mController->GetDefaultFontFamily();
634         }
635         break;
636       }
637       case Toolkit::TextEditor::Property::FONT_STYLE:
638       {
639         GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
640         break;
641       }
642       case Toolkit::TextEditor::Property::POINT_SIZE:
643       {
644         if( impl.mController )
645         {
646           value = impl.mController->GetDefaultPointSize();
647         }
648         break;
649       }
650       case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
651       {
652         if( impl.mController )
653         {
654           const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
655                                                                                                                 HORIZONTAL_ALIGNMENT_STRING_TABLE,
656                                                                                                                 HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
657           if( name )
658           {
659             value = std::string( name );
660           }
661         }
662         break;
663       }
664       case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
665       {
666         if( impl.mDecorator )
667         {
668           value = impl.mDecorator->GetScrollThreshold();
669         }
670         break;
671       }
672       case Toolkit::TextEditor::Property::SCROLL_SPEED:
673       {
674         if( impl.mDecorator )
675         {
676           value = impl.mDecorator->GetScrollSpeed();
677         }
678         break;
679       }
680       case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
681       {
682         if( impl.mDecorator )
683         {
684           value = impl.mDecorator->GetColor( PRIMARY_CURSOR );
685         }
686         break;
687       }
688       case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
689       {
690         if( impl.mDecorator )
691         {
692           value = impl.mDecorator->GetColor( SECONDARY_CURSOR );
693         }
694         break;
695       }
696       case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
697       {
698         value = impl.mController->GetEnableCursorBlink();
699         break;
700       }
701       case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
702       {
703         if( impl.mDecorator )
704         {
705           value = impl.mDecorator->GetCursorBlinkInterval();
706         }
707         break;
708       }
709       case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
710       {
711         if( impl.mDecorator )
712         {
713           value = impl.mDecorator->GetCursorBlinkDuration();
714         }
715         break;
716       }
717       case Toolkit::TextEditor::Property::CURSOR_WIDTH:
718       {
719         if( impl.mDecorator )
720         {
721           value = impl.mDecorator->GetCursorWidth();
722         }
723         break;
724       }
725       case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
726       {
727         if( impl.mDecorator )
728         {
729           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED ) );
730           if( image )
731           {
732             value = image.GetUrl();
733           }
734         }
735         break;
736       }
737       case Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE:
738       {
739         if( impl.mDecorator )
740         {
741           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED ) );
742           if( image )
743           {
744             value = image.GetUrl();
745           }
746         }
747         break;
748       }
749       case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
750       {
751         impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED );
752         break;
753       }
754       case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT:
755       {
756         impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED ) ;
757         break;
758       }
759       case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
760       {
761         impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED );
762         break;
763       }
764       case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
765       {
766         impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED );
767         break;
768       }
769       case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
770       {
771         impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED );
772         break;
773       }
774       case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
775       {
776         impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED );
777         break;
778       }
779       case Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR:
780       {
781         if( impl.mDecorator )
782         {
783           value = impl.mDecorator->GetHighlightColor();
784         }
785         break;
786       }
787       case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
788       {
789         if( impl.mDecorator )
790         {
791           Rect<int> boundingBox;
792           impl.mDecorator->GetBoundingBox( boundingBox );
793           value = boundingBox;
794         }
795         break;
796       }
797       case Toolkit::TextEditor::Property::ENABLE_MARKUP:
798       {
799         if( impl.mController )
800         {
801           value = impl.mController->IsMarkupProcessorEnabled();
802         }
803         break;
804       }
805       case Toolkit::TextEditor::Property::INPUT_COLOR:
806       {
807         if( impl.mController )
808         {
809           value = impl.mController->GetInputColor();
810         }
811         break;
812       }
813       case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
814       {
815         if( impl.mController )
816         {
817           value = impl.mController->GetInputFontFamily();
818         }
819         break;
820       }
821       case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
822       {
823         GetFontStyleProperty( impl.mController, value, Text::FontStyle::INPUT );
824         break;
825       }
826       case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
827       {
828         if( impl.mController )
829         {
830           value = impl.mController->GetInputFontPointSize();
831         }
832         break;
833       }
834       case Toolkit::TextEditor::Property::LINE_SPACING:
835       {
836         if( impl.mController )
837         {
838           value = impl.mController->GetDefaultLineSpacing();
839         }
840         break;
841       }
842       case Toolkit::TextEditor::Property::INPUT_LINE_SPACING:
843       {
844         if( impl.mController )
845         {
846           value = impl.mController->GetInputLineSpacing();
847         }
848         break;
849       }
850       case Toolkit::TextEditor::Property::UNDERLINE:
851       {
852         GetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
853         break;
854       }
855       case Toolkit::TextEditor::Property::INPUT_UNDERLINE:
856       {
857         GetUnderlineProperties( impl.mController, value, Text::EffectStyle::INPUT );
858         break;
859       }
860       case Toolkit::TextEditor::Property::SHADOW:
861       {
862         GetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
863         break;
864       }
865       case Toolkit::TextEditor::Property::INPUT_SHADOW:
866       {
867         GetShadowProperties( impl.mController, value, Text::EffectStyle::INPUT );
868         break;
869       }
870       case Toolkit::TextEditor::Property::EMBOSS:
871       {
872         GetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
873         break;
874       }
875       case Toolkit::TextEditor::Property::INPUT_EMBOSS:
876       {
877         GetEmbossProperties( impl.mController, value, Text::EffectStyle::INPUT );
878         break;
879       }
880       case Toolkit::TextEditor::Property::OUTLINE:
881       {
882         GetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
883         break;
884       }
885       case Toolkit::TextEditor::Property::INPUT_OUTLINE:
886       {
887         GetOutlineProperties( impl.mController, value, Text::EffectStyle::INPUT );
888         break;
889       }
890     } //switch
891   }
892
893   return value;
894 }
895
896 bool TextEditor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
897 {
898   Dali::BaseHandle handle( object );
899
900   bool connected( true );
901   Toolkit::TextEditor editor = Toolkit::TextEditor::DownCast( handle );
902
903   if( 0 == strcmp( signalName.c_str(), SIGNAL_TEXT_CHANGED ) )
904   {
905     editor.TextChangedSignal().Connect( tracker, functor );
906   }
907   else
908   {
909     // signalName does not match any signal
910     connected = false;
911   }
912
913   return connected;
914 }
915
916 Toolkit::TextEditor::TextChangedSignalType& TextEditor::TextChangedSignal()
917 {
918   return mTextChangedSignal;
919 }
920
921 void TextEditor::OnInitialize()
922 {
923   Actor self = Self();
924
925   mController = Text::Controller::New( *this );
926
927   mDecorator = Text::Decorator::New( *mController,
928                                      *mController );
929
930   mController->GetLayoutEngine().SetLayout( LayoutEngine::MULTI_LINE_BOX );
931
932   // Enables the text input.
933   mController->EnableTextInput( mDecorator );
934
935   // Enables the vertical scrolling after the text input has been enabled.
936   mController->SetVerticalScrollEnabled( true );
937
938   // Disables the horizontal scrolling.
939   mController->SetHorizontalScrollEnabled( false );
940
941   mController->SetMaximumNumberOfCharacters( std::numeric_limits<Length>::max() );
942
943   // Enable the smooth handle panning.
944   mController->SetSmoothHandlePanEnabled( true );
945
946   // Forward input events to controller
947   EnableGestureDetection( static_cast<Gesture::Type>( Gesture::Tap | Gesture::Pan | Gesture::LongPress ) );
948   GetTapGestureDetector().SetMaximumTapsRequired( 2 );
949
950   self.TouchSignal().Connect( this, &TextEditor::OnTouched );
951
952   // Set BoundingBox to stage size if not already set.
953   Rect<int> boundingBox;
954   mDecorator->GetBoundingBox( boundingBox );
955
956   if( boundingBox.IsEmpty() )
957   {
958     Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
959     mDecorator->SetBoundingBox( Rect<int>( 0.0f, 0.0f, stageSize.width, stageSize.height ) );
960   }
961
962   // Whether to flip the selection handles as soon as they cross.
963   mDecorator->FlipSelectionHandlesOnCrossEnabled( true );
964
965   // Set the default scroll speed.
966   mDecorator->SetScrollSpeed( DEFAULT_SCROLL_SPEED );
967
968   // Fill-parent area by default
969   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
970   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
971   self.OnStageSignal().Connect( this, &TextEditor::OnStageConnect );
972 }
973
974 void TextEditor::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
975 {
976   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnStyleChange\n");
977
978   switch ( change )
979   {
980     case StyleChange::DEFAULT_FONT_CHANGE:
981     {
982       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnStyleChange DEFAULT_FONT_CHANGE\n");
983       const std::string& newFont = GetImpl( styleManager ).GetDefaultFontFamily();
984       // Property system did not set the font so should update it.
985       mController->UpdateAfterFontChange( newFont );
986       break;
987     }
988
989     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
990     {
991       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
992       break;
993     }
994     case StyleChange::THEME_CHANGE:
995     {
996       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
997       break;
998     }
999   }
1000 }
1001
1002 Vector3 TextEditor::GetNaturalSize()
1003 {
1004   return mController->GetNaturalSize();
1005 }
1006
1007 float TextEditor::GetHeightForWidth( float width )
1008 {
1009   return mController->GetHeightForWidth( width );
1010 }
1011
1012 void TextEditor::OnRelayout( const Vector2& size, RelayoutContainer& container )
1013 {
1014   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor OnRelayout\n");
1015
1016   const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
1017
1018   if( ( Text::Controller::NONE_UPDATED != updateTextType ) ||
1019       !mRenderer )
1020   {
1021     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnRelayout %p Displaying new contents\n", mController.Get() );
1022
1023     if( mDecorator &&
1024         ( Text::Controller::NONE_UPDATED != ( Text::Controller::DECORATOR_UPDATED & updateTextType ) ) )
1025     {
1026       mDecorator->Relayout( size );
1027     }
1028
1029     if( !mRenderer )
1030     {
1031       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
1032     }
1033
1034     EnableClipping( true, size );
1035     RenderText( updateTextType );
1036   }
1037 }
1038
1039 void TextEditor::RenderText( Text::Controller::UpdateTextType updateTextType )
1040 {
1041   Actor self = Self();
1042   Actor renderableActor;
1043
1044   if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) )
1045   {
1046     if( mRenderer )
1047     {
1048       renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT );
1049     }
1050
1051     if( renderableActor != mRenderableActor )
1052     {
1053       UnparentAndReset( mRenderableActor );
1054       mRenderableActor = renderableActor;
1055     }
1056   }
1057
1058   if( mRenderableActor )
1059   {
1060     const Vector2& scrollOffset = mController->GetScrollPosition();
1061
1062     mRenderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
1063
1064     Actor clipRootActor;
1065     if( mClipper )
1066     {
1067       clipRootActor = mClipper->GetRootActor();
1068     }
1069
1070     for( std::vector<Actor>::const_iterator it = mClippingDecorationActors.begin(),
1071            endIt = mClippingDecorationActors.end();
1072          it != endIt;
1073          ++it )
1074     {
1075       Actor actor = *it;
1076
1077       if( clipRootActor )
1078       {
1079         clipRootActor.Add( actor );
1080       }
1081       else
1082       {
1083         self.Add( actor );
1084       }
1085     }
1086     mClippingDecorationActors.clear();
1087
1088     // Make sure the actor is parented correctly with/without clipping
1089     if( clipRootActor )
1090     {
1091       clipRootActor.Add( mRenderableActor );
1092     }
1093     else
1094     {
1095       self.Add( mRenderableActor );
1096     }
1097   }
1098 }
1099
1100 void TextEditor::OnKeyInputFocusGained()
1101 {
1102   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnKeyInputFocusGained %p\n", mController.Get() );
1103
1104   VirtualKeyboard::StatusChangedSignal().Connect( this, &TextEditor::KeyboardStatusChanged );
1105
1106   ImfManager imfManager = ImfManager::Get();
1107
1108   if ( imfManager )
1109   {
1110     imfManager.EventReceivedSignal().Connect( this, &TextEditor::OnImfEvent );
1111
1112     // Notify that the text editing start.
1113     imfManager.Activate();
1114
1115     // When window gain lost focus, the imf manager is deactivated. Thus when window gain focus again, the imf manager must be activated.
1116     imfManager.SetRestoreAfterFocusLost( true );
1117   }
1118
1119    ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
1120
1121    if ( notifier )
1122    {
1123       notifier.ContentSelectedSignal().Connect( this, &TextEditor::OnClipboardTextSelected );
1124    }
1125
1126   mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event
1127
1128   EmitKeyInputFocusSignal( true ); // Calls back into the Control hence done last.
1129 }
1130
1131 void TextEditor::OnKeyInputFocusLost()
1132 {
1133   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor:OnKeyInputFocusLost %p\n", mController.Get() );
1134
1135   VirtualKeyboard::StatusChangedSignal().Disconnect( this, &TextEditor::KeyboardStatusChanged );
1136
1137   ImfManager imfManager = ImfManager::Get();
1138   if ( imfManager )
1139   {
1140     // The text editing is finished. Therefore the imf manager don't have restore activation.
1141     imfManager.SetRestoreAfterFocusLost( false );
1142
1143     // Notify that the text editing finish.
1144     imfManager.Deactivate();
1145
1146     imfManager.EventReceivedSignal().Disconnect( this, &TextEditor::OnImfEvent );
1147   }
1148
1149   ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
1150
1151   if ( notifier )
1152   {
1153     notifier.ContentSelectedSignal().Disconnect( this, &TextEditor::OnClipboardTextSelected );
1154   }
1155
1156   mController->KeyboardFocusLostEvent();
1157
1158   EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
1159 }
1160
1161 void TextEditor::OnTap( const TapGesture& gesture )
1162 {
1163   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnTap %p\n", mController.Get() );
1164
1165   // Show the keyboard if it was hidden.
1166   if (!VirtualKeyboard::IsVisible())
1167   {
1168     VirtualKeyboard::Show();
1169   }
1170
1171   // Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures
1172   mController->TapEvent( gesture.numberOfTaps, gesture.localPoint.x, gesture.localPoint.y );
1173
1174   SetKeyInputFocus();
1175 }
1176
1177 void TextEditor::OnPan( const PanGesture& gesture )
1178 {
1179   mController->PanEvent( gesture.state, gesture.displacement );
1180 }
1181
1182 void TextEditor::OnLongPress( const LongPressGesture& gesture )
1183 {
1184   // Show the keyboard if it was hidden.
1185   if (!VirtualKeyboard::IsVisible())
1186   {
1187     VirtualKeyboard::Show();
1188   }
1189
1190   mController->LongPressEvent( gesture.state, gesture.localPoint.x, gesture.localPoint.y );
1191
1192   SetKeyInputFocus();
1193 }
1194
1195 bool TextEditor::OnKeyEvent( const KeyEvent& event )
1196 {
1197   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
1198
1199   if( Dali::DALI_KEY_ESCAPE == event.keyCode ) // Make a Dali key code for this
1200   {
1201     ClearKeyInputFocus();
1202     return true;
1203   }
1204
1205   return mController->KeyEvent( event );
1206 }
1207
1208 void TextEditor::AddDecoration( Actor& actor, bool needsClipping )
1209 {
1210   if( actor )
1211   {
1212     if( needsClipping )
1213     {
1214       mClippingDecorationActors.push_back( actor );
1215     }
1216     else
1217     {
1218       Self().Add( actor );
1219     }
1220   }
1221 }
1222
1223 void TextEditor::RequestTextRelayout()
1224 {
1225   RelayoutRequest();
1226 }
1227
1228 void TextEditor::TextChanged()
1229 {
1230   Dali::Toolkit::TextEditor handle( GetOwner() );
1231   mTextChangedSignal.Emit( handle );
1232 }
1233
1234 void TextEditor::MaxLengthReached()
1235 {
1236   // Nothing to do as TextEditor doesn't emit a max length reached signal.
1237 }
1238
1239 void TextEditor::OnStageConnect( Dali::Actor actor )
1240 {
1241   if ( mHasBeenStaged )
1242   {
1243     RenderText( static_cast<Text::Controller::UpdateTextType>( Text::Controller::MODEL_UPDATED | Text::Controller::DECORATOR_UPDATED ) );
1244   }
1245   else
1246   {
1247     mHasBeenStaged = true;
1248   }
1249 }
1250
1251 ImfManager::ImfCallbackData TextEditor::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
1252 {
1253   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
1254   return mController->OnImfEvent( imfManager, imfEvent );
1255 }
1256
1257 void TextEditor::GetHandleImagePropertyValue(  Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType )
1258 {
1259   if( mDecorator )
1260   {
1261     ResourceImage image = ResourceImage::DownCast( mDecorator->GetHandleImage( handleType, handleImageType ) );
1262
1263     if ( image )
1264     {
1265       Property::Map map;
1266       Scripting::CreatePropertyMap( image, map );
1267       value = map;
1268     }
1269   }
1270 }
1271
1272 void TextEditor::EnableClipping( bool clipping, const Vector2& size )
1273 {
1274   if( clipping )
1275   {
1276     // Not worth to created clip actor if width or height is equal to zero.
1277     if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
1278     {
1279       if( !mClipper )
1280       {
1281         Actor self = Self();
1282
1283         mClipper = Clipper::New( size );
1284         self.Add( mClipper->GetRootActor() );
1285         self.Add( mClipper->GetImageView() );
1286       }
1287       else if ( mClipper )
1288       {
1289         mClipper->Refresh( size );
1290       }
1291     }
1292   }
1293   else
1294   {
1295     // Note - this will automatically remove the root actor & the image view
1296     mClipper.Reset();
1297   }
1298 }
1299
1300 void TextEditor::OnClipboardTextSelected( ClipboardEventNotifier& clipboard )
1301 {
1302   mController->PasteClipboardItemEvent();
1303 }
1304
1305 void TextEditor::KeyboardStatusChanged(bool keyboardShown)
1306 {
1307   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown );
1308
1309   // Just hide the grab handle when keyboard is hidden.
1310   if (!keyboardShown )
1311   {
1312     mController->KeyboardFocusLostEvent();
1313   }
1314   else
1315   {
1316     mController->KeyboardFocusGainEvent(); // Initially called by OnKeyInputFocusGained
1317   }
1318 }
1319
1320 void TextEditor::OnStageConnection( int depth )
1321 {
1322   // Call the Control::OnStageConnection() to set the depth of the background.
1323   Control::OnStageConnection( depth );
1324
1325   // Sets the depth to the visuals inside the text's decorator.
1326   mDecorator->SetTextDepth( depth );
1327
1328   // The depth of the text renderer is set in the RenderText() called from OnRelayout().
1329 }
1330
1331 bool TextEditor::OnTouched( Actor actor, const TouchData& touch )
1332 {
1333   return true;
1334 }
1335
1336 TextEditor::TextEditor()
1337 : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
1338   mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
1339   mHasBeenStaged( false )
1340 {
1341 }
1342
1343 TextEditor::~TextEditor()
1344 {
1345   mClipper.Reset();
1346 }
1347
1348 } // namespace Internal
1349
1350 } // namespace Toolkit
1351
1352 } // namespace Dali