Merge "(Page) Using registered properties" into tizen
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-field-impl.cpp
1 /*
2  * Copyright (c) 2015 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-field-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <string>
23 #include <dali/public-api/adaptor-framework/key.h>
24 #include <dali/public-api/common/stage.h>
25 #include <dali/public-api/images/resource-image.h>
26 #include <dali/public-api/object/type-registry.h>
27 #include <dali/public-api/object/type-registry-helper.h>
28 #include <dali/public-api/scripting/scripting.h>
29 #include <dali/integration-api/debug.h>
30 #include <dali/public-api/adaptor-framework/virtual-keyboard.h>
31
32 // INTERNAL INCLUDES
33 #include <dali-toolkit/public-api/text/rendering-backend.h>
34 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
35 #include <dali-toolkit/internal/text/rendering/text-backend.h>
36 #include <dali-toolkit/internal/styling/style-manager-impl.h>
37
38 using namespace Dali::Toolkit::Text;
39
40 namespace Dali
41 {
42
43 namespace Toolkit
44 {
45
46 namespace Internal
47 {
48
49 namespace
50 {
51   const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
52 }
53
54 namespace
55 {
56
57 const Scripting::StringEnum< Toolkit::Text::LayoutEngine::HorizontalAlignment > HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
58 {
59   { "BEGIN",  Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN  },
60   { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
61   { "END",    Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END    },
62 };
63 const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
64
65 const Scripting::StringEnum< Toolkit::Text::LayoutEngine::VerticalAlignment > VERTICAL_ALIGNMENT_STRING_TABLE[] =
66 {
67   { "TOP",    Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP    },
68   { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
69   { "BOTTOM", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_BOTTOM },
70 };
71 const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
72
73 // Type registration
74 BaseHandle Create()
75 {
76   return Toolkit::TextField::New();
77 }
78
79 // Setup properties, signals and actions using the type-registry.
80 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextField, Toolkit::Control, Create );
81
82 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "rendering-backend",                    INTEGER,   RENDERING_BACKEND                    )
83 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "placeholder-text",                     STRING,    PLACEHOLDER_TEXT                     )
84 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "text",                                 STRING,    TEXT                                 )
85 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "font-family",                          STRING,    FONT_FAMILY                          )
86 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "font-style",                           STRING,    FONT_STYLE                           )
87 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "point-size",                           FLOAT,     POINT_SIZE                           )
88 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "exceed-policy",                        INTEGER,   EXCEED_POLICY                        )
89 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "horizontal-alignment",                 STRING,    HORIZONTAL_ALIGNMENT                 )
90 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "vertical-alignment",                   STRING,    VERTICAL_ALIGNMENT                   )
91 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "text-color",                           VECTOR4,   TEXT_COLOR                           )
92 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "shadow-offset",                        VECTOR2,   SHADOW_OFFSET                        )
93 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "shadow-color",                         VECTOR4,   SHADOW_COLOR                         )
94 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "primary-cursor-color",                 VECTOR4,   PRIMARY_CURSOR_COLOR                 )
95 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "secondary-cursor-color",               VECTOR4,   SECONDARY_CURSOR_COLOR               )
96 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "enable-cursor-blink",                  BOOLEAN,   ENABLE_CURSOR_BLINK                  )
97 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "cursor-blink-interval",                FLOAT,     CURSOR_BLINK_INTERVAL                )
98 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "cursor-blink-duration",                FLOAT,     CURSOR_BLINK_DURATION                )
99 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "grab-handle-image",                    STRING,    GRAB_HANDLE_IMAGE                    )
100 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "grab-handle-pressed-image",            VECTOR4,   GRAB_HANDLE_PRESSED_IMAGE            )
101 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "scroll-threshold",                     FLOAT,     SCROLL_THRESHOLD                     )
102 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "scroll-speed",                         FLOAT,     SCROLL_SPEED                         )
103 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selection-handle-image-left",          STRING,    SELECTION_HANDLE_IMAGE_LEFT          )
104 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selection-handle-image-right",         STRING,    SELECTION_HANDLE_IMAGE_RIGHT         )
105 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selection-handle-pressed-image-left",  STRING,    SELECTION_HANDLE_PRESSED_IMAGE_LEFT  )
106 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selection-handle-pressed-image-right", STRING,    SELECTION_HANDLE_PRESSED_IMAGE_RIGHT )
107 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "selection-highlight-color",            STRING,    SELECTION_HIGHLIGHT_COLOR            )
108 DALI_PROPERTY_REGISTRATION( Toolkit, TextField, "decoration-bounding-box",              RECTANGLE, DECORATION_BOUNDING_BOX              )
109
110 DALI_TYPE_REGISTRATION_END()
111
112 } // namespace
113
114 Toolkit::TextField TextField::New()
115 {
116   // Create the implementation, temporarily owned by this handle on stack
117   IntrusivePtr< TextField > impl = new TextField();
118
119   // Pass ownership to CustomActor handle
120   Toolkit::TextField handle( *impl );
121
122   // Second-phase init of the implementation
123   // This can only be done after the CustomActor connection has been made...
124   impl->Initialize();
125
126   return handle;
127 }
128
129 void TextField::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
130 {
131   Toolkit::TextField textField = Toolkit::TextField::DownCast( Dali::BaseHandle( object ) );
132
133   if( textField )
134   {
135     TextField& impl( GetImpl( textField ) );
136
137     switch( index )
138     {
139       case Toolkit::TextField::Property::RENDERING_BACKEND:
140       {
141         int backend = value.Get< int >();
142
143         if( impl.mRenderingBackend != backend )
144         {
145           impl.mRenderingBackend = backend;
146           impl.mRenderer.Reset();
147         }
148         break;
149       }
150       case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
151       {
152         if( impl.mController )
153         {
154           //impl.mController->SetPlaceholderText( value.Get< std::string >() ); TODO
155         }
156         break;
157       }
158       case Toolkit::TextField::Property::TEXT:
159       {
160         if( impl.mController )
161         {
162           impl.mController->SetText( value.Get< std::string >() );
163         }
164         break;
165       }
166       case Toolkit::TextField::Property::FONT_FAMILY:
167       {
168         if( impl.mController )
169         {
170           std::string fontFamily = value.Get< std::string >();
171
172           if( impl.mController->GetDefaultFontFamily() != fontFamily )
173           {
174             impl.mController->SetDefaultFontFamily( fontFamily );
175             impl.RequestTextRelayout();
176           }
177         }
178         break;
179       }
180       case Toolkit::TextField::Property::FONT_STYLE:
181       {
182         if( impl.mController )
183         {
184           std::string fontStyle = value.Get< std::string >();
185
186           if( impl.mController->GetDefaultFontStyle() != fontStyle )
187           {
188             impl.mController->SetDefaultFontStyle( fontStyle );
189             impl.RequestTextRelayout();
190           }
191         }
192         break;
193       }
194       case Toolkit::TextField::Property::POINT_SIZE:
195       {
196         if( impl.mController )
197         {
198           float pointSize = value.Get< float >();
199
200           if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
201           {
202             impl.mController->SetDefaultPointSize( pointSize );
203             impl.RequestTextRelayout();
204           }
205         }
206         break;
207       }
208       case Toolkit::TextField::Property::EXCEED_POLICY:
209       {
210         impl.mExceedPolicy = value.Get< int >();
211         break;
212       }
213       case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
214       {
215         LayoutEngine& engine = impl.mController->GetLayoutEngine();
216         const LayoutEngine::HorizontalAlignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( value.Get< std::string >().c_str(),
217                                                                                                                                            HORIZONTAL_ALIGNMENT_STRING_TABLE,
218                                                                                                                                            HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
219
220         if( engine.GetHorizontalAlignment() != alignment )
221         {
222           engine.SetHorizontalAlignment( alignment );
223           impl.RequestTextRelayout();
224         }
225         break;
226       }
227       case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
228       {
229         LayoutEngine& engine = impl.mController->GetLayoutEngine();
230         const LayoutEngine::VerticalAlignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( value.Get< std::string >().c_str(),
231                                                                                                                                        VERTICAL_ALIGNMENT_STRING_TABLE,
232                                                                                                                                        VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
233
234         if( engine.GetVerticalAlignment() != alignment )
235         {
236           engine.SetVerticalAlignment( alignment );
237           impl.RequestTextRelayout();
238         }
239         break;
240       }
241       case Toolkit::TextField::Property::TEXT_COLOR:
242       {
243         if ( impl.mController )
244         {
245           Vector4 textColor = value.Get< Vector4 >();
246           if ( impl.mController->GetTextColor() != textColor )
247           {
248             impl.mController->SetTextColor( textColor );
249             impl.RequestTextRelayout();
250           }
251         }
252         break;
253       }
254       case Toolkit::TextField::Property::SHADOW_OFFSET:
255       {
256         if( impl.mController )
257         {
258           Vector2 shadowOffset = value.Get< Vector2 >();
259           if ( impl.mController->GetShadowOffset() != shadowOffset )
260           {
261             impl.mController->SetShadowOffset( shadowOffset );
262             impl.RequestTextRelayout();
263           }
264         }
265         break;
266       }
267       case Toolkit::TextField::Property::SHADOW_COLOR:
268       {
269         if( impl.mController )
270         {
271           Vector4 shadowColor = value.Get< Vector4 >();
272           if ( impl.mController->GetShadowColor() != shadowColor )
273           {
274             impl.mController->SetShadowColor( shadowColor );
275             impl.RequestTextRelayout();
276           }
277         }
278         break;
279       }
280       case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
281       {
282         if( impl.mDecorator )
283         {
284           impl.mDecorator->SetColor( PRIMARY_CURSOR, value.Get< Vector4 >() );
285         }
286         break;
287       }
288       case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
289       {
290         if( impl.mDecorator )
291         {
292           impl.mDecorator->SetColor( SECONDARY_CURSOR, value.Get< Vector4 >() );
293         }
294         break;
295       }
296       case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
297       {
298         if( impl.mController )
299         {
300           impl.mController->SetEnableCursorBlink( value.Get< bool >() );
301         }
302         break;
303       }
304       case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
305       {
306         if( impl.mDecorator )
307         {
308           impl.mDecorator->SetCursorBlinkInterval( value.Get< float >() );
309         }
310         break;
311       }
312       case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
313       {
314         if( impl.mDecorator )
315         {
316           impl.mDecorator->SetCursorBlinkDuration( value.Get< float >() );
317         }
318         break;
319       }
320       case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
321       {
322         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
323
324         if( impl.mDecorator )
325         {
326           impl.mDecorator->SetGrabHandleImage( GRAB_HANDLE_IMAGE_RELEASED, image );
327         }
328         break;
329       }
330       case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
331       {
332         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
333
334         if( impl.mDecorator )
335         {
336           impl.mDecorator->SetGrabHandleImage( GRAB_HANDLE_IMAGE_PRESSED, image );
337         }
338         break;
339       }
340       case Toolkit::TextField::Property::SCROLL_THRESHOLD:
341       {
342         float threshold = value.Get< float >();
343
344         if( impl.mDecorator )
345         {
346           impl.mDecorator->SetScrollThreshold( threshold );
347         }
348         break;
349       }
350       case Toolkit::TextField::Property::SCROLL_SPEED:
351       {
352         float speed = value.Get< float >();
353
354         if( impl.mDecorator )
355         {
356           impl.mDecorator->SetScrollSpeed( speed );
357         }
358         break;
359       }
360       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
361       {
362         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
363
364         if( impl.mDecorator )
365         {
366           impl.mDecorator->SetLeftSelectionImage( SELECTION_HANDLE_RELEASED, image );
367         }
368         break;
369       }
370       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
371       {
372         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
373
374         if( impl.mDecorator )
375         {
376           impl.mDecorator->SetRightSelectionImage( SELECTION_HANDLE_RELEASED, image );
377         }
378         break;
379       }
380       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
381       {
382         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
383
384         if( impl.mDecorator )
385         {
386           impl.mDecorator->SetLeftSelectionImage( SELECTION_HANDLE_PRESSED, image );
387         }
388         break;
389       }
390       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
391       {
392         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
393
394         if( impl.mDecorator )
395         {
396           impl.mDecorator->SetLeftSelectionImage( SELECTION_HANDLE_PRESSED, image );
397         }
398         break;
399       }
400       case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
401       {
402         Vector4 color = value.Get< Vector4 >();
403
404         if( impl.mDecorator )
405         {
406           impl.mDecorator->SetHighlightColor( color );
407         }
408         break;
409       }
410       case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
411       {
412         if( impl.mDecorator )
413         {
414           impl.mDecorator->SetBoundingBox( value.Get< Rect<int> >() );
415         }
416         break;
417       }
418     } // switch
419   } // textfield
420 }
421
422 Property::Value TextField::GetProperty( BaseObject* object, Property::Index index )
423 {
424   Property::Value value;
425
426   Toolkit::TextField textField = Toolkit::TextField::DownCast( Dali::BaseHandle( object ) );
427
428   if( textField )
429   {
430     TextField& impl( GetImpl( textField ) );
431
432     switch( index )
433     {
434       case Toolkit::TextField::Property::RENDERING_BACKEND:
435       {
436         value = impl.mRenderingBackend;
437         break;
438       }
439       case Toolkit::TextField::Property::PLACEHOLDER_TEXT:
440       {
441         if( impl.mController )
442         {
443           std::string text;
444           impl.mController->GetPlaceholderText( text );
445           value = text;
446         }
447         break;
448       }
449       case Toolkit::TextField::Property::TEXT:
450       {
451         if( impl.mController )
452         {
453           std::string text;
454           impl.mController->GetText( text );
455           value = text;
456         }
457         break;
458       }
459       case Toolkit::TextField::Property::EXCEED_POLICY:
460       {
461         value = impl.mExceedPolicy;
462         break;
463       }
464       case Toolkit::TextField::Property::HORIZONTAL_ALIGNMENT:
465       {
466         if( impl.mController )
467         {
468           value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
469                                                                                                                   HORIZONTAL_ALIGNMENT_STRING_TABLE,
470                                                                                                                   HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT ) );
471         }
472         break;
473       }
474       case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
475       {
476         if( impl.mController )
477         {
478           value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetLayoutEngine().GetVerticalAlignment(),
479                                                                                                                   VERTICAL_ALIGNMENT_STRING_TABLE,
480                                                                                                                   VERTICAL_ALIGNMENT_STRING_TABLE_COUNT ) );
481         }
482         break;
483       }
484       case Toolkit::TextField::Property::TEXT_COLOR:
485       {
486         if ( impl.mController )
487         {
488           value = impl.mController->GetTextColor();
489         }
490         break;
491       }
492       case Toolkit::TextField::Property::SHADOW_OFFSET:
493       {
494         if ( impl.mController )
495         {
496           value = impl.mController->GetShadowOffset();
497         }
498         break;
499       }
500       case Toolkit::TextField::Property::SHADOW_COLOR:
501       {
502         if ( impl.mController )
503         {
504           value = impl.mController->GetShadowColor();
505         }
506         break;
507       }
508       case Toolkit::TextField::Property::PRIMARY_CURSOR_COLOR:
509       {
510         if( impl.mDecorator )
511         {
512           value = impl.mDecorator->GetColor( PRIMARY_CURSOR );
513         }
514         break;
515       }
516       case Toolkit::TextField::Property::SECONDARY_CURSOR_COLOR:
517       {
518         if( impl.mDecorator )
519         {
520           value = impl.mDecorator->GetColor( SECONDARY_CURSOR );
521         }
522         break;
523       }
524       case Toolkit::TextField::Property::ENABLE_CURSOR_BLINK:
525       {
526         value = impl.mController->GetEnableCursorBlink();
527         break;
528       }
529       case Toolkit::TextField::Property::CURSOR_BLINK_INTERVAL:
530       {
531         if( impl.mDecorator )
532         {
533           value = impl.mDecorator->GetCursorBlinkInterval();
534         }
535         break;
536       }
537       case Toolkit::TextField::Property::CURSOR_BLINK_DURATION:
538       {
539         if( impl.mDecorator )
540         {
541           value = impl.mDecorator->GetCursorBlinkDuration();
542         }
543         break;
544       }
545       case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
546       {
547         if( impl.mDecorator )
548         {
549           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetGrabHandleImage( GRAB_HANDLE_IMAGE_RELEASED ) );
550           if( image )
551           {
552             value = image.GetUrl();
553           }
554         }
555         break;
556       }
557       case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
558       {
559         if( impl.mDecorator )
560         {
561           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetGrabHandleImage( GRAB_HANDLE_IMAGE_PRESSED ) );
562           if( image )
563           {
564             value = image.GetUrl();
565           }
566         }
567         break;
568       }
569       case Toolkit::TextField::Property::SCROLL_THRESHOLD:
570       {
571         if( impl.mDecorator )
572         {
573           value = impl.mDecorator->GetScrollThreshold();
574         }
575         break;
576       }
577       case Toolkit::TextField::Property::SCROLL_SPEED:
578       {
579         if( impl.mDecorator )
580         {
581           value = impl.mDecorator->GetScrollSpeed();
582         }
583         break;
584       }
585       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
586       {
587         if( impl.mDecorator )
588         {
589           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetLeftSelectionImage( SELECTION_HANDLE_RELEASED ) );
590           if( image )
591           {
592             value = image.GetUrl();
593           }
594         }
595         break;
596       }
597       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
598       {
599         if( impl.mDecorator )
600         {
601           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetRightSelectionImage( SELECTION_HANDLE_RELEASED ) );
602           if( image )
603           {
604             value = image.GetUrl();
605           }
606         }
607         break;
608       }
609       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
610       {
611         if( impl.mDecorator )
612         {
613           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetLeftSelectionImage( SELECTION_HANDLE_PRESSED ) );
614           if( image )
615           {
616             value = image.GetUrl();
617           }
618         }
619         break;
620       }
621       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
622       {
623         if( impl.mDecorator )
624         {
625           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetRightSelectionImage( SELECTION_HANDLE_PRESSED ) );
626           if( image )
627           {
628             value = image.GetUrl();
629           }
630         }
631         break;
632       }
633       case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
634       {
635         if( impl.mDecorator )
636         {
637           value = impl.mDecorator->GetHighlightColor();
638         }
639         break;
640       }
641       case Toolkit::TextField::Property::DECORATION_BOUNDING_BOX:
642       {
643         if( impl.mDecorator )
644         {
645           value = impl.mDecorator->GetBoundingBox();
646         }
647         break;
648       }
649     } //switch
650   }
651
652   return value;
653 }
654
655 void TextField::OnInitialize()
656 {
657   Actor self = Self();
658
659   mController = Text::Controller::New( *this );
660
661   mDecorator = Text::Decorator::New( *this, *mController );
662
663   mController->GetLayoutEngine().SetLayout( LayoutEngine::SINGLE_LINE_BOX );
664
665   mController->EnableTextInput( mDecorator );
666
667   // Forward input events to controller
668   EnableGestureDetection(Gesture::Tap);
669   GetTapGestureDetector().SetMaximumTapsRequired( 2 );
670   EnableGestureDetection(Gesture::Pan);
671
672   // Set BoundingBox to stage size if not already set.
673   if ( mDecorator->GetBoundingBox().IsEmpty() )
674   {
675     Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
676     mDecorator->SetBoundingBox( Rect<int>( 0.0f, 0.0f, stageSize.width, stageSize.height ) );
677   }
678
679   // Fill-parent area by default
680   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
681   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
682 }
683
684 void TextField::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange change )
685 {
686   GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
687 }
688
689 Vector3 TextField::GetNaturalSize()
690 {
691   return mController->GetNaturalSize();
692 }
693
694 float TextField::GetHeightForWidth( float width )
695 {
696   return mController->GetHeightForWidth( width );
697 }
698
699 void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
700 {
701   if( mController->Relayout( size ) ||
702       !mRenderer )
703   {
704     if( mDecorator )
705     {
706       mDecorator->Relayout( size );
707     }
708
709     if( !mRenderer )
710     {
711       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
712     }
713
714     RenderableActor renderableActor;
715     if( mRenderer )
716     {
717       renderableActor = mRenderer->Render( mController->GetView() );
718     }
719
720     EnableClipping( (Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy), size );
721
722     if( renderableActor != mRenderableActor )
723     {
724       UnparentAndReset( mRenderableActor );
725       mRenderableActor = renderableActor;
726     }
727
728     if( mRenderableActor )
729     {
730       const Vector2 offset = mController->GetScrollPosition() + mController->GetAlignmentOffset();
731
732       mRenderableActor.SetPosition( offset.x, offset.y );
733
734       // Make sure the actor is parented correctly with/without clipping
735       if( mClipper )
736       {
737         mClipper->GetRootActor().Add( mRenderableActor );
738       }
739       else
740       {
741         Self().Add( mRenderableActor );
742       }
743     }
744   }
745 }
746
747 void TextField::OnKeyInputFocusGained()
748 {
749   VirtualKeyboard::StatusChangedSignal().Connect( this, &TextField::KeyboardStatusChanged );
750
751   ImfManager imfManager = ImfManager::Get();
752
753   if ( imfManager )
754   {
755     imfManager.EventReceivedSignal().Connect( this, &TextField::OnImfEvent );
756
757     // Notify that the text editing start.
758     imfManager.Activate();
759
760     // When window gain lost focus, the imf manager is deactivated. Thus when window gain focus again, the imf manager must be activated.
761     imfManager.SetRestoreAfterFocusLost( true );
762   }
763
764   mController->KeyboardFocusGainEvent();
765
766   EmitKeyInputFocusSignal( true ); // Calls back into the Control hence done last.
767 }
768
769 void TextField::OnKeyInputFocusLost()
770 {
771   VirtualKeyboard::StatusChangedSignal().Disconnect( this, &TextField::KeyboardStatusChanged );
772
773   ImfManager imfManager = ImfManager::Get();
774   if ( imfManager )
775   {
776     // The text editing is finished. Therefore the imf manager don't have restore activation.
777     imfManager.SetRestoreAfterFocusLost( false );
778
779     // Notify that the text editing finish.
780     imfManager.Deactivate();
781
782     imfManager.EventReceivedSignal().Disconnect( this, &TextField::OnImfEvent );
783   }
784
785   mController->KeyboardFocusLostEvent();
786
787   EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
788 }
789
790 void TextField::OnTap( const TapGesture& gesture )
791 {
792   // Show the keyboard if it was hidden.
793   if (!VirtualKeyboard::IsVisible())
794   {
795     VirtualKeyboard::Show();
796   }
797
798   SetKeyInputFocus();
799
800   mController->TapEvent( gesture.numberOfTaps, gesture.localPoint.x, gesture.localPoint.y );
801 }
802
803 void TextField::OnPan( const PanGesture& gesture )
804 {
805   mController->PanEvent( gesture.state, gesture.displacement );
806 }
807
808 bool TextField::OnKeyEvent( const KeyEvent& event )
809 {
810   if( Dali::DALI_KEY_ESCAPE == event.keyCode )
811   {
812     ClearKeyInputFocus();
813   }
814
815   return mController->KeyEvent( event );
816 }
817
818 ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
819 {
820   switch ( imfEvent.eventName )
821   {
822     case ImfManager::COMMIT:
823     {
824       KeyEvent event( "", imfEvent.predictiveString, 0, 0, 0, KeyEvent::Down );
825       mController->KeyEvent( event );
826       break;
827     }
828     case ImfManager::PREEDIT: // fall through
829     case ImfManager::DELETESURROUNDING:
830     case ImfManager::GETSURROUNDING:
831     case ImfManager::VOID:
832     {
833       // do nothing
834     }
835   } // end switch
836
837   return ImfManager::ImfCallbackData();
838 }
839
840 void TextField::RequestTextRelayout()
841 {
842   RelayoutRequest();
843 }
844
845 void TextField::EnableClipping( bool clipping, const Vector2& size )
846 {
847   if( clipping )
848   {
849     // Not worth to created clip actor if width or height is equal to zero.
850     if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
851     {
852       if( !mClipper )
853       {
854         Actor self = Self();
855
856         mClipper = Clipper::New( size );
857         self.Add( mClipper->GetRootActor() );
858         self.Add( mClipper->GetImageActor() );
859       }
860       else if ( mClipper )
861       {
862         mClipper->Refresh( size );
863       }
864     }
865   }
866   else
867   {
868     // Note - this will automatically remove the root & image actors
869     mClipper.Reset();
870   }
871 }
872
873 void TextField::KeyboardStatusChanged(bool keyboardShown)
874 {
875   // Just hide the grab handle when keyboard is hidden.
876   if (!keyboardShown )
877   {
878     mController->KeyboardFocusLostEvent();
879   }
880 }
881
882 TextField::TextField()
883 : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
884   mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
885   mExceedPolicy( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP )
886 {
887 }
888
889 TextField::~TextField()
890 {
891   mClipper.Reset();
892 }
893
894 } // namespace Internal
895
896 } // namespace Toolkit
897
898 } // namespace Dali