1d6af0fd3b0c18a660de944c94885a31e09d6607
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-label-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-label-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/object/type-registry-helper.h>
23 #include <dali/integration-api/debug.h>
24
25 // INTERNAL INCLUDES
26 #include <dali-toolkit/public-api/text/rendering-backend.h>
27 #include <dali-toolkit/public-api/visuals/text-visual-properties.h>
28 #include <dali-toolkit/devel-api/visual-factory/devel-visual-properties.h>
29 #include <dali-toolkit/internal/text/text-effects-style.h>
30 #include <dali-toolkit/internal/styling/style-manager-impl.h>
31
32 using Dali::Toolkit::Text::LayoutEngine;
33
34 namespace Dali
35 {
36
37 namespace Toolkit
38 {
39
40 namespace Internal
41 {
42
43 namespace
44 {
45   const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
46 }
47
48 namespace
49 {
50
51 #if defined ( DEBUG_ENABLED )
52   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
53 #endif
54
55 // Type registration
56 BaseHandle Create()
57 {
58   return Toolkit::TextLabel::New();
59 }
60
61 // Setup properties, signals and actions using the type-registry.
62 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextLabel, Toolkit::Control, Create );
63
64 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "renderingBackend",     INTEGER, RENDERING_BACKEND      )
65 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "text",                 STRING,  TEXT                   )
66 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontFamily",           STRING,  FONT_FAMILY            )
67 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontStyle",            MAP,     FONT_STYLE             )
68 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "pointSize",            FLOAT,   POINT_SIZE             )
69 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "multiLine",            BOOLEAN, MULTI_LINE             )
70 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "horizontalAlignment",  STRING,  HORIZONTAL_ALIGNMENT   )
71 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "verticalAlignment",    STRING,  VERTICAL_ALIGNMENT     )
72 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "textColor",            VECTOR4, TEXT_COLOR             )
73 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "shadowOffset",         VECTOR2, SHADOW_OFFSET          )
74 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "shadowColor",          VECTOR4, SHADOW_COLOR           )
75 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underlineEnabled",     BOOLEAN, UNDERLINE_ENABLED      )
76 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underlineColor",       VECTOR4, UNDERLINE_COLOR        )
77 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underlineHeight",      FLOAT,   UNDERLINE_HEIGHT       )
78 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "enableMarkup",         BOOLEAN, ENABLE_MARKUP          )
79 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "enableAutoScroll",     BOOLEAN, ENABLE_AUTO_SCROLL     )
80 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollSpeed",      INTEGER, AUTO_SCROLL_SPEED      )
81 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollLoopCount",  INTEGER, AUTO_SCROLL_LOOP_COUNT )
82 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollGap",        FLOAT,   AUTO_SCROLL_GAP        )
83 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "lineSpacing",          FLOAT,   LINE_SPACING           )
84 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underline",            MAP,     UNDERLINE              )
85 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "shadow",               MAP,     SHADOW                 )
86 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "emboss",               MAP,     EMBOSS                 )
87 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "outline",              MAP,     OUTLINE                )
88
89 DALI_TYPE_REGISTRATION_END()
90
91 const int TEXT_VISUAL_PROPERTY_TABLE[] = {
92   Dali::Toolkit::TextVisual::Property::RENDERING_BACKEND,
93   Dali::Toolkit::TextVisual::Property::TEXT,
94   Dali::Toolkit::TextVisual::Property::FONT_FAMILY,
95   Dali::Toolkit::TextVisual::Property::FONT_STYLE,
96   Dali::Toolkit::TextVisual::Property::POINT_SIZE,
97   Dali::Toolkit::TextVisual::Property::MULTI_LINE,
98   Dali::Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT,
99   Dali::Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT,
100   Dali::Toolkit::TextVisual::Property::TEXT_COLOR,
101   Dali::Toolkit::TextVisual::Property::SHADOW,
102   Dali::Toolkit::TextVisual::Property::SHADOW,
103   Dali::Toolkit::TextVisual::Property::UNDERLINE,
104   Dali::Toolkit::TextVisual::Property::UNDERLINE,
105   Dali::Toolkit::TextVisual::Property::UNDERLINE,
106   Dali::Toolkit::TextVisual::Property::ENABLE_MARKUP,
107   Dali::Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL,
108   Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED,
109   Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT,
110   Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_GAP,
111   Dali::Toolkit::TextVisual::Property::LINE_SPACING,
112   Dali::Toolkit::TextVisual::Property::UNDERLINE,
113   Dali::Toolkit::TextVisual::Property::SHADOW,
114   Dali::Toolkit::TextVisual::Property::EMBOSS,
115   Dali::Toolkit::TextVisual::Property::OUTLINE,
116   Dali::Toolkit::TextVisual::Property::BATCHING_ENABLED
117 };
118
119 } // namespace
120
121 Toolkit::TextLabel TextLabel::New()
122 {
123   // Create the implementation, temporarily owned by this handle on stack
124   IntrusivePtr< TextLabel > impl = new TextLabel();
125
126   // Pass ownership to CustomActor handle
127   Toolkit::TextLabel handle( *impl );
128
129   // Second-phase init of the implementation
130   // This can only be done after the CustomActor connection has been made...
131   impl->Initialize();
132
133   return handle;
134 }
135
136 void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
137 {
138   Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( Dali::BaseHandle( object ) );
139
140   if( label )
141   {
142     TextLabel& impl = GetImpl( label );
143
144     // Sets the property to the to the text visual.
145     impl.mVisual.SetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX], value );
146   }
147 }
148
149 Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index index )
150 {
151   Property::Value value;
152
153   Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( Dali::BaseHandle( object ) );
154
155   if( label )
156   {
157     TextLabel& impl = GetImpl( label );
158
159     if( ( Toolkit::TextLabel::Property::SHADOW_OFFSET == index ) ||
160         ( Toolkit::TextLabel::Property::SHADOW_COLOR == index ) ||
161         ( Toolkit::TextLabel::Property::UNDERLINE_ENABLED == index ) ||
162         ( Toolkit::TextLabel::Property::UNDERLINE_COLOR == index ) ||
163         ( Toolkit::TextLabel::Property::UNDERLINE_HEIGHT == index ) )
164     {
165       // TODO : Branch to be removed when the deprecated properties are finally removed.
166       value = impl.mVisual.GetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX] );
167
168       switch( index )
169       {
170         case Toolkit::TextLabel::Property::SHADOW_OFFSET: // Converts the deprecated property to the new one.
171         {
172           bool colorDefined = false;
173           Vector4 color;
174           bool offsetDefined = false;
175           Vector2 offset;
176           const bool empty = Text::ParseShadowProperties( value.Get<Property::Map>(),
177                                                           colorDefined,
178                                                           color,
179                                                           offsetDefined,
180                                                           offset );
181
182           if( !empty )
183           {
184             value = offset;
185           }
186           break;
187         }
188         case Toolkit::TextLabel::Property::SHADOW_COLOR: // Converts the deprecated property to the new one.
189         {
190           bool colorDefined = false;
191           Vector4 color;
192           bool offsetDefined = false;
193           Vector2 offset;
194           const bool empty = Text::ParseShadowProperties( value.Get<Property::Map>(),
195                                                           colorDefined,
196                                                           color,
197                                                           offsetDefined,
198                                                           offset );
199
200           if( !empty )
201           {
202             value = color;
203           }
204           break;
205         }
206         case Toolkit::TextLabel::Property::UNDERLINE_ENABLED: // Converts the deprecated property to the new one.
207         {
208           bool enabled = false;
209           bool colorDefined = false;
210           Vector4 color;
211           bool heightDefined = false;
212           float height = 0.f;
213           const bool empty = Text::ParseUnderlineProperties( value.Get<Property::Map>(),
214                                                              enabled,
215                                                              colorDefined,
216                                                              color,
217                                                              heightDefined,
218                                                              height );
219
220           if( !empty )
221           {
222             value = enabled;
223           }
224           break;
225         }
226         case Toolkit::TextLabel::Property::UNDERLINE_COLOR: // Converts the deprecated property to the new one.
227         {
228           bool enabled = false;
229           bool colorDefined = false;
230           Vector4 color;
231           bool heightDefined = false;
232           float height = 0.f;
233           const bool empty = Text::ParseUnderlineProperties( value.Get<Property::Map>(),
234                                                              enabled,
235                                                              colorDefined,
236                                                              color,
237                                                              heightDefined,
238                                                              height );
239
240           if( !empty && colorDefined )
241           {
242             value = color;
243           }
244           break;
245         }
246         case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT: // Converts the deprecated property to the new one.
247         {
248           bool enabled = false;
249           bool colorDefined = false;
250           Vector4 color;
251           bool heightDefined = false;
252           float height = 0.f;
253           const bool empty = Text::ParseUnderlineProperties( value.Get<Property::Map>(),
254                                                              enabled,
255                                                              colorDefined,
256                                                              color,
257                                                              heightDefined,
258                                                              height );
259
260           if( !empty && heightDefined )
261           {
262             value = height;
263           }
264           break;
265         }
266         default:
267         {
268           // Nothing to do.
269           break;
270         }
271       }
272     }
273     else
274     {
275       // Retrieves the property from the text visual.
276       value = impl.mVisual.GetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX] );
277     }
278   }
279
280   return value;
281 }
282
283 void TextLabel::OnInitialize()
284 {
285   Actor self = Self();
286
287   // Creates the text's visual.
288   Property::Map visualMap;
289   visualMap[Toolkit::VisualProperty::TYPE] = Toolkit::Visual::TEXT;
290   visualMap[Toolkit::TextVisual::Property::RENDERING_BACKEND] = static_cast<int>( DEFAULT_RENDERING_BACKEND );
291
292   mVisual =  Toolkit::VisualFactory::Get().CreateVisual( visualMap );
293   RegisterVisual( Toolkit::TextLabel::Property::TEXT, mVisual );
294
295   Internal::Visual::Base& visualBase = Toolkit::GetImplementation( mVisual );
296   TextVisual* textVisual = static_cast<TextVisual*>( &visualBase );
297
298   // Sets the text's control interface.
299   textVisual->SetTextControlInterface( this );
300
301   // Use height-for-width negotiation by default
302   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
303   self.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
304 }
305
306 void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
307 {
308   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::OnStyleChange\n");
309
310   switch ( change )
311   {
312     case StyleChange::DEFAULT_FONT_CHANGE:
313     {
314       // Property system did not set the font so should update it.
315       const std::string& newFont = GetImpl( styleManager ).GetDefaultFontFamily();
316       DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnStyleChange StyleChange::DEFAULT_FONT_CHANGE newFont(%s)\n", newFont.c_str() );
317
318       const std::string fontString = "{\"family\":\"" + newFont + "\",\"type\":\"system\"}";
319       mVisual.SetProperty( Toolkit::TextVisual::Property::FONT_FAMILY, fontString );
320       break;
321     }
322     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
323     {
324       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
325       break;
326     }
327     case StyleChange::THEME_CHANGE:
328     {
329       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
330       break;
331     }
332   }
333 }
334
335 Vector3 TextLabel::GetNaturalSize()
336 {
337   Vector2 naturalSize;
338   mVisual.GetNaturalSize( naturalSize );
339
340   return Vector3( naturalSize );
341 }
342
343 float TextLabel::GetHeightForWidth( float width )
344 {
345   return mVisual.GetHeightForWidth( width );
346 }
347
348 void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container )
349 {
350   DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnRelayout\n" );
351
352   mVisual.SetSize( size );
353 }
354
355 void TextLabel::RequestTextRelayout()
356 {
357   RelayoutRequest();
358 }
359
360 void TextLabel::OnStageConnection( int depth )
361 {
362   // Call the Control::OnStageConnection() to set the depth of the background.
363   Control::OnStageConnection( depth );
364
365   // The depth of the text renderer is set by the text-visual called from OnRelayout().
366 }
367
368 TextLabel::TextLabel()
369 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) )
370 {
371 }
372
373 TextLabel::~TextLabel()
374 {
375 }
376
377 } // namespace Internal
378
379 } // namespace Toolkit
380
381 } // namespace Dali