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