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