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