4ebda6f12a0b8b2ae9e4b425a390b396ce7956aa
[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/integration-api/debug.h>
25
26 // INTERNAL INCLUDES
27 #include <dali-toolkit/public-api/text/layouts/layout-engine.h>
28 #include <dali-toolkit/public-api/text/rendering/text-backend.h>
29
30 using namespace Dali::Toolkit::Text;
31
32 namespace
33 {
34
35 } // namespace
36
37 namespace Dali
38 {
39
40 namespace Toolkit
41 {
42
43 const Property::Index TextField::PROPERTY_RENDERING_BACKEND(      Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX );
44 const Property::Index TextField::PROPERTY_PLACEHOLDER_TEXT(       Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 1 );
45 const Property::Index TextField::PROPERTY_TEXT(                   Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 2 );
46 const Property::Index TextField::PROPERTY_CURSOR_IMAGE(           Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 3 );
47 const Property::Index TextField::PROPERTY_PRIMARY_CURSOR_COLOR(   Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 4 );
48 const Property::Index TextField::PROPERTY_SECONDARY_CURSOR_COLOR( Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 5 );
49 const Property::Index TextField::PROPERTY_ENABLE_CURSOR_BLINK(    Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 6 );
50 const Property::Index TextField::PROPERTY_CURSOR_BLINK_INTERVAL(  Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 7 );
51 const Property::Index TextField::PROPERTY_CURSOR_BLINK_DURATION(  Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 8 );
52 const Property::Index TextField::PROPERTY_GRAB_HANDLE_IMAGE(      Internal::TextField::TEXTFIELD_PROPERTY_START_INDEX + 9 );
53
54 namespace Internal
55 {
56
57 namespace
58 {
59
60 // Type registration
61 BaseHandle Create()
62 {
63   return Toolkit::TextField::New();
64 }
65
66 TypeRegistration mType( typeid(Toolkit::TextField), typeid(Toolkit::Control), Create );
67
68 PropertyRegistration property01( mType, "rendering-backend",      Toolkit::TextField::PROPERTY_RENDERING_BACKEND,      Property::UNSIGNED_INTEGER, &TextField::SetProperty, &TextField::GetProperty );
69 PropertyRegistration property02( mType, "placeholder-text",       Toolkit::TextField::PROPERTY_PLACEHOLDER_TEXT,       Property::STRING,           &TextField::SetProperty, &TextField::GetProperty );
70 PropertyRegistration property03( mType, "text",                   Toolkit::TextField::PROPERTY_TEXT,                   Property::STRING,           &TextField::SetProperty, &TextField::GetProperty );
71 PropertyRegistration property04( mType, "cursor-image",           Toolkit::TextField::PROPERTY_CURSOR_IMAGE,           Property::STRING,           &TextField::SetProperty, &TextField::GetProperty );
72 PropertyRegistration property05( mType, "primary-cursor-color",   Toolkit::TextField::PROPERTY_PRIMARY_CURSOR_COLOR,   Property::VECTOR4,          &TextField::SetProperty, &TextField::GetProperty );
73 PropertyRegistration property06( mType, "secondary-cursor-color", Toolkit::TextField::PROPERTY_SECONDARY_CURSOR_COLOR, Property::VECTOR4,          &TextField::SetProperty, &TextField::GetProperty );
74 PropertyRegistration property07( mType, "enable-cursor-blink",    Toolkit::TextField::PROPERTY_ENABLE_CURSOR_BLINK,    Property::BOOLEAN,          &TextField::SetProperty, &TextField::GetProperty );
75 PropertyRegistration property08( mType, "cursor-blink-interval",  Toolkit::TextField::PROPERTY_CURSOR_BLINK_INTERVAL,  Property::FLOAT,            &TextField::SetProperty, &TextField::GetProperty );
76 PropertyRegistration property09( mType, "cursor-blink-duration",  Toolkit::TextField::PROPERTY_CURSOR_BLINK_DURATION,  Property::FLOAT,            &TextField::SetProperty, &TextField::GetProperty );
77 PropertyRegistration property10( mType, "grab-handle-image",      Toolkit::TextField::PROPERTY_GRAB_HANDLE_IMAGE,      Property::STRING,           &TextField::SetProperty, &TextField::GetProperty );
78
79 } // namespace
80
81 Toolkit::TextField TextField::New()
82 {
83   // Create the implementation, temporarily owned by this handle on stack
84   IntrusivePtr< TextField > impl = new TextField();
85
86   // Pass ownership to CustomActor handle
87   Toolkit::TextField handle( *impl );
88
89   // Second-phase init of the implementation
90   // This can only be done after the CustomActor connection has been made...
91   impl->Initialize();
92
93   return handle;
94 }
95
96 void TextField::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
97 {
98   Toolkit::TextField textField = Toolkit::TextField::DownCast( Dali::BaseHandle( object ) );
99
100   if( textField )
101   {
102     TextField& impl( GetImpl( textField ) );
103
104     switch( index )
105     {
106       case Toolkit::TextField::PROPERTY_RENDERING_BACKEND:
107       {
108         unsigned int backend = value.Get< unsigned int >();
109
110         if( impl.mRenderingBackend != backend )
111         {
112           impl.mRenderingBackend = backend;
113           impl.mRenderer.Reset();
114         }
115         break;
116       }
117       case Toolkit::TextField::PROPERTY_PLACEHOLDER_TEXT:
118       {
119         if( impl.mController )
120         {
121           //impl.mController->SetPlaceholderText( value.Get< std::string >() ); TODO
122         }
123         break;
124       }
125       case Toolkit::TextField::PROPERTY_TEXT:
126       {
127         if( impl.mController )
128         {
129           impl.mController->SetText( value.Get< std::string >() );
130         }
131         break;
132       }
133       case Toolkit::TextField::PROPERTY_CURSOR_IMAGE:
134       {
135         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
136
137         if( impl.mDecorator )
138         {
139           impl.mDecorator->SetCursorImage( image );
140         }
141         break;
142       }
143       case Toolkit::TextField::PROPERTY_PRIMARY_CURSOR_COLOR:
144       {
145         if( impl.mDecorator )
146         {
147           impl.mDecorator->SetColor( PRIMARY_CURSOR, value.Get< Vector4 >() );
148         }
149         break;
150       }
151       case Toolkit::TextField::PROPERTY_SECONDARY_CURSOR_COLOR:
152       {
153         if( impl.mDecorator )
154         {
155           impl.mDecorator->SetColor( SECONDARY_CURSOR, value.Get< Vector4 >() );
156         }
157         break;
158       }
159       case Toolkit::TextField::PROPERTY_ENABLE_CURSOR_BLINK:
160       {
161         if( impl.mController )
162         {
163           //impl.mController->SetEnableCursorBlink( value.Get< bool >() ); TODO
164         }
165         break;
166       }
167       case Toolkit::TextField::PROPERTY_CURSOR_BLINK_INTERVAL:
168       {
169         if( impl.mDecorator )
170         {
171           impl.mDecorator->SetCursorBlinkInterval( value.Get< float >() );
172         }
173         break;
174       }
175       case Toolkit::TextField::PROPERTY_CURSOR_BLINK_DURATION:
176       {
177         if( impl.mDecorator )
178         {
179           impl.mDecorator->SetCursorBlinkDuration( value.Get< float >() );
180         }
181         break;
182       }
183       case Toolkit::TextField::PROPERTY_GRAB_HANDLE_IMAGE:
184       {
185         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
186
187         if( impl.mDecorator )
188         {
189           impl.mDecorator->SetGrabHandleImage( image );
190         }
191         break;
192       }
193     }
194   }
195 }
196
197 Property::Value TextField::GetProperty( BaseObject* object, Property::Index index )
198 {
199   Property::Value value;
200
201   Toolkit::TextField textField = Toolkit::TextField::DownCast( Dali::BaseHandle( object ) );
202
203   if( textField )
204   {
205     TextField& impl( GetImpl( textField ) );
206
207     switch( index )
208     {
209       case Toolkit::TextField::PROPERTY_RENDERING_BACKEND:
210       {
211         value = impl.mRenderingBackend;
212         break;
213       }
214       case Toolkit::TextField::PROPERTY_PLACEHOLDER_TEXT:
215       {
216         DALI_LOG_WARNING( "UTF-8 text representation was discarded\n" );
217         break;
218       }
219       case Toolkit::TextField::PROPERTY_TEXT:
220       {
221         DALI_LOG_WARNING( "UTF-8 text representation was discarded\n" );
222         break;
223       }
224       case Toolkit::TextField::PROPERTY_CURSOR_IMAGE:
225       {
226         if( impl.mDecorator )
227         {
228           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetCursorImage() );
229           if( image )
230           {
231             value = image.GetUrl();
232           }
233         }
234         break;
235       }
236       case Toolkit::TextField::PROPERTY_PRIMARY_CURSOR_COLOR:
237       {
238         if( impl.mDecorator )
239         {
240           value = impl.mDecorator->GetColor( PRIMARY_CURSOR );
241         }
242         break;
243       }
244       case Toolkit::TextField::PROPERTY_SECONDARY_CURSOR_COLOR:
245       {
246         if( impl.mDecorator )
247         {
248           value = impl.mDecorator->GetColor( SECONDARY_CURSOR );
249         }
250         break;
251       }
252       case Toolkit::TextField::PROPERTY_ENABLE_CURSOR_BLINK:
253       {
254         //value = impl.mController->GetEnableCursorBlink(); TODO
255         break;
256       }
257       case Toolkit::TextField::PROPERTY_CURSOR_BLINK_INTERVAL:
258       {
259         if( impl.mDecorator )
260         {
261           value = impl.mDecorator->GetCursorBlinkInterval();
262         }
263         break;
264       }
265       case Toolkit::TextField::PROPERTY_CURSOR_BLINK_DURATION:
266       {
267         if( impl.mDecorator )
268         {
269           value = impl.mDecorator->GetCursorBlinkDuration();
270         }
271         break;
272       }
273       case Toolkit::TextField::PROPERTY_GRAB_HANDLE_IMAGE:
274       {
275         if( impl.mDecorator )
276         {
277           ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetCursorImage() );
278           if( image )
279           {
280             value = image.GetUrl();
281           }
282         }
283         break;
284       }
285     }
286   }
287
288   return value;
289 }
290
291 void TextField::OnInitialize()
292 {
293   mController = Text::Controller::New( *this );
294
295   mDecorator = Text::Decorator::New( *this, *mController );
296
297   mController->GetLayoutEngine().SetLayout( LayoutEngine::SINGLE_LINE_BOX );
298
299   mController->EnableTextInput( mDecorator );
300
301   // Forward input events to controller
302   EnableGestureDetection( Gesture::Tap );
303 }
304
305 void TextField::OnRelayout( const Vector2& size, ActorSizeContainer& container )
306 {
307   if( mController->Relayout( size ) )
308   {
309     if( !mRenderer )
310     {
311       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
312     }
313
314     if( mRenderer )
315     {
316       Actor renderableActor = mRenderer->Render( mController->GetView() );
317
318       if( renderableActor )
319       {
320         Self().Add( renderableActor );
321       }
322     }
323   }
324 }
325
326 void TextField::OnTap( const TapGesture& tap )
327 {
328   mController->TapEvent( tap.localPoint.x, tap.localPoint.y );
329 }
330
331 void TextField::RequestTextRelayout()
332 {
333   RelayoutRequest();
334 }
335
336 TextField::TextField()
337 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_NONE ) )
338 {
339 }
340
341 TextField::~TextField()
342 {
343 }
344
345 } // namespace Internal
346
347 } // namespace Toolkit
348
349 } // namespace Dali