Merge "Fix resource package install issue." into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-label-impl.cpp
1 /*
2  * Copyright (c) 2017 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/devel-api/object/property-helper-devel.h>
24 #include <dali/integration-api/debug.h>
25
26 // INTERNAL INCLUDES
27 #include <dali-toolkit/public-api/text/rendering-backend.h>
28 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
29 #include <dali-toolkit/devel-api/controls/text-controls/text-label-devel.h>
30 #include <dali-toolkit/internal/text/property-string-parser.h>
31 #include <dali-toolkit/internal/text/rendering/text-backend.h>
32 #include <dali-toolkit/internal/text/text-effects-style.h>
33 #include <dali-toolkit/internal/text/text-font-style.h>
34 #include <dali-toolkit/internal/text/text-view.h>
35 #include <dali-toolkit/internal/text/text-definitions.h>
36 #include <dali-toolkit/internal/styling/style-manager-impl.h>
37
38 using namespace Dali::Toolkit::Text;
39
40 namespace Dali
41 {
42
43 namespace Toolkit
44 {
45
46 namespace Internal
47 {
48
49 namespace
50 {
51   const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
52 }
53
54 namespace
55 {
56
57 #if defined ( DEBUG_ENABLED )
58   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
59 #endif
60
61 const Scripting::StringEnum AUTO_SCROLL_STOP_MODE_TABLE[] =
62 {
63   { "IMMEDIATE", Toolkit::DevelTextLabel::AutoScrollStopMode::IMMEDIATE },
64   { "FINISH_LOOP",  Toolkit::DevelTextLabel::AutoScrollStopMode::FINISH_LOOP  },
65 };
66 const unsigned int AUTO_SCROLL_STOP_MODE_TABLE_COUNT = sizeof( AUTO_SCROLL_STOP_MODE_TABLE ) / sizeof( AUTO_SCROLL_STOP_MODE_TABLE[0] );
67
68 const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
69 {
70   { "BEGIN",  Toolkit::Text::Layout::HORIZONTAL_ALIGN_BEGIN  },
71   { "CENTER", Toolkit::Text::Layout::HORIZONTAL_ALIGN_CENTER },
72   { "END",    Toolkit::Text::Layout::HORIZONTAL_ALIGN_END    },
73 };
74 const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
75
76 const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
77 {
78   { "TOP",    Toolkit::Text::Layout::VERTICAL_ALIGN_TOP    },
79   { "CENTER", Toolkit::Text::Layout::VERTICAL_ALIGN_CENTER },
80   { "BOTTOM", Toolkit::Text::Layout::VERTICAL_ALIGN_BOTTOM },
81 };
82 const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
83
84 const Scripting::StringEnum LINE_WRAP_MODE_STRING_TABLE[] =
85 {
86   { "WRAP_MODE_WORD",      Toolkit::Text::Layout::LineWrap::WORD  },
87   { "WRAP_MODE_CHARACTER", Toolkit::Text::Layout::LineWrap::CHARACTER }
88 };
89 const unsigned int LINE_WRAP_MODE_STRING_TABLE_COUNT = sizeof( LINE_WRAP_MODE_STRING_TABLE ) / sizeof( LINE_WRAP_MODE_STRING_TABLE[0] );
90
91 // Type registration
92 BaseHandle Create()
93 {
94   return Toolkit::TextLabel::New();
95 }
96
97 // Setup properties, signals and actions using the type-registry.
98 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextLabel, Toolkit::Control, Create );
99
100 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "renderingBackend",          INTEGER, RENDERING_BACKEND      )
101 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "text",                      STRING,  TEXT                   )
102 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontFamily",                STRING,  FONT_FAMILY            )
103 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontStyle",                 MAP,     FONT_STYLE             )
104 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "pointSize",                 FLOAT,   POINT_SIZE             )
105 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "multiLine",                 BOOLEAN, MULTI_LINE             )
106 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "horizontalAlignment",       STRING,  HORIZONTAL_ALIGNMENT   )
107 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "verticalAlignment",         STRING,  VERTICAL_ALIGNMENT     )
108 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "textColor",                 VECTOR4, TEXT_COLOR             )
109 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "shadowOffset",              VECTOR2, SHADOW_OFFSET          )
110 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "shadowColor",               VECTOR4, SHADOW_COLOR           )
111 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underlineEnabled",          BOOLEAN, UNDERLINE_ENABLED      )
112 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underlineColor",            VECTOR4, UNDERLINE_COLOR        )
113 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underlineHeight",           FLOAT,   UNDERLINE_HEIGHT       )
114 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "enableMarkup",              BOOLEAN, ENABLE_MARKUP          )
115 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "enableAutoScroll",          BOOLEAN, ENABLE_AUTO_SCROLL     )
116 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollSpeed",           INTEGER, AUTO_SCROLL_SPEED      )
117 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollLoopCount",       INTEGER, AUTO_SCROLL_LOOP_COUNT )
118 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollGap",             FLOAT,   AUTO_SCROLL_GAP        )
119 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "lineSpacing",               FLOAT,   LINE_SPACING           )
120 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underline",                 MAP,     UNDERLINE              )
121 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "shadow",                    MAP,     SHADOW                 )
122 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "emboss",                    MAP,     EMBOSS                 )
123 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "outline",                   MAP,     OUTLINE                )
124 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "pixelSize",           FLOAT,   PIXEL_SIZE             )
125 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "ellipsis",            BOOLEAN, ELLIPSIS               )
126 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollLoopDelay", FLOAT,   AUTO_SCROLL_LOOP_DELAY )
127 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollStopMode",  STRING,  AUTO_SCROLL_STOP_MODE  )
128 DALI_DEVEL_PROPERTY_REGISTRATION_READ_ONLY( Toolkit, TextLabel, "lineCount", INTEGER, LINE_COUNT             )
129 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit, TextLabel, "lineWrapMode",        STRING,  LINE_WRAP_MODE         )
130 DALI_DEVEL_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, TextLabel, "textColorAnimatable", Color::WHITE, TEXT_COLOR_ANIMATABLE )
131 DALI_DEVEL_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorRed",   TEXT_COLOR_RED,   TEXT_COLOR_ANIMATABLE, 0)
132 DALI_DEVEL_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorGreen", TEXT_COLOR_GREEN, TEXT_COLOR_ANIMATABLE, 1)
133 DALI_DEVEL_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorBlue",  TEXT_COLOR_BLUE,  TEXT_COLOR_ANIMATABLE, 2)
134 DALI_DEVEL_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, TextLabel, "textColorAlpha", TEXT_COLOR_ALPHA, TEXT_COLOR_ANIMATABLE, 3)
135 DALI_TYPE_REGISTRATION_END()
136
137 } // namespace
138
139 Toolkit::TextLabel TextLabel::New()
140 {
141   // Create the implementation, temporarily owned by this handle on stack
142   IntrusivePtr< TextLabel > impl = new TextLabel();
143
144   // Pass ownership to CustomActor handle
145   Toolkit::TextLabel handle( *impl );
146
147   // Second-phase init of the implementation
148   // This can only be done after the CustomActor connection has been made...
149   impl->Initialize();
150
151   return handle;
152 }
153
154 void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
155 {
156   Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( Dali::BaseHandle( object ) );
157
158   if( label )
159   {
160     TextLabel& impl( GetImpl( label ) );
161     switch( index )
162     {
163       case Toolkit::TextLabel::Property::RENDERING_BACKEND:
164       {
165         int backend = value.Get< int >();
166
167 #ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
168         if( Text::RENDERING_VECTOR_BASED == backend )
169         {
170           backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering
171         }
172 #endif
173         if( impl.mRenderingBackend != backend )
174         {
175           impl.mRenderingBackend = backend;
176           impl.mRenderer.Reset();
177
178           if( impl.mController )
179           {
180             // When using the vector-based rendering, the size of the GLyphs are different
181             TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
182             impl.mController->SetGlyphType( glyphType );
183           }
184         }
185         break;
186       }
187       case Toolkit::TextLabel::Property::TEXT:
188       {
189         if( impl.mController )
190         {
191           impl.mController->SetText( value.Get< std::string >() );
192         }
193         break;
194       }
195       case Toolkit::TextLabel::Property::FONT_FAMILY:
196       {
197         if( impl.mController )
198         {
199           const std::string& fontFamily = value.Get< std::string >();
200
201           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::SetProperty Property::FONT_FAMILY newFont(%s)\n", fontFamily.c_str() );
202           impl.mController->SetDefaultFontFamily( fontFamily );
203         }
204         break;
205       }
206       case Toolkit::TextLabel::Property::FONT_STYLE:
207       {
208         SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
209         break;
210       }
211       case Toolkit::TextLabel::Property::POINT_SIZE:
212       {
213         if( impl.mController )
214         {
215           const float pointSize = value.Get< float >();
216
217           if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE ), pointSize ) )
218           {
219             impl.mController->SetDefaultFontSize( pointSize, Text::Controller::POINT_SIZE );
220           }
221         }
222         break;
223       }
224       case Toolkit::TextLabel::Property::MULTI_LINE:
225       {
226         if( impl.mController )
227         {
228           impl.mController->SetMultiLineEnabled( value.Get< bool >() );
229         }
230         break;
231       }
232       case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
233       {
234         if( impl.mController )
235         {
236           Layout::HorizontalAlignment alignment( Layout::HORIZONTAL_ALIGN_BEGIN );
237           if( Scripting::GetEnumeration< Toolkit::Text::Layout::HorizontalAlignment >( value.Get< std::string >().c_str(),
238                                                                                        HORIZONTAL_ALIGNMENT_STRING_TABLE,
239                                                                                        HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
240                                                                                        alignment ) )
241           {
242             impl.mController->SetHorizontalAlignment( alignment );
243           }
244         }
245         break;
246       }
247       case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
248       {
249         if( impl.mController )
250         {
251           Layout::VerticalAlignment alignment( Layout::VERTICAL_ALIGN_BOTTOM );
252           if( Scripting::GetEnumeration< Toolkit::Text::Layout::VerticalAlignment >( value.Get< std::string >().c_str(),
253                                                                                      VERTICAL_ALIGNMENT_STRING_TABLE,
254                                                                                      VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
255                                                                                      alignment ) )
256           {
257             impl.mController->SetVerticalAlignment( alignment );
258           }
259         }
260         break;
261       }
262
263       case Toolkit::TextLabel::Property::TEXT_COLOR:
264       {
265         SetProperty( object, DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE, value );
266         break;
267       }
268
269       case Toolkit::TextLabel::Property::SHADOW_OFFSET:
270       {
271         if( impl.mController )
272         {
273           const Vector2& shadowOffset = value.Get< Vector2 >();
274           if ( impl.mController->GetShadowOffset() != shadowOffset )
275           {
276             impl.mController->SetShadowOffset( shadowOffset );
277             impl.mRenderer.Reset();
278           }
279         }
280         break;
281       }
282       case Toolkit::TextLabel::Property::SHADOW_COLOR:
283       {
284         if( impl.mController )
285         {
286           const Vector4& shadowColor = value.Get< Vector4 >();
287           if ( impl.mController->GetShadowColor() != shadowColor )
288           {
289             impl.mController->SetShadowColor( shadowColor );
290             impl.mRenderer.Reset();
291           }
292         }
293         break;
294       }
295       case Toolkit::TextLabel::Property::UNDERLINE_COLOR:
296       {
297         if( impl.mController )
298         {
299           const Vector4& color = value.Get< Vector4 >();
300           if ( impl.mController->GetUnderlineColor() != color )
301           {
302             impl.mController->SetUnderlineColor( color );
303             impl.mRenderer.Reset();
304           }
305         }
306         break;
307       }
308       case Toolkit::TextLabel::Property::UNDERLINE_ENABLED:
309       {
310         if( impl.mController )
311         {
312           const bool enabled = value.Get< bool >();
313           if ( impl.mController->IsUnderlineEnabled() != enabled )
314           {
315             impl.mController->SetUnderlineEnabled( enabled );
316             impl.mRenderer.Reset();
317           }
318         }
319         break;
320       }
321
322       case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT:
323       {
324         if( impl.mController )
325         {
326           float height = value.Get< float >();
327           if( fabsf( impl.mController->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 )
328           {
329             impl.mController->SetUnderlineHeight( height );
330             impl.mRenderer.Reset();
331           }
332         }
333         break;
334       }
335       case Toolkit::TextLabel::Property::ENABLE_MARKUP:
336       {
337         if( impl.mController )
338         {
339           const bool enableMarkup = value.Get<bool>();
340           impl.mController->SetMarkupProcessorEnabled( enableMarkup );
341         }
342         break;
343       }
344       case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL:
345       {
346         if( impl.mController )
347         {
348           const bool enableAutoScroll = value.Get<bool>();
349           // If request to auto scroll is the same as current state then do nothing.
350           if ( enableAutoScroll != impl.mController->IsAutoScrollEnabled() )
351           {
352              // If request is disable (false) and auto scrolling is enabled then need to stop it
353              if ( enableAutoScroll == false )
354              {
355                if( impl.mTextScroller )
356                {
357                  impl.mTextScroller->StopScrolling();
358                }
359              }
360              // If request is enable (true) then start autoscroll as not already running
361              else
362              {
363                impl.mController->SetTextElideEnabled( false );
364                impl.mController->SetAutoScrollEnabled( enableAutoScroll );
365              }
366           }
367         }
368         break;
369       }
370       case Toolkit::DevelTextLabel::Property::AUTO_SCROLL_STOP_MODE:
371       {
372         if( !impl.mTextScroller )
373         {
374           impl.mTextScroller = Text::TextScroller::New( impl );
375         }
376         DevelTextLabel::AutoScrollStopMode::Type stopMode = impl.mTextScroller->GetStopMode();
377         if( Scripting::GetEnumerationProperty< Toolkit::DevelTextLabel::AutoScrollStopMode::Type >( value,
378                                                                                                     AUTO_SCROLL_STOP_MODE_TABLE,
379                                                                                                     AUTO_SCROLL_STOP_MODE_TABLE_COUNT,
380                                                                                                     stopMode ) )
381         {
382             impl.mTextScroller->SetStopMode( stopMode );
383         }
384         break;
385       }
386       case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED:
387       {
388         if( !impl.mTextScroller )
389         {
390           impl.mTextScroller = Text::TextScroller::New( impl );
391         }
392         impl.mTextScroller->SetSpeed( value.Get<int>() );
393         break;
394       }
395       case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT:
396       {
397         if( !impl.mTextScroller )
398         {
399           impl.mTextScroller = Text::TextScroller::New( impl );
400         }
401         impl.mTextScroller->SetLoopCount( value.Get<int>() );
402         break;
403       }
404       case Toolkit::DevelTextLabel::Property::AUTO_SCROLL_LOOP_DELAY:
405       {
406          if( !impl.mTextScroller )
407         {
408           impl.mTextScroller = Text::TextScroller::New( impl );
409         }
410         impl.mTextScroller->SetLoopDelay( value.Get<float>() );
411         break;
412       }
413       case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP:
414       {
415         if( !impl.mTextScroller )
416         {
417           impl.mTextScroller = Text::TextScroller::New( impl );
418         }
419         impl.mTextScroller->SetGap( value.Get<float>() );
420         break;
421       }
422       case Toolkit::TextLabel::Property::LINE_SPACING:
423       {
424         if( impl.mController )
425         {
426           const float lineSpacing = value.Get<float>();
427           impl.mController->SetDefaultLineSpacing( lineSpacing );
428           impl.mRenderer.Reset();
429         }
430         break;
431       }
432       case Toolkit::TextLabel::Property::UNDERLINE:
433       {
434         const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
435         if( update )
436         {
437           impl.mRenderer.Reset();
438         }
439         break;
440       }
441       case Toolkit::TextLabel::Property::SHADOW:
442       {
443         const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
444         if( update )
445         {
446           impl.mRenderer.Reset();
447         }
448         break;
449       }
450       case Toolkit::TextLabel::Property::EMBOSS:
451       {
452         const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
453         if( update )
454         {
455           impl.mRenderer.Reset();
456         }
457         break;
458       }
459       case Toolkit::TextLabel::Property::OUTLINE:
460       {
461         const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
462         if( update )
463         {
464           impl.mRenderer.Reset();
465         }
466         break;
467       }
468       case Toolkit::DevelTextLabel::Property::PIXEL_SIZE:
469       {
470         if( impl.mController )
471         {
472           const float pixelSize = value.Get< float >();
473           DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize );
474
475           if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE ), pixelSize ) )
476           {
477             impl.mController->SetDefaultFontSize( pixelSize, Text::Controller::PIXEL_SIZE );
478           }
479         }
480         break;
481       }
482       case Toolkit::DevelTextLabel::Property::ELLIPSIS:
483       {
484         if( impl.mController )
485         {
486           const bool ellipsis = value.Get<bool>();
487           DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis );
488
489           impl.mController->SetTextElideEnabled( ellipsis );
490         }
491         break;
492       }
493       case Toolkit::DevelTextLabel::Property::LINE_WRAP_MODE:
494       {
495         const std::string& wrapModeStr = value.Get< std::string >();
496         DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p LINE_WRAP_MODE %s\n", impl.mController.Get(), wrapModeStr.c_str() );
497
498         Layout::LineWrap::Mode lineWrapMode( Layout::LineWrap::WORD );
499         if( Scripting::GetEnumeration< Layout::LineWrap::Mode >( wrapModeStr.c_str(),
500                                                                  LINE_WRAP_MODE_STRING_TABLE,
501                                                                  LINE_WRAP_MODE_STRING_TABLE_COUNT,
502                                                                  lineWrapMode ) )
503         {
504           impl.mController->SetLineWrapMode( lineWrapMode );
505         }
506         break;
507       }
508     }
509   }
510 }
511
512 Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index index )
513 {
514   Property::Value value;
515
516   Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( Dali::BaseHandle( object ) );
517
518   if( label )
519   {
520     TextLabel& impl( GetImpl( label ) );
521     switch( index )
522     {
523       case Toolkit::TextLabel::Property::RENDERING_BACKEND:
524       {
525         value = impl.mRenderingBackend;
526         break;
527       }
528       case Toolkit::TextLabel::Property::TEXT:
529       {
530         if( impl.mController )
531         {
532           std::string text;
533           impl.mController->GetText( text );
534           value = text;
535         }
536         break;
537       }
538       case Toolkit::TextLabel::Property::FONT_FAMILY:
539       {
540         if( impl.mController )
541         {
542           value = impl.mController->GetDefaultFontFamily();
543         }
544         break;
545       }
546       case Toolkit::TextLabel::Property::FONT_STYLE:
547       {
548         GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
549         break;
550       }
551       case Toolkit::TextLabel::Property::POINT_SIZE:
552       {
553         if( impl.mController )
554         {
555           value = impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE );
556         }
557         break;
558       }
559       case Toolkit::TextLabel::Property::MULTI_LINE:
560       {
561         if( impl.mController )
562         {
563           value = impl.mController->IsMultiLineEnabled();
564         }
565         break;
566       }
567       case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
568       {
569         if( impl.mController )
570         {
571           const char* name = Scripting::GetEnumerationName< Toolkit::Text::Layout::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
572                                                                                                           HORIZONTAL_ALIGNMENT_STRING_TABLE,
573                                                                                                           HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
574           if( name )
575           {
576             value = std::string( name );
577           }
578         }
579         break;
580       }
581       case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
582       {
583         if( impl.mController )
584         {
585           const char* name = Scripting::GetEnumerationName< Toolkit::Text::Layout::VerticalAlignment >( impl.mController->GetVerticalAlignment(),
586                                                                                                         VERTICAL_ALIGNMENT_STRING_TABLE,
587                                                                                                         VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
588           if( name )
589           {
590             value = std::string( name );
591           }
592         }
593         break;
594       }
595       case Toolkit::TextLabel::Property::TEXT_COLOR:
596       {
597         if( impl.mController )
598         {
599           value = impl.mController->GetDefaultColor();
600         }
601         break;
602       }
603       case Toolkit::TextLabel::Property::SHADOW_OFFSET:
604       {
605         if ( impl.mController )
606         {
607           value = impl.mController->GetShadowOffset();
608         }
609         break;
610       }
611       case Toolkit::TextLabel::Property::SHADOW_COLOR:
612       {
613         if ( impl.mController )
614         {
615           value = impl.mController->GetShadowColor();
616         }
617         break;
618       }
619       case Toolkit::TextLabel::Property::UNDERLINE_COLOR:
620       {
621         if ( impl.mController )
622         {
623           value = impl.mController->GetUnderlineColor();
624         }
625         break;
626       }
627       case Toolkit::TextLabel::Property::UNDERLINE_ENABLED:
628       {
629         if ( impl.mController )
630         {
631           value = impl.mController->IsUnderlineEnabled();
632         }
633         break;
634       }
635       case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT:
636       {
637         if ( impl.mController )
638         {
639           value = impl.mController->GetUnderlineHeight();
640         }
641         break;
642       }
643       case Toolkit::TextLabel::Property::ENABLE_MARKUP:
644       {
645         if( impl.mController )
646         {
647           value = impl.mController->IsMarkupProcessorEnabled();
648         }
649         break;
650       }
651       case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL:
652       {
653         if( impl.mController )
654         {
655           value = impl.mController->IsAutoScrollEnabled();
656         }
657         break;
658       }
659       case Toolkit::DevelTextLabel::Property::AUTO_SCROLL_STOP_MODE:
660       {
661         if( impl.mTextScroller )
662         {
663           const char* mode = Scripting::GetEnumerationName< Toolkit::DevelTextLabel::AutoScrollStopMode::Type >( impl.mTextScroller->GetStopMode(),
664                                                                                                                  AUTO_SCROLL_STOP_MODE_TABLE,
665                                                                                                                  AUTO_SCROLL_STOP_MODE_TABLE_COUNT );
666           if( mode )
667           {
668             value = std::string( mode );
669           }
670         }
671         break;
672       }
673       case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED:
674       {
675         TextLabel& impl( GetImpl( label ) );
676         if ( impl.mTextScroller )
677         {
678           value = impl.mTextScroller->GetSpeed();
679         }
680         break;
681       }
682       case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT:
683       {
684         if( impl.mController )
685         {
686           TextLabel& impl( GetImpl( label ) );
687           if ( impl.mTextScroller )
688           {
689             value = impl.mTextScroller->GetLoopCount();
690           }
691         }
692         break;
693       }
694       case Toolkit::DevelTextLabel::Property::AUTO_SCROLL_LOOP_DELAY:
695       {
696         if( impl.mController )
697         {
698           TextLabel& impl( GetImpl( label ) );
699           if ( impl.mTextScroller )
700           {
701             value = impl.mTextScroller->GetLoopDelay();
702           }
703         }
704         break;
705       }
706       case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP:
707       {
708         TextLabel& impl( GetImpl( label ) );
709         if ( impl.mTextScroller )
710         {
711           value = impl.mTextScroller->GetGap();
712         }
713         break;
714       }
715       case Toolkit::TextLabel::Property::LINE_SPACING:
716       {
717         if( impl.mController )
718         {
719           value = impl.mController->GetDefaultLineSpacing();
720         }
721         break;
722       }
723       case Toolkit::TextLabel::Property::UNDERLINE:
724       {
725         GetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
726         break;
727       }
728       case Toolkit::TextLabel::Property::SHADOW:
729       {
730         GetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
731         break;
732       }
733       case Toolkit::TextLabel::Property::EMBOSS:
734       {
735         GetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
736         break;
737       }
738       case Toolkit::TextLabel::Property::OUTLINE:
739       {
740         GetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
741         break;
742       }
743       case Toolkit::DevelTextLabel::Property::PIXEL_SIZE:
744       {
745         if( impl.mController )
746         {
747           value = impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE );
748         }
749         break;
750       }
751       case Toolkit::DevelTextLabel::Property::ELLIPSIS:
752       {
753         if( impl.mController )
754         {
755           value = impl.mController->IsTextElideEnabled();
756         }
757         break;
758       }
759       case Toolkit::DevelTextLabel::Property::LINE_WRAP_MODE:
760       {
761         if( impl.mController )
762         {
763           value = impl.mController->GetLineWrapMode();
764         }
765         break;
766       }
767       case Toolkit::DevelTextLabel::Property::LINE_COUNT:
768       {
769         if( impl.mController )
770         {
771           float width = label.GetProperty( Actor::Property::SIZE_WIDTH ).Get<float>();
772           value = impl.mController->GetLineCount( width );
773         }
774         break;
775       }
776     }
777   }
778
779   return value;
780 }
781
782 void TextLabel::OnInitialize()
783 {
784   Actor self = Self();
785
786   mController = Text::Controller::New( this );
787
788   // When using the vector-based rendering, the size of the GLyphs are different
789   TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
790   mController->SetGlyphType( glyphType );
791
792   // Use height-for-width negotiation by default
793   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
794   self.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
795
796   // Enable the text ellipsis.
797   mController->SetTextElideEnabled( true );   // If false then text larger than control will overflow
798
799   Layout::Engine& engine = mController->GetLayoutEngine();
800   engine.SetCursorWidth( 0u ); // Do not layout space for the cursor.
801
802   self.OnStageSignal().Connect( this, &TextLabel::OnStageConnect );
803 }
804
805 void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
806 {
807   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::OnStyleChange\n");
808
809   switch ( change )
810   {
811     case StyleChange::DEFAULT_FONT_CHANGE:
812     {
813       // Property system did not set the font so should update it.
814       const std::string& newFont = GetImpl( styleManager ).GetDefaultFontFamily();
815       DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnStyleChange StyleChange::DEFAULT_FONT_CHANGE newFont(%s)\n", newFont.c_str() );
816       mController->UpdateAfterFontChange( newFont );
817       RelayoutRequest();
818       break;
819     }
820     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
821     {
822       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
823       RelayoutRequest();
824       break;
825     }
826     case StyleChange::THEME_CHANGE:
827     {
828       // Nothing to do, let control base class handle this
829       break;
830     }
831   }
832
833   // Up call to Control
834   Control::OnStyleChange( styleManager, change );
835 }
836
837 Vector3 TextLabel::GetNaturalSize()
838 {
839   return mController->GetNaturalSize();
840 }
841
842 float TextLabel::GetHeightForWidth( float width )
843 {
844   Padding padding;
845   Self().GetPadding( padding );
846   return mController->GetHeightForWidth( width ) + padding.top + padding.bottom;
847 }
848
849 void TextLabel::OnPropertySet( Property::Index index, Property::Value propertyValue )
850 {
851   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::OnPropertySet index[%d]\n", index );
852
853   switch ( index )
854   {
855     case Toolkit::TextLabel::Property::TEXT_COLOR:
856     case Toolkit::DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE:
857     {
858       const Vector4& textColor = propertyValue.Get< Vector4 >();
859       if( mController->GetDefaultColor() != textColor )
860       {
861          mController->SetDefaultColor( textColor );
862          mRenderer.Reset();
863       }
864       break;
865     }
866     default:
867     {
868       Control::OnPropertySet( index, propertyValue ); // up call to control for non-handled properties
869       break;
870     }
871   }
872 }
873
874 void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container )
875 {
876   DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnRelayout\n" );
877
878   Padding padding;
879   Self().GetPadding( padding );
880   Vector2 contentSize( size.x - ( padding.left + padding.right ), size.y - ( padding.top + padding.bottom ) );
881
882
883   const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize );
884
885   if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) ||
886       !mRenderer )
887   {
888     if( !mRenderer )
889     {
890       mRenderer = Text::Backend::Get().NewRenderer( mRenderingBackend );
891     }
892     RenderText();
893   }
894 }
895
896 void TextLabel::RequestTextRelayout()
897 {
898   RelayoutRequest();
899 }
900
901 void TextLabel::RenderText()
902 {
903   DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::RenderText IsAutoScrollEnabled[%s] [%p]\n", ( mController->IsAutoScrollEnabled())?"true":"false", this );
904
905   Actor self = Self();
906   Actor renderableActor;
907
908   float alignmentOffset = 0.f;
909   if( mRenderer )
910   {
911
912     Dali::Toolkit::TextLabel handle = Dali::Toolkit::TextLabel( GetOwner() );
913
914     renderableActor = mRenderer->Render( mController->GetView(),
915                                          handle,
916                                          Toolkit::DevelTextLabel::Property::TEXT_COLOR_ANIMATABLE,
917                                          alignmentOffset,
918                                          DepthIndex::CONTENT );
919   }
920
921   if( renderableActor != mRenderableActor )
922   {
923     UnparentAndReset( mRenderableActor );
924
925     if( renderableActor )
926     {
927       const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition();
928       Padding padding;
929       self.GetPadding( padding );
930       renderableActor.SetPosition( scrollOffset.x + alignmentOffset + padding.left, scrollOffset.y + padding.top );
931
932       self.Add( renderableActor );
933     }
934     mRenderableActor = renderableActor;
935
936     if ( mController->IsAutoScrollEnabled() )
937     {
938       SetUpAutoScrolling();
939     }
940   }
941 }
942
943 void TextLabel::SetUpAutoScrolling()
944 {
945   const Size& controlSize = mController->GetView().GetControlSize();
946   const Size offScreenSize = GetNaturalSize().GetVectorXY(); // As relayout of text may not be done at this point natural size is used to get size. Single line scrolling only.
947   const float alignmentOffset = mController->GetAutoScrollLineAlignment();
948   const Text::CharacterDirection direction = mController->GetAutoScrollDirection();
949
950   DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling alignmentOffset[%f] offScreenSize[%f,%f] controlSize[%f,%f]\n",
951                  alignmentOffset, offScreenSize.x,offScreenSize.y , controlSize.x,controlSize.y );
952
953   if ( !mTextScroller )
954   {
955     DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling Creating default TextScoller\n" );
956
957     // If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults
958     mTextScroller = Text::TextScroller::New( *this );
959   }
960   mTextScroller->SetParameters( mRenderableActor, controlSize, offScreenSize, direction, alignmentOffset, mController->GetHorizontalAlignment() );
961
962   Actor self = Self();
963   self.Add( mTextScroller->GetScrollingText() );
964   self.Add( mTextScroller->GetSourceCamera() );
965 }
966
967 void TextLabel::OnStageConnect( Dali::Actor actor )
968 {
969   if ( mHasBeenStaged )
970   {
971     RenderText();
972   }
973   else
974   {
975     mHasBeenStaged = true;
976   }
977 }
978
979 void TextLabel::ScrollingFinished()
980 {
981   // Pure Virtual from TextScroller Interface
982   DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::ScrollingFinished\n");
983   mController->SetAutoScrollEnabled( false );
984   mController->SetTextElideEnabled( true );
985   RequestTextRelayout();
986 }
987
988 TextLabel::TextLabel()
989 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
990   mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
991   mHasBeenStaged( false )
992 {
993 }
994
995 TextLabel::~TextLabel()
996 {
997 }
998
999 } // namespace Internal
1000
1001 } // namespace Toolkit
1002
1003 } // namespace Dali