2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-toolkit/internal/controls/text-controls/text-label-impl.h>
22 #include <dali/public-api/object/type-registry.h>
23 #include <dali/devel-api/object/type-registry-helper.h>
24 #include <dali/devel-api/scripting/scripting.h>
25 #include <dali/integration-api/debug.h>
28 #include <dali-toolkit/public-api/text/rendering-backend.h>
29 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
30 #include <dali-toolkit/internal/text/rendering/text-backend.h>
31 #include <dali-toolkit/internal/text/text-view.h>
32 #include <dali-toolkit/internal/styling/style-manager-impl.h>
34 using Dali::Toolkit::Text::LayoutEngine;
35 using Dali::Toolkit::Text::Backend;
48 const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
54 #if defined(DEBUG_ENABLED)
55 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
58 const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
60 { "BEGIN", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN },
61 { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
62 { "END", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END },
64 const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
66 const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
68 { "TOP", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP },
69 { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
70 { "BOTTOM", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_BOTTOM },
72 const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
77 return Toolkit::TextLabel::New();
80 // Setup properties, signals and actions using the type-registry.
81 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextLabel, Toolkit::Control, Create );
83 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "rendering-backend", INTEGER, RENDERING_BACKEND )
84 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "text", STRING, TEXT )
85 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "font-family", STRING, FONT_FAMILY )
86 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "font-style", STRING, FONT_STYLE )
87 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "point-size", FLOAT, POINT_SIZE )
88 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "multi-line", BOOLEAN, MULTI_LINE )
89 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "horizontal-alignment", STRING, HORIZONTAL_ALIGNMENT )
90 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "vertical-alignment", STRING, VERTICAL_ALIGNMENT )
91 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "text-color", VECTOR4, TEXT_COLOR )
92 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "shadow-offset", VECTOR2, SHADOW_OFFSET )
93 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "shadow-color", VECTOR4, SHADOW_COLOR )
94 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underline-enabled", BOOLEAN, UNDERLINE_ENABLED )
95 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underline-color", VECTOR4, UNDERLINE_COLOR )
96 DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underline-height", FLOAT, UNDERLINE_HEIGHT )
98 DALI_TYPE_REGISTRATION_END()
102 Toolkit::TextLabel TextLabel::New()
104 // Create the implementation, temporarily owned by this handle on stack
105 IntrusivePtr< TextLabel > impl = new TextLabel();
107 // Pass ownership to CustomActor handle
108 Toolkit::TextLabel handle( *impl );
110 // Second-phase init of the implementation
111 // This can only be done after the CustomActor connection has been made...
117 void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
119 Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( Dali::BaseHandle( object ) );
123 TextLabel& impl( GetImpl( label ) );
126 case Toolkit::TextLabel::Property::RENDERING_BACKEND:
128 const int backend = value.Get< int >();
130 if( impl.mRenderingBackend != backend )
132 impl.mRenderingBackend = backend;
133 impl.mRenderer.Reset();
134 impl.RequestTextRelayout();
138 case Toolkit::TextLabel::Property::TEXT:
140 if( impl.mController )
142 impl.mController->SetText( value.Get< std::string >() );
146 case Toolkit::TextLabel::Property::FONT_FAMILY:
148 if( impl.mController )
150 const std::string fontFamily = value.Get< std::string >();
152 if( impl.mController->GetDefaultFontFamily() != fontFamily )
154 impl.mController->SetDefaultFontFamily( fontFamily );
159 case Toolkit::TextLabel::Property::FONT_STYLE:
161 if( impl.mController )
163 const std::string fontStyle = value.Get< std::string >();
165 if( impl.mController->GetDefaultFontStyle() != fontStyle )
167 impl.mController->SetDefaultFontStyle( fontStyle );
172 case Toolkit::TextLabel::Property::POINT_SIZE:
174 if( impl.mController )
176 const float pointSize = value.Get< float >();
178 if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
180 impl.mController->SetDefaultPointSize( pointSize );
185 case Toolkit::TextLabel::Property::MULTI_LINE:
187 if( impl.mController )
189 impl.mController->SetMultiLineEnabled( value.Get< bool >() );
193 case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
195 if( impl.mController )
197 LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
198 if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( value.Get< std::string >().c_str(),
199 HORIZONTAL_ALIGNMENT_STRING_TABLE,
200 HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
203 impl.mController->SetHorizontalAlignment( alignment );
208 case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
210 if( impl.mController )
212 LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
213 if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( value.Get< std::string >().c_str(),
214 VERTICAL_ALIGNMENT_STRING_TABLE,
215 VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
218 impl.mController->SetVerticalAlignment( alignment );
224 case Toolkit::TextLabel::Property::TEXT_COLOR:
226 if( impl.mController )
228 const Vector4 textColor = value.Get< Vector4 >();
229 if( impl.mController->GetTextColor() != textColor )
231 impl.mController->SetTextColor( textColor );
232 impl.mRenderer.Reset();
238 case Toolkit::TextLabel::Property::SHADOW_OFFSET:
240 if( impl.mController )
242 const Vector2 shadowOffset = value.Get< Vector2 >();
243 if ( impl.mController->GetShadowOffset() != shadowOffset )
245 impl.mController->SetShadowOffset( shadowOffset );
246 impl.mRenderer.Reset();
251 case Toolkit::TextLabel::Property::SHADOW_COLOR:
253 if( impl.mController )
255 const Vector4 shadowColor = value.Get< Vector4 >();
256 if ( impl.mController->GetShadowColor() != shadowColor )
258 impl.mController->SetShadowColor( shadowColor );
259 impl.mRenderer.Reset();
264 case Toolkit::TextLabel::Property::UNDERLINE_COLOR:
266 if( impl.mController )
268 const Vector4 color = value.Get< Vector4 >();
269 if ( impl.mController->GetUnderlineColor() != color )
271 impl.mController->SetUnderlineColor( color );
272 impl.mRenderer.Reset();
277 case Toolkit::TextLabel::Property::UNDERLINE_ENABLED:
279 if( impl.mController )
281 const bool enabled = value.Get< bool >();
282 if ( impl.mController->IsUnderlineEnabled() != enabled )
284 impl.mController->SetUnderlineEnabled( enabled );
285 impl.mRenderer.Reset();
291 case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT:
293 if( impl.mController )
295 float height = value.Get< float >();
296 if ( impl.mController->GetUnderlineHeight() != height )
298 impl.mController->SetUnderlineHeight( height );
299 impl.mRenderer.Reset();
308 Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index index )
310 Property::Value value;
312 Toolkit::TextLabel label = Toolkit::TextLabel::DownCast( Dali::BaseHandle( object ) );
316 TextLabel& impl( GetImpl( label ) );
319 case Toolkit::TextLabel::Property::RENDERING_BACKEND:
321 value = impl.mRenderingBackend;
324 case Toolkit::TextLabel::Property::TEXT:
326 if( impl.mController )
329 impl.mController->GetText( text );
334 case Toolkit::TextLabel::Property::FONT_FAMILY:
336 if( impl.mController )
338 value = impl.mController->GetDefaultFontFamily();
342 case Toolkit::TextLabel::Property::FONT_STYLE:
344 if( impl.mController )
346 value = impl.mController->GetDefaultFontStyle();
350 case Toolkit::TextLabel::Property::POINT_SIZE:
352 if( impl.mController )
354 value = impl.mController->GetDefaultPointSize();
358 case Toolkit::TextLabel::Property::MULTI_LINE:
360 if( impl.mController )
362 value = impl.mController->IsMultiLineEnabled();
366 case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
368 if( impl.mController )
370 const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
371 HORIZONTAL_ALIGNMENT_STRING_TABLE,
372 HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
375 value = std::string( name );
380 case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
382 if( impl.mController )
384 const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetVerticalAlignment(),
385 VERTICAL_ALIGNMENT_STRING_TABLE,
386 VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
389 value = std::string( name );
394 case Toolkit::TextLabel::Property::TEXT_COLOR:
396 if ( impl.mController )
398 value = impl.mController->GetTextColor();
402 case Toolkit::TextLabel::Property::SHADOW_OFFSET:
404 if ( impl.mController )
406 value = impl.mController->GetShadowOffset();
410 case Toolkit::TextLabel::Property::SHADOW_COLOR:
412 if ( impl.mController )
414 value = impl.mController->GetShadowColor();
418 case Toolkit::TextLabel::Property::UNDERLINE_COLOR:
420 if ( impl.mController )
422 value = impl.mController->GetUnderlineColor();
426 case Toolkit::TextLabel::Property::UNDERLINE_ENABLED:
428 if ( impl.mController )
430 value = impl.mController->IsUnderlineEnabled();
434 case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT:
436 if ( impl.mController )
438 value = impl.mController->GetUnderlineHeight();
448 void TextLabel::OnInitialize()
452 mController = Text::Controller::New( *this );
454 // Use height-for-width negotiation by default
455 self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
456 self.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
458 // Enable the text ellipsis.
459 LayoutEngine& engine = mController->GetLayoutEngine();
460 engine.SetTextEllipsisEnabled( true );
461 self.OnStageSignal().Connect( this, &TextLabel::OnStageConnect );
464 void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
467 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::OnStyleChange\n");
471 case StyleChange::DEFAULT_FONT_CHANGE:
473 DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnStyleChange StyleChange::DEFAULT_FONT_CHANGE\n");
474 if ( mController->GetDefaultFontFamily() == "" )
476 // Property system did not set the font so should update it.
477 // todo instruct text-controller to update model
482 case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
484 DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnStyleChange StyleChange::DEFAULT_FONT_SIZE_CHANGE (%f)\n", mController->GetDefaultPointSize() );
486 if ( (mController->GetDefaultPointSize() <= 0.0f) ) // If DefaultPointSize not set by Property system it will be 0.0f
488 // Property system did not set the PointSize so should update it.
489 // todo instruct text-controller to update model
493 case StyleChange::THEME_CHANGE:
495 GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
501 Vector3 TextLabel::GetNaturalSize()
503 return mController->GetNaturalSize();
506 float TextLabel::GetHeightForWidth( float width )
508 return mController->GetHeightForWidth( width );
511 void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container )
513 if( mController->Relayout( size ) ||
518 mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
524 void TextLabel::RequestTextRelayout()
529 void TextLabel::RenderText()
532 Actor renderableActor;
535 renderableActor = mRenderer->Render( mController->GetView(), self.GetHierarchyDepth() );
538 if( renderableActor != mRenderableActor )
540 UnparentAndReset( mRenderableActor );
542 if( renderableActor )
544 const Vector2& alignmentOffset = mController->GetAlignmentOffset();
545 renderableActor.SetPosition( alignmentOffset.x, alignmentOffset.y );
547 self.Add( renderableActor );
549 mRenderableActor = renderableActor;
553 void TextLabel::OnStageConnect( Dali::Actor actor )
555 if ( mHasBeenStaged )
561 mHasBeenStaged = true;
565 void TextLabel::AddDecoration( Actor& actor, bool needsClipping )
567 // TextLabel does not show decorations
570 void TextLabel::OnStageConnection( int depth )
572 // Call the Control::OnStageConnection() to set the depth of the background.
573 Control::OnStageConnection( depth );
575 // The depth of the text renderer is set in the RenderText() called from OnRelayout().
578 void TextLabel::TextChanged()
580 // TextLabel does not provide a signal for this
583 void TextLabel::MaxLengthReached()
585 // Pure Virtual from TextController Interface, only needed when inputting text
588 TextLabel::TextLabel()
589 : Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
590 mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
591 mHasBeenStaged( false )
595 TextLabel::~TextLabel()
599 } // namespace Internal
601 } // namespace Toolkit