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