75780c3b0fb14ffd9458266f24408192b51e7cc2
[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       DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor::OnStyleChange StyleChange::DEFAULT_FONT_SIZE_CHANGE (%f)\n", mController->GetDefaultPointSize() );
992
993       if ( (mController->GetDefaultPointSize() <= 0.0f) ) // If DefaultPointSize not set by Property system it will be 0.0f
994       {
995         // Property system did not set the PointSize so should update it.
996         // todo instruct text-controller to update model
997       }
998       break;
999     }
1000     case StyleChange::THEME_CHANGE:
1001     {
1002       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
1003       break;
1004     }
1005   }
1006 }
1007
1008 Vector3 TextEditor::GetNaturalSize()
1009 {
1010   return mController->GetNaturalSize();
1011 }
1012
1013 float TextEditor::GetHeightForWidth( float width )
1014 {
1015   return mController->GetHeightForWidth( width );
1016 }
1017
1018 void TextEditor::OnRelayout( const Vector2& size, RelayoutContainer& container )
1019 {
1020   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor OnRelayout\n");
1021
1022   const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
1023
1024   if( ( Text::Controller::NONE_UPDATED != updateTextType ) ||
1025       !mRenderer )
1026   {
1027     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnRelayout %p Displaying new contents\n", mController.Get() );
1028
1029     if( mDecorator &&
1030         ( Text::Controller::NONE_UPDATED != ( Text::Controller::DECORATOR_UPDATED & updateTextType ) ) )
1031     {
1032       mDecorator->Relayout( size );
1033     }
1034
1035     if( !mRenderer )
1036     {
1037       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
1038     }
1039
1040     EnableClipping( true, size );
1041     RenderText( updateTextType );
1042   }
1043 }
1044
1045 void TextEditor::RenderText( Text::Controller::UpdateTextType updateTextType )
1046 {
1047   Actor self = Self();
1048   Actor renderableActor;
1049
1050   if( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) )
1051   {
1052     if( mRenderer )
1053     {
1054       renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT );
1055     }
1056
1057     if( renderableActor != mRenderableActor )
1058     {
1059       UnparentAndReset( mRenderableActor );
1060       mRenderableActor = renderableActor;
1061     }
1062   }
1063
1064   if( mRenderableActor )
1065   {
1066     const Vector2& scrollOffset = mController->GetScrollPosition();
1067
1068     mRenderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
1069
1070     Actor clipRootActor;
1071     if( mClipper )
1072     {
1073       clipRootActor = mClipper->GetRootActor();
1074     }
1075
1076     for( std::vector<Actor>::const_iterator it = mClippingDecorationActors.begin(),
1077            endIt = mClippingDecorationActors.end();
1078          it != endIt;
1079          ++it )
1080     {
1081       Actor actor = *it;
1082
1083       if( clipRootActor )
1084       {
1085         clipRootActor.Add( actor );
1086       }
1087       else
1088       {
1089         self.Add( actor );
1090       }
1091     }
1092     mClippingDecorationActors.clear();
1093
1094     // Make sure the actor is parented correctly with/without clipping
1095     if( clipRootActor )
1096     {
1097       clipRootActor.Add( mRenderableActor );
1098     }
1099     else
1100     {
1101       self.Add( mRenderableActor );
1102     }
1103   }
1104 }
1105
1106 void TextEditor::OnKeyInputFocusGained()
1107 {
1108   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnKeyInputFocusGained %p\n", mController.Get() );
1109
1110   VirtualKeyboard::StatusChangedSignal().Connect( this, &TextEditor::KeyboardStatusChanged );
1111
1112   ImfManager imfManager = ImfManager::Get();
1113
1114   if ( imfManager )
1115   {
1116     imfManager.EventReceivedSignal().Connect( this, &TextEditor::OnImfEvent );
1117
1118     // Notify that the text editing start.
1119     imfManager.Activate();
1120
1121     // When window gain lost focus, the imf manager is deactivated. Thus when window gain focus again, the imf manager must be activated.
1122     imfManager.SetRestoreAfterFocusLost( true );
1123   }
1124
1125    ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
1126
1127    if ( notifier )
1128    {
1129       notifier.ContentSelectedSignal().Connect( this, &TextEditor::OnClipboardTextSelected );
1130    }
1131
1132   mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event
1133
1134   EmitKeyInputFocusSignal( true ); // Calls back into the Control hence done last.
1135 }
1136
1137 void TextEditor::OnKeyInputFocusLost()
1138 {
1139   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor:OnKeyInputFocusLost %p\n", mController.Get() );
1140
1141   VirtualKeyboard::StatusChangedSignal().Disconnect( this, &TextEditor::KeyboardStatusChanged );
1142
1143   ImfManager imfManager = ImfManager::Get();
1144   if ( imfManager )
1145   {
1146     // The text editing is finished. Therefore the imf manager don't have restore activation.
1147     imfManager.SetRestoreAfterFocusLost( false );
1148
1149     // Notify that the text editing finish.
1150     imfManager.Deactivate();
1151
1152     imfManager.EventReceivedSignal().Disconnect( this, &TextEditor::OnImfEvent );
1153   }
1154
1155   ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
1156
1157   if ( notifier )
1158   {
1159     notifier.ContentSelectedSignal().Disconnect( this, &TextEditor::OnClipboardTextSelected );
1160   }
1161
1162   mController->KeyboardFocusLostEvent();
1163
1164   EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
1165 }
1166
1167 void TextEditor::OnTap( const TapGesture& gesture )
1168 {
1169   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnTap %p\n", mController.Get() );
1170
1171   // Show the keyboard if it was hidden.
1172   if (!VirtualKeyboard::IsVisible())
1173   {
1174     VirtualKeyboard::Show();
1175   }
1176
1177   // Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures
1178   mController->TapEvent( gesture.numberOfTaps, gesture.localPoint.x, gesture.localPoint.y );
1179
1180   SetKeyInputFocus();
1181 }
1182
1183 void TextEditor::OnPan( const PanGesture& gesture )
1184 {
1185   mController->PanEvent( gesture.state, gesture.displacement );
1186 }
1187
1188 void TextEditor::OnLongPress( const LongPressGesture& gesture )
1189 {
1190   // Show the keyboard if it was hidden.
1191   if (!VirtualKeyboard::IsVisible())
1192   {
1193     VirtualKeyboard::Show();
1194   }
1195
1196   mController->LongPressEvent( gesture.state, gesture.localPoint.x, gesture.localPoint.y );
1197
1198   SetKeyInputFocus();
1199 }
1200
1201 bool TextEditor::OnKeyEvent( const KeyEvent& event )
1202 {
1203   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
1204
1205   if( Dali::DALI_KEY_ESCAPE == event.keyCode ) // Make a Dali key code for this
1206   {
1207     ClearKeyInputFocus();
1208     return true;
1209   }
1210
1211   return mController->KeyEvent( event );
1212 }
1213
1214 void TextEditor::AddDecoration( Actor& actor, bool needsClipping )
1215 {
1216   if( actor )
1217   {
1218     if( needsClipping )
1219     {
1220       mClippingDecorationActors.push_back( actor );
1221     }
1222     else
1223     {
1224       Self().Add( actor );
1225     }
1226   }
1227 }
1228
1229 void TextEditor::RequestTextRelayout()
1230 {
1231   RelayoutRequest();
1232 }
1233
1234 void TextEditor::TextChanged()
1235 {
1236   Dali::Toolkit::TextEditor handle( GetOwner() );
1237   mTextChangedSignal.Emit( handle );
1238 }
1239
1240 void TextEditor::MaxLengthReached()
1241 {
1242   // Nothing to do as TextEditor doesn't emit a max length reached signal.
1243 }
1244
1245 void TextEditor::OnStageConnect( Dali::Actor actor )
1246 {
1247   if ( mHasBeenStaged )
1248   {
1249     RenderText( static_cast<Text::Controller::UpdateTextType>( Text::Controller::MODEL_UPDATED | Text::Controller::DECORATOR_UPDATED ) );
1250   }
1251   else
1252   {
1253     mHasBeenStaged = true;
1254   }
1255 }
1256
1257 ImfManager::ImfCallbackData TextEditor::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
1258 {
1259   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
1260   return mController->OnImfEvent( imfManager, imfEvent );
1261 }
1262
1263 void TextEditor::GetHandleImagePropertyValue(  Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType )
1264 {
1265   if( mDecorator )
1266   {
1267     ResourceImage image = ResourceImage::DownCast( mDecorator->GetHandleImage( handleType, handleImageType ) );
1268
1269     if ( image )
1270     {
1271       Property::Map map;
1272       Scripting::CreatePropertyMap( image, map );
1273       value = map;
1274     }
1275   }
1276 }
1277
1278 void TextEditor::EnableClipping( bool clipping, const Vector2& size )
1279 {
1280   if( clipping )
1281   {
1282     // Not worth to created clip actor if width or height is equal to zero.
1283     if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
1284     {
1285       if( !mClipper )
1286       {
1287         Actor self = Self();
1288
1289         mClipper = Clipper::New( size );
1290         self.Add( mClipper->GetRootActor() );
1291         self.Add( mClipper->GetImageView() );
1292       }
1293       else if ( mClipper )
1294       {
1295         mClipper->Refresh( size );
1296       }
1297     }
1298   }
1299   else
1300   {
1301     // Note - this will automatically remove the root actor & the image view
1302     mClipper.Reset();
1303   }
1304 }
1305
1306 void TextEditor::OnClipboardTextSelected( ClipboardEventNotifier& clipboard )
1307 {
1308   mController->PasteClipboardItemEvent();
1309 }
1310
1311 void TextEditor::KeyboardStatusChanged(bool keyboardShown)
1312 {
1313   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown );
1314
1315   // Just hide the grab handle when keyboard is hidden.
1316   if (!keyboardShown )
1317   {
1318     mController->KeyboardFocusLostEvent();
1319   }
1320   else
1321   {
1322     mController->KeyboardFocusGainEvent(); // Initially called by OnKeyInputFocusGained
1323   }
1324 }
1325
1326 void TextEditor::OnStageConnection( int depth )
1327 {
1328   // Call the Control::OnStageConnection() to set the depth of the background.
1329   Control::OnStageConnection( depth );
1330
1331   // Sets the depth to the visuals inside the text's decorator.
1332   mDecorator->SetTextDepth( depth );
1333
1334   // The depth of the text renderer is set in the RenderText() called from OnRelayout().
1335 }
1336
1337 bool TextEditor::OnTouched( Actor actor, const TouchData& touch )
1338 {
1339   return true;
1340 }
1341
1342 TextEditor::TextEditor()
1343 : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
1344   mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
1345   mHasBeenStaged( false )
1346 {
1347 }
1348
1349 TextEditor::~TextEditor()
1350 {
1351   mClipper.Reset();
1352 }
1353
1354 } // namespace Internal
1355
1356 } // namespace Toolkit
1357
1358 } // namespace Dali