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