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