Merge remote-tracking branch 'origin/tizen' into new_text
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-label-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-label-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/object/type-registry.h>
23 #include <dali/public-api/object/type-registry-helper.h>
24 #include <dali/public-api/scripting/scripting.h>
25 #include <dali/integration-api/debug.h>
26
27 // INTERNAL INCLUDES
28 #include <dali-toolkit/public-api/text/rendering-backend.h>
29 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
30 #include <dali-toolkit/internal/text/rendering/text-backend.h>
31 #include <dali-toolkit/internal/styling/style-manager-impl.h>
32
33 using Dali::Toolkit::Text::LayoutEngine;
34 using Dali::Toolkit::Text::Backend;
35
36 namespace Dali
37 {
38
39 namespace Toolkit
40 {
41
42 namespace Internal
43 {
44
45 namespace
46 {
47   const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
48 }
49
50 namespace
51 {
52
53 const Scripting::StringEnum< Toolkit::Text::LayoutEngine::Alignment > ALIGNMENT_STRING_TABLE[] =
54 {
55   { "BEGIN",  Toolkit::Text::LayoutEngine::ALIGN_BEGIN  },
56   { "CENTER", Toolkit::Text::LayoutEngine::ALIGN_CENTER },
57   { "END",    Toolkit::Text::LayoutEngine::ALIGN_END    },
58 };
59 const unsigned int ALIGNMENT_STRING_TABLE_COUNT = sizeof( ALIGNMENT_STRING_TABLE ) / sizeof( ALIGNMENT_STRING_TABLE[0] );
60
61 // Type registration
62 BaseHandle Create()
63 {
64   return Toolkit::TextLabel::New();
65 }
66
67 // Setup properties, signals and actions using the type-registry.
68 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextLabel, Toolkit::Control, Create );
69
70 DALI_PROPERTY_REGISTRATION( TextLabel, "rendering-backend", INTEGER, RENDERING_BACKEND )
71 DALI_PROPERTY_REGISTRATION( TextLabel, "text",              STRING,  TEXT              )
72 DALI_PROPERTY_REGISTRATION( TextLabel, "font-family",       STRING,  FONT_FAMILY       )
73 DALI_PROPERTY_REGISTRATION( TextLabel, "font-style",        STRING,  FONT_STYLE        )
74 DALI_PROPERTY_REGISTRATION( TextLabel, "point-size",        FLOAT,   POINT_SIZE        )
75 DALI_PROPERTY_REGISTRATION( TextLabel, "multi-line",        BOOLEAN, MULTI_LINE        )
76 DALI_PROPERTY_REGISTRATION( TextLabel, "alignment",         STRING,  ALIGNMENT         )
77
78 DALI_TYPE_REGISTRATION_END()
79
80 } // namespace
81
82 Toolkit::TextLabel TextLabel::New()
83 {
84   // Create the implementation, temporarily owned by this handle on stack
85   IntrusivePtr< TextLabel > impl = new TextLabel();
86
87   // Pass ownership to CustomActor handle
88   Toolkit::TextLabel handle( *impl );
89
90   // Second-phase init of the implementation
91   // This can only be done after the CustomActor connection has been made...
92   impl->Initialize();
93
94   return handle;
95 }
96
97 void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
98 {
99   Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( Dali::BaseHandle( object ) );
100
101   if( label )
102   {
103     TextLabel& impl( GetImpl( label ) );
104     switch( index )
105     {
106       case Toolkit::TextLabel::Property::RENDERING_BACKEND:
107       {
108         int backend = value.Get< int >();
109
110         if( impl.mRenderingBackend != backend )
111         {
112           impl.mRenderingBackend = backend;
113           impl.mRenderer.Reset();
114           impl.RequestTextRelayout();
115         }
116         break;
117       }
118       case Toolkit::TextLabel::Property::TEXT:
119       {
120         if( impl.mController )
121         {
122           impl.mController->SetText( value.Get< std::string >() );
123           impl.RequestTextRelayout();
124         }
125         break;
126       }
127       case Toolkit::TextLabel::Property::FONT_FAMILY:
128       {
129         if( impl.mController )
130         {
131           std::string fontFamily = value.Get< std::string >();
132
133           if( impl.mController->GetDefaultFontFamily() != fontFamily )
134           {
135             impl.mController->SetDefaultFontFamily( fontFamily );
136             impl.RequestTextRelayout();
137           }
138         }
139         break;
140       }
141       case Toolkit::TextLabel::Property::FONT_STYLE:
142       {
143         if( impl.mController )
144         {
145           std::string fontStyle = value.Get< std::string >();
146
147           if( impl.mController->GetDefaultFontStyle() != fontStyle )
148           {
149             impl.mController->SetDefaultFontStyle( fontStyle );
150             impl.RequestTextRelayout();
151           }
152         }
153         break;
154       }
155       case Toolkit::TextLabel::Property::POINT_SIZE:
156       {
157         if( impl.mController )
158         {
159           float pointSize = value.Get< float >();
160
161           if( impl.mController->GetDefaultPointSize() != pointSize /*TODO - epsilon*/ )
162           {
163             impl.mController->SetDefaultPointSize( pointSize );
164             impl.RequestTextRelayout();
165           }
166         }
167         break;
168       }
169       case Toolkit::TextLabel::Property::MULTI_LINE:
170       {
171         if( impl.mController )
172         {
173           LayoutEngine& engine = impl.mController->GetLayoutEngine();
174           LayoutEngine::Layout layout = value.Get< bool >() ? LayoutEngine::MULTI_LINE_BOX : LayoutEngine::SINGLE_LINE_BOX;
175
176           if( engine.GetLayout() != layout )
177           {
178             engine.SetLayout( layout );
179             impl.RequestTextRelayout();
180           }
181         }
182         break;
183       }
184       case Toolkit::TextLabel::Property::ALIGNMENT:
185       {
186         LayoutEngine& engine = impl.mController->GetLayoutEngine();
187         const LayoutEngine::Alignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::Alignment >( value.Get< std::string >().c_str(),
188                                                                                                                        ALIGNMENT_STRING_TABLE,
189                                                                                                                        ALIGNMENT_STRING_TABLE_COUNT );
190
191         if( engine.GetAlignment() != alignment )
192         {
193           engine.SetAlignment( alignment );
194           impl.RequestTextRelayout();
195         }
196         break;
197       }
198     }
199   }
200 }
201
202 Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index index )
203 {
204   Property::Value value;
205
206   Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( Dali::BaseHandle( object ) );
207
208   if( label )
209   {
210     TextLabel& impl( GetImpl( label ) );
211     switch( index )
212     {
213       case Toolkit::TextLabel::Property::RENDERING_BACKEND:
214       {
215         value = impl.mRenderingBackend;
216         break;
217       }
218       case Toolkit::TextLabel::Property::TEXT:
219       {
220         if( impl.mController )
221         {
222           std::string text;
223           impl.mController->GetText( text );
224           value = text;
225         }
226         break;
227       }
228       case Toolkit::TextLabel::Property::MULTI_LINE:
229       {
230         if( impl.mController )
231         {
232           value = static_cast<bool>( LayoutEngine::MULTI_LINE_BOX == impl.mController->GetLayoutEngine().GetLayout() );
233         }
234         break;
235       }
236       case Toolkit::TextLabel::Property::ALIGNMENT:
237       {
238         if( impl.mController )
239         {
240           value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::Alignment >( impl.mController->GetLayoutEngine().GetAlignment(),
241                                                                                                         ALIGNMENT_STRING_TABLE,
242                                                                                                         ALIGNMENT_STRING_TABLE_COUNT ) );
243         }
244         break;
245       }
246     }
247   }
248
249   return value;
250 }
251
252 void TextLabel::OnInitialize()
253 {
254   mController = Text::Controller::New( *this );
255 }
256
257 void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange change )
258 {
259   GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
260 }
261
262 Vector3 TextLabel::GetNaturalSize()
263 {
264   return mController->GetNaturalSize();
265 }
266
267 float TextLabel::GetHeightForWidth( float width )
268 {
269   return mController->GetHeightForWidth( width );
270 }
271
272 void TextLabel::OnRelayout( const Vector2& size, ActorSizeContainer& container )
273 {
274   if( mController->Relayout( size ) ||
275       !mRenderer )
276   {
277     if( !mRenderer )
278     {
279       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
280     }
281
282     RenderableActor renderableActor;
283     if( mRenderer )
284     {
285       renderableActor = mRenderer->Render( mController->GetView() );
286     }
287
288     if( renderableActor != mRenderableActor )
289     {
290       UnparentAndReset( mRenderableActor );
291
292       if( renderableActor )
293       {
294         Self().Add( renderableActor );
295       }
296
297       mRenderableActor = renderableActor;
298     }
299   }
300 }
301
302 void TextLabel::RequestTextRelayout()
303 {
304   RelayoutRequest();
305 }
306
307 TextLabel::TextLabel()
308 : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
309   mRenderingBackend( DEFAULT_RENDERING_BACKEND )
310 {
311 }
312
313 TextLabel::~TextLabel()
314 {
315 }
316
317 } // namespace Internal
318
319 } // namespace Toolkit
320
321 } // namespace Dali