Property system fixes
[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 <dali/public-api/images/resource-image.h>
23 #include <dali/public-api/object/type-registry.h>
24 #include <dali/public-api/common/stage.h>
25 #include <dali/integration-api/debug.h>
26
27 // INTERNAL INCLUDES
28 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
29 #include <dali-toolkit/internal/text/rendering/text-backend.h>
30
31 using namespace Dali::Toolkit::Text;
32
33 namespace
34 {
35
36 const unsigned int DEFAULT_RENDERING_BACKEND = 0;
37
38 } // namespace
39
40
41 namespace Dali
42 {
43
44 namespace Toolkit
45 {
46
47 namespace Internal
48 {
49
50 namespace
51 {
52
53 // Type registration
54 BaseHandle Create()
55 {
56   return Toolkit::TextField::New();
57 }
58
59 TypeRegistration mType( typeid(Toolkit::TextField), typeid(Toolkit::Control), Create );
60
61 // Setup properties, signals and actions using the type-registry.
62 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextField, Toolkit::Control, Create );
63
64 DALI_PROPERTY_REGISTRATION( TextField, "rendering-backend",       INT,       RENDERING_BACKEND       )
65 DALI_PROPERTY_REGISTRATION( TextField, "placeholder-text",        STRING,    PLACEHOLDER_TEXT        )
66 DALI_PROPERTY_REGISTRATION( TextField, "text",                    STRING,    TEXT                    )
67 DALI_PROPERTY_REGISTRATION( TextField, "font-family",             STRING,    FONT_FAMILY             )
68 DALI_PROPERTY_REGISTRATION( TextField, "font-style",              STRING,    FONT_STYLE              )
69 DALI_PROPERTY_REGISTRATION( TextField, "point-size",              FLOAT,     POINT_SIZE              )
70 DALI_PROPERTY_REGISTRATION( TextField, "cursor-image",            STRING,    CURSOR_IMAGE            )
71 DALI_PROPERTY_REGISTRATION( TextField, "primary-cursor-color",    VECTOR4,   PRIMARY_CURSOR_COLOR    )
72 DALI_PROPERTY_REGISTRATION( TextField, "secondary-cursor-color",  VECTOR4,   SECONDARY_CURSOR_COLOR  )
73 DALI_PROPERTY_REGISTRATION( TextField, "enable-cursor-blink",     BOOLEAN,   ENABLE_CURSOR_BLINK     )
74 DALI_PROPERTY_REGISTRATION( TextField, "cursor-blink-interval",   FLOAT,     CURSOR_BLINK_INTERVAL   )
75 DALI_PROPERTY_REGISTRATION( TextField, "cursor-blink-duration",   FLOAT,     CURSOR_BLINK_DURATION   )
76 DALI_PROPERTY_REGISTRATION( TextField, "grab-handle-image",       STRING,    GRAB_HANDLE_IMAGE       )
77 DALI_PROPERTY_REGISTRATION( TextField, "decoration bounding-box", RECTANGLE, DECORATION_BOUNDING_BOX )
78
79 DALI_TYPE_REGISTRATION_END()
80
81 } // namespace
82
83 Toolkit::TextField TextField::New()
84 {
85   // Create the implementation, temporarily owned by this handle on stack
86   IntrusivePtr< TextField > impl = new TextField();
87
88   // Pass ownership to CustomActor handle
89   Toolkit::TextField handle( *impl );
90
91   // Second-phase init of the implementation
92   // This can only be done after the CustomActor connection has been made...
93   impl->Initialize();
94
95   return handle;
96 }
97
98 void TextField::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
99 {
100   Toolkit::TextField textField = Toolkit::TextField::DownCast( Dali::BaseHandle( object ) );
101
102   if( textField )
103   {
104     TextField& impl( GetImpl( textField ) );
105
106     switch( index )
107     {
108       case Toolkit::TextField::PROPERTY_RENDERING_BACKEND:
109       {
110         unsigned int backend = value.Get< unsigned int >();
111
112         if( impl.mRenderingBackend != backend )
113         {
114           impl.mRenderingBackend = backend;
115           impl.mRenderer.Reset();
116         }
117         break;
118       }
119       case Toolkit::TextField::PROPERTY_PLACEHOLDER_TEXT:
120       {
121         if( impl.mController )
122         {
123           //impl.mController->SetPlaceholderText( value.Get< std::string >() ); TODO
124         }
125         break;
126       }
127       case Toolkit::TextField::PROPERTY_TEXT:
128       {
129         if( impl.mController )
130         {
131           impl.mController->SetText( value.Get< std::string >() );
132         }
133         break;
134       }
135       case Toolkit::TextField::PROPERTY_CURSOR_IMAGE:
136       {
137         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
138
139         if( impl.mDecorator )
140         {
141           impl.mDecorator->SetCursorImage( image );
142         }
143         break;
144       }
145       case Toolkit::TextField::PROPERTY_PRIMARY_CURSOR_COLOR:
146       {
147         if( impl.mDecorator )
148         {
149           impl.mDecorator->SetColor( PRIMARY_CURSOR, value.Get< Vector4 >() );
150         }
151         break;
152       }
153       case Toolkit::TextField::PROPERTY_SECONDARY_CURSOR_COLOR:
154       {
155         if( impl.mDecorator )
156         {
157           impl.mDecorator->SetColor( SECONDARY_CURSOR, value.Get< Vector4 >() );
158         }
159         break;
160       }
161       case Toolkit::TextField::PROPERTY_ENABLE_CURSOR_BLINK:
162       {
163         if( impl.mController )
164         {
165           //impl.mController->SetEnableCursorBlink( value.Get< bool >() ); TODO
166         }
167         break;
168       }
169       case Toolkit::TextField::PROPERTY_CURSOR_BLINK_INTERVAL:
170       {
171         if( impl.mDecorator )
172         {
173           impl.mDecorator->SetCursorBlinkInterval( value.Get< float >() );
174         }
175         break;
176       }
177       case Toolkit::TextField::PROPERTY_CURSOR_BLINK_DURATION:
178       {
179         if( impl.mDecorator )
180         {
181           impl.mDecorator->SetCursorBlinkDuration( value.Get< float >() );
182         }
183         break;
184       }
185       case Toolkit::TextField::PROPERTY_GRAB_HANDLE_IMAGE:
186       {
187         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
188
189         if( impl.mDecorator )
190         {
191           impl.mDecorator->SetGrabHandleImage( image );
192         }
193         break;
194       }
195       case Toolkit::TextField::PROPERTY_DECORATION_BOUNDING_BOX:
196       {
197         if( impl.mDecorator )
198         {
199           impl.mDecorator->SetBoundingBox( value.Get< Rect<int> >() );
200         }
201         break;
202       }
203     }
204   }
205 }
206
207 Property::Value TextField::GetProperty( BaseObject* object, Property::Index index )
208 {
209   Property::Value value;
210
211   Toolkit::TextField textField = Toolkit::TextField::DownCast( Dali::BaseHandle( object ) );
212
213   if( textField )
214   {
215     TextField& impl( GetImpl( textField ) );
216
217     switch( index )
218     {
219       case Toolkit::TextField::PROPERTY_RENDERING_BACKEND:
220       {
221         value = impl.mRenderingBackend;
222         break;
223       }
224       case Toolkit::TextField::PROPERTY_PLACEHOLDER_TEXT:
225       {
226         DALI_LOG_WARNING( "UTF-8 text representation was discarded\n" );
227         break;
228       }
229       case Toolkit::TextField::PROPERTY_TEXT:
230       {
231         DALI_LOG_WARNING( "UTF-8 text representation was discarded\n" );
232         break;
233       }
234       case Toolkit::TextField::PROPERTY_CURSOR_IMAGE:
235       {
236         if( impl.mDecorator )
237         {
238           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetCursorImage() );
239           if( image )
240           {
241             value = image.GetUrl();
242           }
243         }
244         break;
245       }
246       case Toolkit::TextField::PROPERTY_PRIMARY_CURSOR_COLOR:
247       {
248         if( impl.mDecorator )
249         {
250           value = impl.mDecorator->GetColor( PRIMARY_CURSOR );
251         }
252         break;
253       }
254       case Toolkit::TextField::PROPERTY_SECONDARY_CURSOR_COLOR:
255       {
256         if( impl.mDecorator )
257         {
258           value = impl.mDecorator->GetColor( SECONDARY_CURSOR );
259         }
260         break;
261       }
262       case Toolkit::TextField::PROPERTY_ENABLE_CURSOR_BLINK:
263       {
264         //value = impl.mController->GetEnableCursorBlink(); TODO
265         break;
266       }
267       case Toolkit::TextField::PROPERTY_CURSOR_BLINK_INTERVAL:
268       {
269         if( impl.mDecorator )
270         {
271           value = impl.mDecorator->GetCursorBlinkInterval();
272         }
273         break;
274       }
275       case Toolkit::TextField::PROPERTY_CURSOR_BLINK_DURATION:
276       {
277         if( impl.mDecorator )
278         {
279           value = impl.mDecorator->GetCursorBlinkDuration();
280         }
281         break;
282       }
283       case Toolkit::TextField::PROPERTY_GRAB_HANDLE_IMAGE:
284       {
285         if( impl.mDecorator )
286         {
287           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetCursorImage() );
288           if( image )
289           {
290             value = image.GetUrl();
291           }
292         }
293         break;
294       }
295       case Toolkit::TextField::PROPERTY_DECORATION_BOUNDING_BOX:
296       {
297         if( impl.mDecorator )
298         {
299           value = impl.mDecorator->GetBoundingBox();
300         }
301         break;
302       }
303     }
304   }
305
306   return value;
307 }
308
309 void TextField::OnInitialize()
310 {
311   mController = Text::Controller::New( *this );
312
313   mDecorator = Text::Decorator::New( *this, *mController );
314
315   mController->GetLayoutEngine().SetLayout( LayoutEngine::SINGLE_LINE_BOX );
316
317   mController->EnableTextInput( mDecorator );
318
319   // Forward input events to controller
320   mDoubleTapDetector = TapGestureDetector::New();
321   mDoubleTapDetector.SetMaximumTapsRequired( 2 );
322   mDoubleTapDetector.DetectedSignal().Connect( this, &TextField::OnTap );
323   mDoubleTapDetector.Attach(Self());
324
325   // Set BoundingBox to stage size if not already set.
326   if ( mDecorator->GetBoundingBox().IsEmpty() )
327   {
328     Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
329     mDecorator->SetBoundingBox( Rect<int>( 0.0f, 0.0f, stageSize.width, stageSize.height ) );
330   }
331 }
332
333 Vector3 TextField::GetNaturalSize()
334 {
335   return mController->GetNaturalSize();
336 }
337
338 float TextField::GetHeightForWidth( float width )
339 {
340   return mController->GetHeightForWidth( width );
341 }
342
343 void TextField::OnRelayout( const Vector2& size, ActorSizeContainer& container )
344 {
345   if( mController->Relayout( size ) )
346   {
347     if( mDecorator )
348     {
349       mDecorator->Relayout( size );
350     }
351
352     if( !mRenderer )
353     {
354       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
355     }
356
357     if( mRenderer )
358     {
359       Actor renderableActor = mRenderer->Render( mController->GetView() );
360
361       if( renderableActor )
362       {
363         Self().Add( renderableActor );
364       }
365     }
366   }
367 }
368
369 void TextField::OnTap( Actor actor, const TapGesture& gesture )
370 {
371   mController->TapEvent( gesture.numberOfTaps, gesture.localPoint.x, gesture.localPoint.y );
372 }
373
374 void TextField::RequestTextRelayout()
375 {
376   RelayoutRequest();
377 }
378
379 TextField::TextField()
380 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_NONE ) ),
381   mRenderingBackend( DEFAULT_RENDERING_BACKEND )
382 {
383 }
384
385 TextField::~TextField()
386 {
387 }
388
389 } // namespace Internal
390
391 } // namespace Toolkit
392
393 } // namespace Dali