From: David Steele Date: Mon, 7 Nov 2016 16:20:59 +0000 (-0800) Subject: Merge "Remove ResourceImages from Popup implementation" into devel/master X-Git-Tag: dali_1.2.14~9 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=4be17ce4114c629f694703381a0d09cca895850d;hp=311b47650f088ac9766a72c3deb7aa5a91bb49c2 Merge "Remove ResourceImages from Popup implementation" into devel/master --- diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp index f2e761f..cdb29f9 100644 --- a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp +++ b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp @@ -26,7 +26,6 @@ #include #include #include -#include using namespace Dali; using namespace Toolkit; @@ -403,122 +402,3 @@ int UtcDaliTextControllerSetGetAutoScrollEnabled(void) tet_result(TET_PASS); END_TEST; } - -int UtcDaliTextControllerSetGetAutoScrollSpeed(void) -{ - tet_infoline(" UtcDaliTextControllerSetGetAutoScrollSpeed"); - ToolkitTestApplication application; - - // Creates a text controller. - ControllerPtr controller = Controller::New(); - - DALI_TEST_CHECK( controller ); - - // Check the default value. - DALI_TEST_EQUALS( 0, controller->GetAutoScrollSpeed(), TEST_LOCATION ); - - // Set the auto scroll speed. - controller->SetAutoscrollSpeed( 10 ); - - DALI_TEST_EQUALS( 10, controller->GetAutoScrollSpeed(), TEST_LOCATION ); - - tet_result(TET_PASS); - END_TEST; -} - -int UtcDaliTextControllerSetGetAutoScrollLoopCount(void) -{ - tet_infoline(" UtcDaliTextControllerSetGetAutoScrollLoopCount"); - ToolkitTestApplication application; - - // Creates a text controller. - ControllerPtr controller = Controller::New(); - - DALI_TEST_CHECK( controller ); - - // Check the default value. - DALI_TEST_EQUALS( 0, controller->GetAutoScrollLoopCount(), TEST_LOCATION ); - - // Set the auto scroll loop count. - controller->SetAutoScrollLoopCount( 5 ); - - DALI_TEST_EQUALS( 5, controller->GetAutoScrollLoopCount(), TEST_LOCATION ); - - tet_result(TET_PASS); - END_TEST; -} - -int UtcDaliTextControllerSetGetAutoScrollWrapGap(void) -{ - tet_infoline(" UtcDaliTextControllerSetGetAutoScrollWrapGap"); - ToolkitTestApplication application; - - // Creates a text controller. - ControllerPtr controller = Controller::New(); - - DALI_TEST_CHECK( controller ); - - // Check the default value. - DALI_TEST_EQUALS( 0.f, controller->GetAutoScrollWrapGap(), Math::MACHINE_EPSILON_1000, TEST_LOCATION ); - - // Set the auto scroll loop count. - controller->SetAutoScrollWrapGap( 25.f ); - - DALI_TEST_EQUALS( 25.f, controller->GetAutoScrollWrapGap(), Math::MACHINE_EPSILON_1000, TEST_LOCATION ); - - tet_result(TET_PASS); - END_TEST; -} - -int UtcDaliTextControllerGetAutoScrollData(void) -{ - tet_infoline(" UtcDaliTextControllerGetAutoScrollData"); - ToolkitTestApplication application; - - // Load some fonts to get the same metrics on different platforms. - TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get(); - fontClient.SetDpi( 96u, 96u ); - - char* pathNamePtr = get_current_dir_name(); - const std::string pathName( pathNamePtr ); - free( pathNamePtr ); - - fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" ); - - // Creates a text controller. - ControllerPtr controller = Controller::New(); - - DALI_TEST_CHECK( controller ); - - DALI_TEST_CHECK( NULL == controller->GetAutoScrollData() ); - - // Set and check some values. - controller->SetAutoscrollSpeed( 10 ); - controller->SetAutoScrollLoopCount( 5 ); - controller->SetAutoScrollWrapGap( 25.f ); - - const ScrollerData* scrollerData = controller->GetAutoScrollData(); - DALI_TEST_CHECK( NULL != controller->GetAutoScrollData() ); - - DALI_TEST_EQUALS( Size::ZERO, scrollerData->mControlSize, TEST_LOCATION ); - DALI_TEST_EQUALS( Size::ZERO, scrollerData->mOffscreenSize, TEST_LOCATION ); - DALI_TEST_EQUALS( 10, scrollerData->mScrollSpeed, TEST_LOCATION ); - DALI_TEST_EQUALS( 5, scrollerData->mLoopCount, TEST_LOCATION ); - DALI_TEST_EQUALS( 25.f, scrollerData->mWrapGap, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); - DALI_TEST_EQUALS( 0.f, scrollerData->mAlignmentOffset, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); - DALI_TEST_CHECK( !scrollerData->mAutoScrollDirectionRTL ); - - // Set some text and layout. - controller->SetMarkupProcessorEnabled( true ); - controller->SetHorizontalAlignment( LayoutEngine::HORIZONTAL_ALIGN_END ); - controller->SetText( "Hello world" ); - controller->Relayout( Size( 100.f, 20.f ) ); - - scrollerData = controller->GetAutoScrollData(); - DALI_TEST_EQUALS( Size( 100.f, 20.f ), scrollerData->mControlSize, TEST_LOCATION ); - DALI_TEST_EQUALS( Size( 80.f, 20.f ), scrollerData->mOffscreenSize, TEST_LOCATION ); - DALI_TEST_EQUALS( 20.f, scrollerData->mAlignmentOffset, Math::MACHINE_EPSILON_1000, TEST_LOCATION ); - - tet_result(TET_PASS); - END_TEST; -} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp index 5f70749..7cda6e5 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp @@ -1047,8 +1047,7 @@ int UtcDaliVisualGetPropertyMap10(void) DALI_TEST_CHECK( !value->Get() ); value = resultMap.Find( TextVisual::Property::ENABLE_AUTO_SCROLL, Property::BOOLEAN ); - DALI_TEST_CHECK( value ); - DALI_TEST_CHECK( !value->Get() ); + DALI_TEST_CHECK( !value ); value = resultMap.Find( TextVisual::Property::LINE_SPACING, Property::FLOAT ); DALI_TEST_CHECK( value ); diff --git a/dali-toolkit/devel-api/visual-factory/visual-base.h b/dali-toolkit/devel-api/visual-factory/visual-base.h index b590484..49e8cf0 100644 --- a/dali-toolkit/devel-api/visual-factory/visual-base.h +++ b/dali-toolkit/devel-api/visual-factory/visual-base.h @@ -38,11 +38,47 @@ class Base; namespace Visual { /** - * @brief Visual provides a renderer for rendering the controls. A control may have multiple visuals. + * @brief A Visual provides a renderer for drawing a control component. A control may have multiple visuals. * - * Visuals reuses geometry, shader etc. across controls and manages the renderer and texture sets to exist only when control is on-stage. - * It also responds to actor size and color change, and provides the clipping at the renderer level. + * Visuals reuse geometry, shader etc. across controls. They ensure that the renderer and texture sets exist only when control is on-stage. + * Each visual also responds to actor size and color change, and provides clipping at the renderer level. * Note: The visual responds to the the Actor::COLOR by blending it with the 'Multiply' operator. + * + * The following properties are optional, but can be supplied in the property map to Dali::Toolkit::VisualFactory::CreateVisual(). + * + * | %Property Name | Type | + * |-------------------------|------------------| + * | customShader | MAP | + * | transform | MAP | + * + * where \b customShader is a map with at least one of the following properties: + * | %Property Name | Type | Required | Default | Description | + * |-------------------------|------------------|----------|---------|-------------| + * | vertexShader | STRING | No | "" | Vertex shader code| + * | fragmentShader | STRING | No | "" | Fragment shader code| + * | subdivideGridX | INTEGER | No | 1 | How to subdivide the grid along X | + * | subdivideGridY | INTEGER | No | 1 | How to subdivide the grid along Y | + * | shaderHints | INTEGER or ARRAY of STRING | No | NONE | Bitmask of hints @sa Dali::Shader::Hint | + * + * and \b transform is a map with the following properties: + * | %Property Name | Type | Required | Default |Description | + * |-------------------------|------------------|----------|---------|------------| + * | offset | VECTOR2 | No | (0,0) | Offset of visual from origin | + * | size | VECTOR2 | No | (1,1) | size of visual | + * | origin | INTEGER or STRING | No | CENTER | origin of the visual @sa Dali::Toolkit::Align | + * | anchorPoint | INTEGER or STRING | No | CENTER | anchor point of the visual @sa Dali::Toolkit::Align | + * | offsetSizeMode | VECTOR4 | No | (0,0,0,0) | See below | + * + * + * offsetSizeMode describes whether the offset and the size are + * relative or absolute by using 0 or 1 respectively in the corresponding + * components (offsetSizeMode.xy for offset.xy; offsetSizeMode.zw for size.xy). + * + * Relative means that the component describes a factor of the parent control size; + * size.x = 1 means full width; size.y = 0.5 means half height. + * + * Absolute means that the component describes world units (equivalent to pixels) + * */ class DALI_IMPORT_API Base : public BaseHandle { diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp index 1d6af0f..094e755 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp @@ -24,9 +24,13 @@ // INTERNAL INCLUDES #include -#include -#include +#include +#include +#include #include +#include +#include +#include #include using Dali::Toolkit::Text::LayoutEngine; @@ -52,6 +56,22 @@ namespace Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS"); #endif +const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] = +{ + { "BEGIN", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN }, + { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER }, + { "END", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END }, +}; +const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] ); + +const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] = +{ + { "TOP", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP }, + { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER }, + { "BOTTOM", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_BOTTOM }, +}; +const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] ); + // Type registration BaseHandle Create() { @@ -88,34 +108,6 @@ DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "outline", MAP, DALI_TYPE_REGISTRATION_END() -const int TEXT_VISUAL_PROPERTY_TABLE[] = { - Dali::Toolkit::TextVisual::Property::RENDERING_BACKEND, - Dali::Toolkit::TextVisual::Property::TEXT, - Dali::Toolkit::TextVisual::Property::FONT_FAMILY, - Dali::Toolkit::TextVisual::Property::FONT_STYLE, - Dali::Toolkit::TextVisual::Property::POINT_SIZE, - Dali::Toolkit::TextVisual::Property::MULTI_LINE, - Dali::Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT, - Dali::Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT, - Dali::Toolkit::TextVisual::Property::TEXT_COLOR, - Dali::Toolkit::TextVisual::Property::SHADOW, - Dali::Toolkit::TextVisual::Property::SHADOW, - Dali::Toolkit::TextVisual::Property::UNDERLINE, - Dali::Toolkit::TextVisual::Property::UNDERLINE, - Dali::Toolkit::TextVisual::Property::UNDERLINE, - Dali::Toolkit::TextVisual::Property::ENABLE_MARKUP, - Dali::Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL, - Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED, - Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT, - Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_GAP, - Dali::Toolkit::TextVisual::Property::LINE_SPACING, - Dali::Toolkit::TextVisual::Property::UNDERLINE, - Dali::Toolkit::TextVisual::Property::SHADOW, - Dali::Toolkit::TextVisual::Property::EMBOSS, - Dali::Toolkit::TextVisual::Property::OUTLINE, - Dali::Toolkit::TextVisual::Property::BATCHING_ENABLED -}; - } // namespace Toolkit::TextLabel TextLabel::New() @@ -139,10 +131,298 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr if( label ) { - TextLabel& impl = GetImpl( label ); + TextLabel& impl( GetImpl( label ) ); + switch( index ) + { + case Toolkit::TextLabel::Property::RENDERING_BACKEND: + { + int backend = value.Get< int >(); + +#ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING + if( Text::RENDERING_VECTOR_BASED == backend ) + { + backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering + } +#endif + if( impl.mRenderingBackend != backend ) + { + impl.mRenderingBackend = backend; + impl.mRenderer.Reset(); + + if( impl.mController ) + { + // When using the vector-based rendering, the size of the GLyphs are different + TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH; + impl.mController->SetGlyphType( glyphType ); + } + } + break; + } + case Toolkit::TextLabel::Property::TEXT: + { + if( impl.mController ) + { + impl.mController->SetText( value.Get< std::string >() ); + } + break; + } + case Toolkit::TextLabel::Property::FONT_FAMILY: + { + if( impl.mController ) + { + const std::string fontFamily = value.Get< std::string >(); + + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::SetProperty Property::FONT_FAMILY newFont(%s)\n", fontFamily.c_str() ); + impl.mController->SetDefaultFontFamily( fontFamily ); + } + break; + } + case Toolkit::TextLabel::Property::FONT_STYLE: + { + SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT ); + break; + } + case Toolkit::TextLabel::Property::POINT_SIZE: + { + if( impl.mController ) + { + const float pointSize = value.Get< float >(); + + if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) ) + { + impl.mController->SetDefaultPointSize( pointSize ); + } + } + break; + } + case Toolkit::TextLabel::Property::MULTI_LINE: + { + if( impl.mController ) + { + impl.mController->SetMultiLineEnabled( value.Get< bool >() ); + } + break; + } + case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT: + { + if( impl.mController ) + { + LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN ); + if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( value.Get< std::string >().c_str(), + HORIZONTAL_ALIGNMENT_STRING_TABLE, + HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT, + alignment ) ) + { + impl.mController->SetHorizontalAlignment( alignment ); + } + } + break; + } + case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT: + { + if( impl.mController ) + { + LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM ); + if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( value.Get< std::string >().c_str(), + VERTICAL_ALIGNMENT_STRING_TABLE, + VERTICAL_ALIGNMENT_STRING_TABLE_COUNT, + alignment ) ) + { + impl.mController->SetVerticalAlignment( alignment ); + } + } + break; + } + + case Toolkit::TextLabel::Property::TEXT_COLOR: + { + if( impl.mController ) + { + const Vector4 textColor = value.Get< Vector4 >(); + if( impl.mController->GetTextColor() != textColor ) + { + impl.mController->SetTextColor( textColor ); + impl.mRenderer.Reset(); + } + } + break; + } + + case Toolkit::TextLabel::Property::SHADOW_OFFSET: + { + if( impl.mController ) + { + const Vector2 shadowOffset = value.Get< Vector2 >(); + if ( impl.mController->GetShadowOffset() != shadowOffset ) + { + impl.mController->SetShadowOffset( shadowOffset ); + impl.mRenderer.Reset(); + } + } + break; + } + case Toolkit::TextLabel::Property::SHADOW_COLOR: + { + if( impl.mController ) + { + const Vector4 shadowColor = value.Get< Vector4 >(); + if ( impl.mController->GetShadowColor() != shadowColor ) + { + impl.mController->SetShadowColor( shadowColor ); + impl.mRenderer.Reset(); + } + } + break; + } + case Toolkit::TextLabel::Property::UNDERLINE_COLOR: + { + if( impl.mController ) + { + const Vector4 color = value.Get< Vector4 >(); + if ( impl.mController->GetUnderlineColor() != color ) + { + impl.mController->SetUnderlineColor( color ); + impl.mRenderer.Reset(); + } + } + break; + } + case Toolkit::TextLabel::Property::UNDERLINE_ENABLED: + { + if( impl.mController ) + { + const bool enabled = value.Get< bool >(); + if ( impl.mController->IsUnderlineEnabled() != enabled ) + { + impl.mController->SetUnderlineEnabled( enabled ); + impl.mRenderer.Reset(); + } + } + break; + } - // Sets the property to the to the text visual. - impl.mVisual.SetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX], value ); + case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT: + { + if( impl.mController ) + { + float height = value.Get< float >(); + if( fabsf( impl.mController->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 ) + { + impl.mController->SetUnderlineHeight( height ); + impl.mRenderer.Reset(); + } + } + break; + } + case Toolkit::TextLabel::Property::ENABLE_MARKUP: + { + if( impl.mController ) + { + const bool enableMarkup = value.Get(); + impl.mController->SetMarkupProcessorEnabled( enableMarkup ); + } + break; + } + case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL: + { + if( impl.mController ) + { + const bool enableAutoScroll = value.Get(); + // If request to auto scroll is the same as current state then do nothing. + if ( enableAutoScroll != impl.mController->IsAutoScrollEnabled() ) + { + // If request is disable (false) and auto scrolling is enabled then need to stop it + if ( enableAutoScroll == false ) + { + if( impl.mTextScroller ) + { + impl.mTextScroller->SetLoopCount( 0 ); // Causes the current animation to finish playing (0) + } + } + // If request is enable (true) then start autoscroll as not already running + else + { + impl.mController->GetLayoutEngine().SetTextEllipsisEnabled( false ); + impl.mController->SetAutoScrollEnabled( enableAutoScroll ); + } + } + } + break; + } + case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED: + { + if( !impl.mTextScroller ) + { + impl.mTextScroller = Text::TextScroller::New( impl ); + } + impl.mTextScroller->SetSpeed( value.Get() ); + break; + } + case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT: + { + if( !impl.mTextScroller ) + { + impl.mTextScroller = Text::TextScroller::New( impl ); + } + impl.mTextScroller->SetLoopCount( value.Get() ); + break; + } + case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP: + { + if( !impl.mTextScroller ) + { + impl.mTextScroller = Text::TextScroller::New( impl ); + } + impl.mTextScroller->SetGap( value.Get() ); + break; + } + case Toolkit::TextLabel::Property::LINE_SPACING: + { + if( impl.mController ) + { + const float lineSpacing = value.Get(); + impl.mController->SetDefaultLineSpacing( lineSpacing ); + impl.mRenderer.Reset(); + } + break; + } + case Toolkit::TextLabel::Property::UNDERLINE: + { + const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); + if( update ) + { + impl.mRenderer.Reset(); + } + break; + } + case Toolkit::TextLabel::Property::SHADOW: + { + const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); + if( update ) + { + impl.mRenderer.Reset(); + } + break; + } + case Toolkit::TextLabel::Property::EMBOSS: + { + const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); + if( update ) + { + impl.mRenderer.Reset(); + } + break; + } + case Toolkit::TextLabel::Property::OUTLINE: + { + const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); + if( update ) + { + impl.mRenderer.Reset(); + } + break; + } + } } } @@ -154,126 +434,203 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde if( label ) { - TextLabel& impl = GetImpl( label ); - - if( ( Toolkit::TextLabel::Property::SHADOW_OFFSET == index ) || - ( Toolkit::TextLabel::Property::SHADOW_COLOR == index ) || - ( Toolkit::TextLabel::Property::UNDERLINE_ENABLED == index ) || - ( Toolkit::TextLabel::Property::UNDERLINE_COLOR == index ) || - ( Toolkit::TextLabel::Property::UNDERLINE_HEIGHT == index ) ) + TextLabel& impl( GetImpl( label ) ); + switch( index ) { - // TODO : Branch to be removed when the deprecated properties are finally removed. - value = impl.mVisual.GetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX] ); - - switch( index ) + case Toolkit::TextLabel::Property::RENDERING_BACKEND: + { + value = impl.mRenderingBackend; + break; + } + case Toolkit::TextLabel::Property::TEXT: { - case Toolkit::TextLabel::Property::SHADOW_OFFSET: // Converts the deprecated property to the new one. + if( impl.mController ) { - bool colorDefined = false; - Vector4 color; - bool offsetDefined = false; - Vector2 offset; - const bool empty = Text::ParseShadowProperties( value.Get(), - colorDefined, - color, - offsetDefined, - offset ); - - if( !empty ) - { - value = offset; - } - break; + std::string text; + impl.mController->GetText( text ); + value = text; } - case Toolkit::TextLabel::Property::SHADOW_COLOR: // Converts the deprecated property to the new one. + break; + } + case Toolkit::TextLabel::Property::FONT_FAMILY: + { + if( impl.mController ) { - bool colorDefined = false; - Vector4 color; - bool offsetDefined = false; - Vector2 offset; - const bool empty = Text::ParseShadowProperties( value.Get(), - colorDefined, - color, - offsetDefined, - offset ); - - if( !empty ) - { - value = color; - } - break; - } - case Toolkit::TextLabel::Property::UNDERLINE_ENABLED: // Converts the deprecated property to the new one. - { - bool enabled = false; - bool colorDefined = false; - Vector4 color; - bool heightDefined = false; - float height = 0.f; - const bool empty = Text::ParseUnderlineProperties( value.Get(), - enabled, - colorDefined, - color, - heightDefined, - height ); - - if( !empty ) + value = impl.mController->GetDefaultFontFamily(); + } + break; + } + case Toolkit::TextLabel::Property::FONT_STYLE: + { + GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT ); + break; + } + case Toolkit::TextLabel::Property::POINT_SIZE: + { + if( impl.mController ) + { + value = impl.mController->GetDefaultPointSize(); + } + break; + } + case Toolkit::TextLabel::Property::MULTI_LINE: + { + if( impl.mController ) + { + value = impl.mController->IsMultiLineEnabled(); + } + break; + } + case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT: + { + if( impl.mController ) + { + const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(), + HORIZONTAL_ALIGNMENT_STRING_TABLE, + HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT ); + if( name ) { - value = enabled; + value = std::string( name ); } - break; - } - case Toolkit::TextLabel::Property::UNDERLINE_COLOR: // Converts the deprecated property to the new one. - { - bool enabled = false; - bool colorDefined = false; - Vector4 color; - bool heightDefined = false; - float height = 0.f; - const bool empty = Text::ParseUnderlineProperties( value.Get(), - enabled, - colorDefined, - color, - heightDefined, - height ); - - if( !empty && colorDefined ) + } + break; + } + case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT: + { + if( impl.mController ) + { + const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetVerticalAlignment(), + VERTICAL_ALIGNMENT_STRING_TABLE, + VERTICAL_ALIGNMENT_STRING_TABLE_COUNT ); + if( name ) { - value = color; + value = std::string( name ); } - break; - } - case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT: // Converts the deprecated property to the new one. - { - bool enabled = false; - bool colorDefined = false; - Vector4 color; - bool heightDefined = false; - float height = 0.f; - const bool empty = Text::ParseUnderlineProperties( value.Get(), - enabled, - colorDefined, - color, - heightDefined, - height ); - - if( !empty && heightDefined ) + } + break; + } + case Toolkit::TextLabel::Property::TEXT_COLOR: + { + if ( impl.mController ) + { + value = impl.mController->GetTextColor(); + } + break; + } + case Toolkit::TextLabel::Property::SHADOW_OFFSET: + { + if ( impl.mController ) + { + value = impl.mController->GetShadowOffset(); + } + break; + } + case Toolkit::TextLabel::Property::SHADOW_COLOR: + { + if ( impl.mController ) + { + value = impl.mController->GetShadowColor(); + } + break; + } + case Toolkit::TextLabel::Property::UNDERLINE_COLOR: + { + if ( impl.mController ) + { + value = impl.mController->GetUnderlineColor(); + } + break; + } + case Toolkit::TextLabel::Property::UNDERLINE_ENABLED: + { + if ( impl.mController ) + { + value = impl.mController->IsUnderlineEnabled(); + } + break; + } + case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT: + { + if ( impl.mController ) + { + value = impl.mController->GetUnderlineHeight(); + } + break; + } + case Toolkit::TextLabel::Property::ENABLE_MARKUP: + { + if( impl.mController ) + { + value = impl.mController->IsMarkupProcessorEnabled(); + } + break; + } + case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL: + { + if( impl.mController ) + { + value = impl.mController->IsAutoScrollEnabled(); + } + break; + } + case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED: + { + TextLabel& impl( GetImpl( label ) ); + if ( impl.mTextScroller ) + { + value = impl.mTextScroller->GetSpeed(); + } + break; + } + case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT: + { + if( impl.mController ) + { + TextLabel& impl( GetImpl( label ) ); + if ( impl.mTextScroller ) { - value = height; + value = impl.mTextScroller->GetLoopCount(); } - break; } - default: + break; + } + case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP: + { + TextLabel& impl( GetImpl( label ) ); + if ( impl.mTextScroller ) { - // Nothing to do. - break; + value = impl.mTextScroller->GetGap(); } + break; + } + case Toolkit::TextLabel::Property::LINE_SPACING: + { + if( impl.mController ) + { + value = impl.mController->GetDefaultLineSpacing(); + } + break; + } + case Toolkit::TextLabel::Property::UNDERLINE: + { + GetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); + break; + } + case Toolkit::TextLabel::Property::SHADOW: + { + GetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); + break; + } + case Toolkit::TextLabel::Property::EMBOSS: + { + GetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); + break; + } + case Toolkit::TextLabel::Property::OUTLINE: + { + GetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ); + break; } - } - else - { - // Retrieves the property from the text visual. - value = impl.mVisual.GetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX] ); } } @@ -284,23 +641,23 @@ void TextLabel::OnInitialize() { Actor self = Self(); - // Creates the text's visual. - Property::Map visualMap; - visualMap[Toolkit::VisualProperty::TYPE] = Toolkit::Visual::TEXT; - visualMap[Toolkit::TextVisual::Property::RENDERING_BACKEND] = static_cast( DEFAULT_RENDERING_BACKEND ); + mController = Text::Controller::New( this ); - mVisual = Toolkit::VisualFactory::Get().CreateVisual( visualMap ); - RegisterVisual( Toolkit::TextLabel::Property::TEXT, mVisual ); - - Internal::Visual::Base& visualBase = Toolkit::GetImplementation( mVisual ); - TextVisual* textVisual = static_cast( &visualBase ); - - // Sets the text's control interface. - textVisual->SetTextControlInterface( this ); + // When using the vector-based rendering, the size of the GLyphs are different + TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH; + mController->SetGlyphType( glyphType ); // Use height-for-width negotiation by default self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); self.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT ); + + // Enable the text ellipsis. + LayoutEngine& engine = mController->GetLayoutEngine(); + + engine.SetTextEllipsisEnabled( true ); // If false then text larger than control will overflow + engine.SetCursorWidth( 0u ); // Do not layout space for the cursor. + + self.OnStageSignal().Connect( this, &TextLabel::OnStageConnect ); } void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change ) @@ -314,9 +671,7 @@ void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange:: // Property system did not set the font so should update it. const std::string& newFont = GetImpl( styleManager ).GetDefaultFontFamily(); DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnStyleChange StyleChange::DEFAULT_FONT_CHANGE newFont(%s)\n", newFont.c_str() ); - - const std::string fontString = "{\"family\":\"" + newFont + "\",\"type\":\"system\"}"; - mVisual.SetProperty( Toolkit::TextVisual::Property::FONT_FAMILY, fontString ); + mController->UpdateAfterFontChange( newFont ); break; } case StyleChange::DEFAULT_FONT_SIZE_CHANGE: @@ -334,22 +689,29 @@ void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange:: Vector3 TextLabel::GetNaturalSize() { - Vector2 naturalSize; - mVisual.GetNaturalSize( naturalSize ); - - return Vector3( naturalSize ); + return mController->GetNaturalSize(); } float TextLabel::GetHeightForWidth( float width ) { - return mVisual.GetHeightForWidth( width ); + return mController->GetHeightForWidth( width ); } void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container ) { DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnRelayout\n" ); - mVisual.SetSize( size ); + const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size ); + + if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) || + !mRenderer ) + { + if( !mRenderer ) + { + mRenderer = Text::Backend::Get().NewRenderer( mRenderingBackend ); + } + RenderText(); + } } void TextLabel::RequestTextRelayout() @@ -357,16 +719,95 @@ void TextLabel::RequestTextRelayout() RelayoutRequest(); } +void TextLabel::RenderText() +{ + DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::RenderText IsAutoScrollEnabled[%s] [%p]\n", ( mController->IsAutoScrollEnabled())?"true":"false", this ); + + Actor self = Self(); + Actor renderableActor; + + if( mRenderer ) + { + renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT ); + } + + if( renderableActor != mRenderableActor ) + { + UnparentAndReset( mRenderableActor ); + + if( renderableActor ) + { + const Vector2& scrollOffset = mController->GetScrollPosition(); + renderableActor.SetPosition( scrollOffset.x, scrollOffset.y ); + + self.Add( renderableActor ); + } + mRenderableActor = renderableActor; + + if ( mController->IsAutoScrollEnabled() ) + { + SetUpAutoScrolling(); + } + } +} + +void TextLabel::SetUpAutoScrolling() +{ + const Size& controlSize = mController->GetView().GetControlSize(); + 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. + const float alignmentOffset = mController->GetAutoScrollLineAlignment(); + const Text::CharacterDirection direction = mController->GetAutoScrollDirection(); + + DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling alignmentOffset[%f] offScreenSize[%f,%f] controlSize[%f,%f]\n", + alignmentOffset, offScreenSize.x,offScreenSize.y , controlSize.x,controlSize.y ); + + if ( !mTextScroller ) + { + DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling Creating default TextScoller\n" ); + + // If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults + mTextScroller = Text::TextScroller::New( *this ); + } + mTextScroller->SetParameters( mRenderableActor, controlSize, offScreenSize, direction, alignmentOffset ); + + Actor self = Self(); + self.Add( mTextScroller->GetScrollingText() ); + self.Add( mTextScroller->GetSourceCamera() ); +} + +void TextLabel::OnStageConnect( Dali::Actor actor ) +{ + if ( mHasBeenStaged ) + { + RenderText(); + } + else + { + mHasBeenStaged = true; + } +} + void TextLabel::OnStageConnection( int depth ) { // Call the Control::OnStageConnection() to set the depth of the background. Control::OnStageConnection( depth ); - // The depth of the text renderer is set by the text-visual called from OnRelayout(). + // The depth of the text renderer is set in the RenderText() called from OnRelayout(). +} + +void TextLabel::ScrollingFinished() +{ + // Pure Virtual from TextScroller Interface + DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::ScrollingFinished\n"); + mController->SetAutoScrollEnabled( false ); + mController->GetLayoutEngine().SetTextEllipsisEnabled( true ); + RequestTextRelayout(); } TextLabel::TextLabel() -: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ) +: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ), + mRenderingBackend( DEFAULT_RENDERING_BACKEND ), + mHasBeenStaged( false ) { } diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.h b/dali-toolkit/internal/controls/text-controls/text-label-impl.h index bdc587d..c928763 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.h @@ -22,7 +22,10 @@ #include #include #include -#include +#include +#include +#include +#include namespace Dali { @@ -36,7 +39,7 @@ namespace Internal /** * @brief A control which renders a short text string. */ -class TextLabel : public Control, public Text::ControlInterface +class TextLabel : public Control, public Text::ControlInterface, public Text::ScrollerInterface { public: @@ -104,6 +107,13 @@ private: // From Control */ virtual void RequestTextRelayout(); +private: // from TextScroller + + /** + * @copydoc Text::ScrollerInterface::ScrollingFinished() + */ + virtual void ScrollingFinished(); + private: // Implementation /** @@ -122,9 +132,27 @@ private: TextLabel(const TextLabel&); TextLabel& operator=(const TextLabel& rhs); + // Connection needed to re-render text, when a Text Label returns to the stage + void OnStageConnect( Dali::Actor actor ); + + /** + * @brief Render view, create and attach actor(s) to this Text Label + */ + void RenderText(); + + /** + * @brief Set up Autoscrolling + */ + void SetUpAutoScrolling(); + private: // Data - Toolkit::Visual::Base mVisual; + Text::ControllerPtr mController; + Text::RendererPtr mRenderer; + Text::TextScrollerPtr mTextScroller; + Actor mRenderableActor; + int mRenderingBackend; + bool mHasBeenStaged:1; }; } // namespace Internal diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list index 902074b..1e78bf6 100644 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -115,7 +115,6 @@ toolkit_src_files = \ $(toolkit_src_dir)/text/text-font-style.cpp \ $(toolkit_src_dir)/text/text-io.cpp \ $(toolkit_src_dir)/text/text-scroller.cpp \ - $(toolkit_src_dir)/text/text-scroller-data.cpp \ $(toolkit_src_dir)/text/text-scroller-interface.cpp \ $(toolkit_src_dir)/text/text-view.cpp \ $(toolkit_src_dir)/text/text-view-interface.cpp \ diff --git a/dali-toolkit/internal/text/text-controller-impl.h b/dali-toolkit/internal/text/text-controller-impl.h index 608ea7d..3a89308 100644 --- a/dali-toolkit/internal/text/text-controller-impl.h +++ b/dali-toolkit/internal/text/text-controller-impl.h @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -298,7 +297,6 @@ struct Controller::Impl mEmbossDefaults( NULL ), mOutlineDefaults( NULL ), mEventData( NULL ), - mAutoScrollData( NULL ), mFontClient(), mClipboard(), mView(), @@ -313,7 +311,8 @@ struct Controller::Impl mRecalculateNaturalSize( true ), mMarkupProcessorEnabled( false ), mClipboardHideEnabled( true ), - mIsAutoScrollEnabled( false ) + mIsAutoScrollEnabled( false ), + mAutoScrollDirectionRTL( false ) { mLogicalModel = LogicalModel::New(); mVisualModel = VisualModel::New(); @@ -340,7 +339,6 @@ struct Controller::Impl delete mEmbossDefaults; delete mOutlineDefaults; delete mEventData; - delete mAutoScrollData; } // Text Controller Implementation. @@ -703,7 +701,6 @@ public: EmbossDefaults* mEmbossDefaults; ///< Avoid allocating this when the user does not specify emboss parameters. OutlineDefaults* mOutlineDefaults; ///< Avoid allocating this when the user does not specify outline parameters. EventData* mEventData; ///< Avoid allocating everything for text input until EnableTextInput(). - ScrollerData* mAutoScrollData; ///< Avoid allocating this when the user does not specify the auto text scrolling feature. TextAbstraction::FontClient mFontClient; ///< Handle to the font client. Clipboard mClipboard; ///< Handle to the system clipboard View mView; ///< The view interface to the rendering back-end. @@ -722,8 +719,10 @@ public: bool mRecalculateNaturalSize:1; ///< Whether the natural size needs to be recalculated. bool mMarkupProcessorEnabled:1; ///< Whether the mark-up procesor is enabled. - bool mClipboardHideEnabled:1; ///< Whether the ClipboardHide function work or not. + bool mClipboardHideEnabled:1; ///< Whether the ClipboardHide function work or not bool mIsAutoScrollEnabled:1; ///< Whether auto text scrolling is enabled. + CharacterDirection mAutoScrollDirectionRTL:1; ///< Direction of auto scrolling, true if rtl + }; } // namespace Text diff --git a/dali-toolkit/internal/text/text-controller.cpp b/dali-toolkit/internal/text/text-controller.cpp index 769d0e04..11a9161 100644 --- a/dali-toolkit/internal/text/text-controller.cpp +++ b/dali-toolkit/internal/text/text-controller.cpp @@ -118,11 +118,6 @@ ControllerPtr Controller::New( ControlInterface* controlInterface, editableControlInterface ) ); } -void Controller::SetTextControlInterface( ControlInterface* controlInterface ) -{ - mImpl->mControlInterface = controlInterface; -} - // public : Configure the text controller. void Controller::EnableTextInput( DecoratorPtr decorator ) @@ -170,10 +165,6 @@ void Controller::SetAutoScrollEnabled( bool enable ) UPDATE_DIRECTION | REORDER ); - if( NULL == mImpl->mAutoScrollData ) - { - mImpl->mAutoScrollData = new ScrollerData(); - } } else { @@ -202,87 +193,22 @@ bool Controller::IsAutoScrollEnabled() const return mImpl->mIsAutoScrollEnabled; } -void Controller::SetAutoscrollSpeed( int scrollSpeed ) -{ - if( NULL == mImpl->mAutoScrollData ) - { - mImpl->mAutoScrollData = new ScrollerData(); - } - - mImpl->mAutoScrollData->mScrollSpeed = scrollSpeed; -} - -int Controller::GetAutoScrollSpeed() const -{ - if( NULL != mImpl->mAutoScrollData ) - { - return mImpl->mAutoScrollData->mScrollSpeed; - } - - return 0; -} - -void Controller::SetAutoScrollLoopCount( int loopCount ) -{ - if( NULL == mImpl->mAutoScrollData ) - { - mImpl->mAutoScrollData = new ScrollerData(); - } - - mImpl->mAutoScrollData->mLoopCount = loopCount; -} - -int Controller::GetAutoScrollLoopCount() const -{ - if( NULL != mImpl->mAutoScrollData ) - { - return mImpl->mAutoScrollData->mLoopCount; - } - - return 0; -} - -void Controller::SetAutoScrollWrapGap( float wrapGap ) +CharacterDirection Controller::GetAutoScrollDirection() const { - if( NULL == mImpl->mAutoScrollData ) - { - mImpl->mAutoScrollData = new ScrollerData(); - } - - mImpl->mAutoScrollData->mWrapGap = wrapGap; + return mImpl->mAutoScrollDirectionRTL; } -float Controller::GetAutoScrollWrapGap() const +float Controller::GetAutoScrollLineAlignment() const { - if( NULL != mImpl->mAutoScrollData ) - { - return mImpl->mAutoScrollData->mWrapGap; - } - - return 0.f; -} + float offset = 0.f; -const ScrollerData* const Controller::GetAutoScrollData() -{ - if( NULL != mImpl->mAutoScrollData ) + if( mImpl->mVisualModel && + ( 0u != mImpl->mVisualModel->mLines.Count() ) ) { - // Need to update the data with the latest layout. - if( mImpl->mVisualModel ) - { - mImpl->mAutoScrollData->mControlSize = mImpl->mVisualModel->mControlSize; - mImpl->mAutoScrollData->mOffscreenSize = GetNaturalSize().GetVectorXY(); - - mImpl->mAutoScrollData->mAlignmentOffset = 0.f; - if( 0u != mImpl->mVisualModel->mLines.Count() ) - { - mImpl->mAutoScrollData->mAlignmentOffset = ( *mImpl->mVisualModel->mLines.Begin() ).alignmentOffset; - } - } - - return mImpl->mAutoScrollData; + offset = ( *mImpl->mVisualModel->mLines.Begin() ).alignmentOffset; } - return NULL; + return offset; } void Controller::SetHorizontalScrollEnabled( bool enable ) @@ -2202,17 +2128,6 @@ void Controller::TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Butt } } -// private : Inherit from TextScroller. - -void Controller::ScrollingFinished() -{ - // Pure Virtual from TextScroller Interface - SetAutoScrollEnabled( false ); - GetLayoutEngine().SetTextEllipsisEnabled( true ); - - mImpl->RequestRelayout(); -} - // private : Update. void Controller::InsertText( const std::string& text, Controller::InsertType type ) @@ -2678,10 +2593,7 @@ bool Controller::DoRelayout( const Size& size, if ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) ) { - if( NULL != mImpl->mAutoScrollData ) - { - mImpl->mAutoScrollData->mAutoScrollDirectionRTL = false; - } + mImpl->mAutoScrollDirectionRTL = false; } // Reorder the lines @@ -2717,11 +2629,9 @@ bool Controller::DoRelayout( const Size& size, if ( ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) ) && ( numberOfLines > 0 ) ) { const LineRun* const firstline = mImpl->mVisualModel->mLines.Begin(); - if( firstline && - mImpl->mIsAutoScrollEnabled && - ( NULL != mImpl->mAutoScrollData ) ) + if ( firstline ) { - mImpl->mAutoScrollData->mAutoScrollDirectionRTL = firstline->direction; + mImpl->mAutoScrollDirectionRTL = firstline->direction; } } } @@ -2753,7 +2663,7 @@ bool Controller::DoRelayout( const Size& size, #if defined(DEBUG_ENABLED) std::string currentText; GetText( currentText ); - DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::DoRelayout [%p] mImpl->mAutoScrollDirectionRTL[%s] [%s]\n", this, ( ( NULL != mImpl->mAutoScrollData ) && mImpl->mAutoScrollData->mAutoScrollDirectionRTL)?"true":"false", currentText.c_str() ); + DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::DoRelayout [%p] mImpl->mAutoScrollDirectionRTL[%s] [%s]\n", this, (mImpl->mAutoScrollDirectionRTL)?"true":"false", currentText.c_str() ); #endif DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::DoRelayout, view updated %s\n", ( viewUpdated ? "true" : "false" ) ); return viewUpdated; diff --git a/dali-toolkit/internal/text/text-controller.h b/dali-toolkit/internal/text/text-controller.h index ce5c51a..a78d0eb 100644 --- a/dali-toolkit/internal/text/text-controller.h +++ b/dali-toolkit/internal/text/text-controller.h @@ -26,7 +26,6 @@ #include #include #include -#include namespace Dali { @@ -41,7 +40,6 @@ class Controller; class ControlInterface; class EditableControlInterface; class View; -struct ScrollerData; typedef IntrusivePtr ControllerPtr; @@ -56,7 +54,7 @@ typedef IntrusivePtr ControllerPtr; * * The text selection popup button callbacks are as well handled via the TextSelectionPopupCallbackInterface interface. */ -class Controller : public RefObject, public Decorator::ControllerInterface, public TextSelectionPopupCallbackInterface, public Text::ScrollerInterface +class Controller : public RefObject, public Decorator::ControllerInterface, public TextSelectionPopupCallbackInterface { public: // Enumerated types. @@ -149,13 +147,6 @@ public: // Constructor. static ControllerPtr New( ControlInterface* controlInterface, EditableControlInterface* editableControlInterface ); - /** - * @brief Sets the text-control interface. - * - * @param[in] controlInterface The text-control interface. - */ - void SetTextControlInterface( ControlInterface* controlInterface ); - public: // Configure the text controller. /** @@ -210,53 +201,17 @@ public: // Configure the text controller. bool IsAutoScrollEnabled() const; /** - * @brief Sets the speed the text should automatically scroll at. - * - * @param[in] scrollSpeed The speed of scrolling in pixels per second. + * @brief Get direction of the text from the first line of text, + * @return bool rtl (right to left) is true */ - void SetAutoscrollSpeed( int scrollSpeed ); + CharacterDirection GetAutoScrollDirection() const; /** - * @brief Retrieves the auto scroll speed. + * @brief Get the alignment offset of the first line of text. * - * @return The auto scroll speed in pixels per second. + * @return The alignment offset. */ - int GetAutoScrollSpeed() const; - - /** - * @brief Sets the number of loops the text should scroll. - * - * @param[in] loopCount The number of loops. - */ - void SetAutoScrollLoopCount( int loopCount ); - - /** - * @brief Retrieves the number of loops the text should scroll. - * - * @return The numebr of loops. - */ - int GetAutoScrollLoopCount() const; - - /** - * @brief Sets the gap before text wraps around when scrolling. - * - * @param[in] wrapGap The gap in pixels. - */ - void SetAutoScrollWrapGap( float wrapGap ); - - /** - * @brief Retrieves the gap before text wraps around when scrolling. - * - * @return The gap in pixels. - */ - float GetAutoScrollWrapGap() const; - - /** - * @brief Retrieves the text's autoscroll data. - * - * @return The text's autoscroll data. - */ - const ScrollerData* const GetAutoScrollData(); + float GetAutoScrollLineAlignment() const; /** * @brief Enables the horizontal scrolling. @@ -956,13 +911,6 @@ protected: // Inherit from TextSelectionPopup::TextPopupButtonCallbackInterface. */ virtual void TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Buttons button ); -private: // Inherit from TextScroller - - /** - * @copydoc Text::ScrollerInterface::ScrollingFinished() - */ - virtual void ScrollingFinished(); - private: // Update. /** diff --git a/dali-toolkit/internal/text/text-scroller-data.cpp b/dali-toolkit/internal/text/text-scroller-data.cpp deleted file mode 100644 index d938911..0000000 --- a/dali-toolkit/internal/text/text-scroller-data.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// FILE HEADER -#include - -namespace Dali -{ - -namespace Toolkit -{ - -namespace Text -{ - -const int MINIMUM_SCROLL_SPEED = 1; - -ScrollerData::ScrollerData() -: mScrollSpeed( MINIMUM_SCROLL_SPEED ), - mLoopCount( 1 ), - mWrapGap( 0.f ), - mAlignmentOffset( 0.f ), - mAutoScrollDirectionRTL( false ) -{} - -ScrollerData::~ScrollerData() -{} - -} // namespace Text - -} // namespace Toolkit - -} // namespace Dali diff --git a/dali-toolkit/internal/text/text-scroller-data.h b/dali-toolkit/internal/text/text-scroller-data.h deleted file mode 100644 index 3ba08c9..0000000 --- a/dali-toolkit/internal/text/text-scroller-data.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef DALI_TOOLKIT_TEXT_SCROLLER_DATA_H -#define DALI_TOOLKIT_TEXT_SCROLLER_DATA_H - -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// EXTERNAL INCLUDES -#include - -// INTERNAL INCLUDES -#include - -namespace Dali -{ - -namespace Toolkit -{ - -namespace Text -{ - -extern const int MINIMUM_SCROLL_SPEED; // Speed should be set by Property system. - -/** - * @brief Stores the autoscroll data. - */ -struct ScrollerData -{ - ScrollerData(); - ~ScrollerData(); - - Size mControlSize; ///< The size of the control to scroll within. - Size mOffscreenSize; ///< The size of the sourceActor. - int mScrollSpeed; ///< Speed which text should automatically scroll at. - int mLoopCount; ///< Number of time the text should scroll. - float mWrapGap; ///< Gap before text wraps around when scrolling. - float mAlignmentOffset; ///< The alignment offset of the first line of text to be scrolled. - CharacterDirection mAutoScrollDirectionRTL; ///< Direction of auto scrolling, true if rtl. -}; - -} // namespace Text - -} // namespace Toolkit - -} // namespace Dali - -#endif // DALI_TOOLKIT_TEXT_SCROLLER_H - diff --git a/dali-toolkit/internal/text/text-scroller.cpp b/dali-toolkit/internal/text/text-scroller.cpp index ee1d241..d2f9348 100644 --- a/dali-toolkit/internal/text/text-scroller.cpp +++ b/dali-toolkit/internal/text/text-scroller.cpp @@ -31,7 +31,6 @@ // INTERNAL INCLUDES #include -#include namespace Dali { @@ -39,11 +38,6 @@ namespace Dali namespace Toolkit { -namespace Text -{ -extern const int MINIMUM_SCROLL_SPEED; -} // namespace - namespace { @@ -51,6 +45,8 @@ namespace Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_SCROLLING"); #endif +const int MINIMUM_SCROLL_SPEED = 1; // Speed should be set by Property system. + const char* VERTEX_SHADER_SCROLL = DALI_COMPOSE_SHADER( attribute mediump vec2 aPosition;\n varying highp vec2 vTexCoord;\n @@ -199,6 +195,50 @@ TextScrollerPtr TextScroller::New( ScrollerInterface& scrollerInterface ) return textScroller; } +void TextScroller::SetGap( int gap ) +{ + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetGap gap[%d]\n", gap ); + mWrapGap = static_cast(gap); +} + +int TextScroller::GetGap() const +{ + return static_cast(mWrapGap); +} + +void TextScroller::SetSpeed( int scrollSpeed ) +{ + mScrollSpeed = std::max( MINIMUM_SCROLL_SPEED, scrollSpeed ); +} + +int TextScroller::GetSpeed() const +{ + return mScrollSpeed; +} + +void TextScroller::SetLoopCount( int loopCount ) +{ + if ( loopCount > 0 ) + { + mLoopCount = loopCount; + } + + if ( mScrollAnimation && mScrollAnimation.GetState() == Animation::PLAYING ) + { + if ( loopCount == 0 ) // Request to stop looping + { + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetLoopCount Single loop forced\n" ); + mScrollAnimation.SetLoopCount( 1 ); // As animation already playing this allows the current animation to finish instead of trying to stop mid-way + } + } + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetLoopCount [%d] Status[%s]\n", mLoopCount, (loopCount)?"looping":"stop" ); +} + +int TextScroller::GetLoopCount() const +{ + return mLoopCount; +} + Actor TextScroller::GetSourceCamera() const { return mOffscreenCameraActor; @@ -209,9 +249,11 @@ Actor TextScroller::GetScrollingText() const return mScrollingTextActor; } -TextScroller::TextScroller( ScrollerInterface& scrollerInterface ) -: mScrollerInterface( scrollerInterface ), - mScrollDeltaIndex( Property::INVALID_INDEX ) +TextScroller::TextScroller( ScrollerInterface& scrollerInterface ) : mScrollerInterface( scrollerInterface ), + mScrollDeltaIndex( Property::INVALID_INDEX ), + mScrollSpeed( MINIMUM_SCROLL_SPEED ), + mLoopCount( 1 ), + mWrapGap( 0.0f ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller Default Constructor\n" ); } @@ -221,71 +263,49 @@ TextScroller::~TextScroller() CleanUp(); } -void TextScroller::StartScrolling( Actor sourceActor, - const ScrollerData& data ) +void TextScroller::SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, float alignmentOffset ) { - DALI_LOG_INFO( gLogFilter, - Debug::Verbose, - "TextScroller::StartScrolling controlSize[%f,%f] offscreenSize[%f,%f] direction[%d] alignmentOffset[%f]\n", - data.mControlSize.x, data.mControlSize.y, - data.mOffscreenSize.x, data.mOffscreenSize.y, - data.mAutoScrollDirectionRTL, - data.mAlignmentOffset ); - - FrameBufferImage offscreenRenderTargetForText = FrameBufferImage::New( data.mOffscreenSize.width, data.mOffscreenSize.height, Pixel::RGBA8888 ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters controlSize[%f,%f] offscreenSize[%f,%f] direction[%d] alignmentOffset[%f]\n", + controlSize.x, controlSize.y, offScreenSize.x, offScreenSize.y, direction, alignmentOffset ); + + FrameBufferImage offscreenRenderTargetForText = FrameBufferImage::New( offScreenSize.width, offScreenSize.height, Pixel::RGBA8888 ); Renderer renderer; - CreateCameraActor( data.mOffscreenSize, mOffscreenCameraActor ); + CreateCameraActor( offScreenSize, mOffscreenCameraActor ); CreateRenderer( offscreenRenderTargetForText, renderer ); CreateRenderTask( sourceActor, mOffscreenCameraActor, offscreenRenderTargetForText, mRenderTask ); // Reposition camera to match alignment of target, RTL text has direction=true - if( data.mAutoScrollDirectionRTL ) + if ( direction ) { - mOffscreenCameraActor.SetX( data.mAlignmentOffset + data.mOffscreenSize.width * 0.5f ); + mOffscreenCameraActor.SetX( alignmentOffset + offScreenSize.width*0.5f ); } else { - mOffscreenCameraActor.SetX( data.mOffscreenSize.width * 0.5f ); + mOffscreenCameraActor.SetX( offScreenSize.width * 0.5f ); } - mOffscreenCameraActor.SetY( data.mOffscreenSize.height * 0.5f ); + mOffscreenCameraActor.SetY( offScreenSize.height * 0.5f ); - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters mWrapGap[%f]\n", data.mWrapGap ) + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters mWrapGap[%f]\n", mWrapGap ) mScrollingTextActor = Actor::New(); mScrollingTextActor.AddRenderer( renderer ); - mScrollingTextActor.RegisterProperty( "uTextureSize", data.mOffscreenSize ); - mScrollingTextActor.RegisterProperty( "uRtl", ( data.mAutoScrollDirectionRTL ? 1.f : 0.f ) ); - mScrollingTextActor.RegisterProperty( "uGap", data.mWrapGap ); - mScrollingTextActor.SetSize( data.mControlSize.width, std::min( data.mOffscreenSize.height, data.mControlSize.height ) ); + mScrollingTextActor.RegisterProperty( "uTextureSize", offScreenSize ); + mScrollingTextActor.RegisterProperty( "uRtl", ((direction)?1.0f:0.0f) ); + mScrollingTextActor.RegisterProperty( "uGap", mWrapGap ); + mScrollingTextActor.SetSize( controlSize.width, std::min( offScreenSize.height, controlSize.height ) ); mScrollDeltaIndex = mScrollingTextActor.RegisterProperty( "uDelta", 0.0f ); - float scrollAmount = std::max( data.mOffscreenSize.width + data.mWrapGap, data.mControlSize.width ); - float scrollSpeed = std::max( MINIMUM_SCROLL_SPEED, data.mScrollSpeed ); - float scrollDuration = scrollAmount / scrollSpeed; + float scrollAmount = std::max( offScreenSize.width + mWrapGap, controlSize.width ); + float scrollDuration = scrollAmount / mScrollSpeed; - if( data.mAutoScrollDirectionRTL ) + if ( direction ) { scrollAmount = -scrollAmount; // reverse direction of scrollung } - mScrollAnimation = Animation::New( scrollDuration ); - mScrollAnimation.AnimateTo( Property( mScrollingTextActor, mScrollDeltaIndex ), scrollAmount ); - mScrollAnimation.SetEndAction( Animation::Discard ); - mScrollAnimation.SetLoopCount( data.mLoopCount ); - mScrollAnimation.FinishedSignal().Connect( this, &TextScroller::AutoScrollAnimationFinished ); - mScrollAnimation.Play(); -} - -void TextScroller::StopScrolling() -{ - if( mScrollAnimation && - ( mScrollAnimation.GetState() == Animation::PLAYING ) ) - { - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetLoopCount Single loop forced\n" ); - mScrollAnimation.SetLoopCount( 1 ); // As animation already playing this allows the current animation to finish instead of trying to stop mid-way - } + StartScrolling( scrollAmount, scrollDuration, mLoopCount ); } void TextScroller::AutoScrollAnimationFinished( Dali::Animation& animation ) @@ -295,6 +315,18 @@ void TextScroller::AutoScrollAnimationFinished( Dali::Animation& animation ) mScrollerInterface.ScrollingFinished(); } +void TextScroller::StartScrolling( float scrollAmount, float scrollDuration, int loopCount ) +{ + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::StartScrolling scrollAmount[%f] scrollDuration[%f], loop[%d] speed[%d]\n", scrollAmount, scrollDuration, loopCount, mScrollSpeed ); + + mScrollAnimation = Animation::New( scrollDuration ); + mScrollAnimation.AnimateTo( Property( mScrollingTextActor, mScrollDeltaIndex ), scrollAmount ); + mScrollAnimation.SetEndAction( Animation::Discard ); + mScrollAnimation.SetLoopCount( loopCount ); + mScrollAnimation.FinishedSignal().Connect( this, &TextScroller::AutoScrollAnimationFinished ); + mScrollAnimation.Play(); +} + void TextScroller::CleanUp() { if ( Stage::IsInstalled() ) diff --git a/dali-toolkit/internal/text/text-scroller.h b/dali-toolkit/internal/text/text-scroller.h index a40be3f..17824b6 100644 --- a/dali-toolkit/internal/text/text-scroller.h +++ b/dali-toolkit/internal/text/text-scroller.h @@ -37,7 +37,6 @@ namespace Text class TextScroller; class ScrollerInterface; -struct ScrollerData; typedef IntrusivePtr TextScrollerPtr; @@ -47,6 +46,7 @@ typedef IntrusivePtr TextScrollerPtr; class TextScroller : public RefObject, public ConnectionTracker { public: + /** * @brief Text Scrolling helper, used to automatically scroll text, SetParameters should be called before scrolling is needed. * CleanUp removes the Scrolling actors from stage whilst keeping the Scroller object alive and preserving Speed, Gap and Loop count. @@ -56,19 +56,52 @@ public: static TextScrollerPtr New( ScrollerInterface& scrollerInterface ); /** - * @brief Starts the text scrolling. + * @brief Set parameters relating to source required for scrolling * * @param[in] sourceActor source actor to be scrolled - * @param[in] data Parameters needed to set up the text scrolling. + * @param[in] controlSize size of the control to scroll within + * @param[in] offScreenSize size of the sourceActor + * @param[in] direction text direction true for right to left text + * @param[in] alignmentOffset alignment of source text * */ - void StartScrolling( Actor sourceActor, - const ScrollerData& data ); + void SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, float alignmentOffset ); + + /** + * @brief Set the gap distance to elapse before the text wraps around + * @param[in] gap distance to elapse + */ + void SetGap( int gap ); + + /** + * @brief Get the distance before scrolling wraps + * @return gap distance to elapse + */ + int GetGap() const; + + /** + * @brief Set speed the text should scroll + * @param[in] scrollSpeed pixels per second + */ + void SetSpeed( int scrollSpeed ); /** - * @brief Stops the text scrolling. + * @brief Get the speed of text scrolling + * @return speed in pixels per second */ - void StopScrolling(); + int GetSpeed() const; + + /** + * @brief Set the number of times the text scrolling should loop, can stop current scrolling by passing in 0; + * @param[in] loopCount number of times the scrolled text should loop, 0 to stop scrolling + */ + void SetLoopCount( int loopCount ); + + /** + * @brief Get the number of loops + * @return int number of loops + */ + int GetLoopCount() const; /** * @brief Get the camera used to look at source, should be added to the parent of target actor. @@ -107,6 +140,14 @@ private: // Implementation void AutoScrollAnimationFinished( Dali::Animation& animation ); /** + * @brief variables required to set up scrolling animation + * @param[in] scrollAmount distance to animate text for the given duration + * @param[in] scrollDuration duration of aninmation + * @param[in] loopCount number of times to loop the scrolling text + */ + void StartScrolling( float scrollAmount, float scrollDuration, int loopCount ); + + /** * @brief When scrolling ended, the actors are cleaned up so no longer staged. */ void CleanUp(); @@ -120,6 +161,10 @@ private: Property::Index mScrollDeltaIndex; // Property used by shader to represent distance to scroll Animation mScrollAnimation; // Animation used to update the mScrollDeltaIndex + int mScrollSpeed; ///< Speed which text should automatically scroll at + int mLoopCount; ///< Number of time the text should scroll + float mWrapGap; ///< Gap before text wraps around when scrolling + }; // TextScroller class } // namespace Text diff --git a/dali-toolkit/internal/visuals/text/text-visual.cpp b/dali-toolkit/internal/visuals/text/text-visual.cpp index f7c4f24..baba744 100644 --- a/dali-toolkit/internal/visuals/text/text-visual.cpp +++ b/dali-toolkit/internal/visuals/text/text-visual.cpp @@ -162,14 +162,6 @@ TextVisualPtr TextVisual::New( VisualFactoryCache& factoryCache ) return new TextVisual( factoryCache ); } -void TextVisual::SetTextControlInterface( Text::ControlInterface* controlInterface ) -{ - if( mController ) - { - mController->SetTextControlInterface( controlInterface ); - } -} - void TextVisual::SetSize( const Vector2& size ) { const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size ); @@ -226,14 +218,6 @@ void TextVisual::DoCreatePropertyMap( Property::Map& map ) const map.Insert( Toolkit::TextVisual::Property::ENABLE_MARKUP, mController->IsMarkupProcessorEnabled() ); - map.Insert( Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL, mController->IsAutoScrollEnabled() ); - - map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED, mController->GetAutoScrollSpeed() ); - - map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT, mController->GetAutoScrollLoopCount() ); - - map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_GAP, mController->GetAutoScrollWrapGap() ); - map.Insert( Toolkit::TextVisual::Property::LINE_SPACING, mController->GetDefaultLineSpacing() ); GetUnderlineProperties( mController, value, Text::EffectStyle::DEFAULT ); @@ -501,47 +485,22 @@ void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Propert } case Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL: { - const bool enableAutoScroll = propertyValue.Get(); - - // If request to auto scroll is the same as current state then do nothing. - if( enableAutoScroll != mController->IsAutoScrollEnabled() ) - { - // If request is disable (false) and auto scrolling is enabled then need to stop it - if( !enableAutoScroll ) - { - StopTextAutoScrolling(); // Causes the current animation to finish playing. - } - // If request is enable (true) then start autoscroll as not already running - else - { - mController->GetLayoutEngine().SetTextEllipsisEnabled( false ); - mController->SetAutoScrollEnabled( enableAutoScroll ); - mController->RequestRelayout(); - } - } + // nothing to do. break; } case Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED: { - mController->SetAutoscrollSpeed( propertyValue.Get() ); + // nothing to do. break; } case Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT: { - const int loopCount = propertyValue.Get(); - if( loopCount > 0 ) - { - mController->SetAutoScrollLoopCount( loopCount ); - } - else - { - StopTextAutoScrolling(); // Causes the current animation to finish playing. - } + // nothing to do. break; } case Toolkit::TextVisual::Property::AUTO_SCROLL_GAP: { - mController->SetAutoScrollWrapGap( propertyValue.Get() ); + // nothing to do. break; } case Toolkit::TextVisual::Property::LINE_SPACING: @@ -751,22 +710,22 @@ Dali::Property::Value TextVisual::DoGetProperty( Dali::Property::Index index ) } case Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL: { - value = mController->IsAutoScrollEnabled(); + // nothing to do. break; } case Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED: { - value = mController->GetAutoScrollSpeed(); + // nothing to do. break; } case Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT: { - value = mController->GetAutoScrollLoopCount(); + // nothing to do. break; } case Toolkit::TextVisual::Property::AUTO_SCROLL_GAP: { - value = mController->GetAutoScrollWrapGap(); + // nothing to do. break; } case Toolkit::TextVisual::Property::LINE_SPACING: @@ -837,46 +796,6 @@ void TextVisual::RenderText() self.Add( renderableActor ); } mRenderableActor = renderableActor; - - if( mController->IsAutoScrollEnabled() ) - { - SetUpAutoScrolling(); - } - } -} - -void TextVisual::StopTextAutoScrolling() -{ - if( mTextScroller ) - { - mTextScroller->StopScrolling(); - } -} - -void TextVisual::SetUpAutoScrolling() -{ - Actor self = mSelf.GetHandle(); - if( !self ) - { - // Nothing to do if the handle is not initialized. - return; - } - - const Text::ScrollerData* const data = mController->GetAutoScrollData(); - - if( NULL != data ) - { - if( !mTextScroller ) - { - // If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults - mTextScroller = Text::TextScroller::New( *mController ); - } - - mTextScroller->StartScrolling( mRenderableActor, - *data ); - - self.Add( mTextScroller->GetScrollingText() ); - self.Add( mTextScroller->GetSourceCamera() ); } } diff --git a/dali-toolkit/internal/visuals/text/text-visual.h b/dali-toolkit/internal/visuals/text/text-visual.h index e1a4f80..dd1abf6 100644 --- a/dali-toolkit/internal/visuals/text/text-visual.h +++ b/dali-toolkit/internal/visuals/text/text-visual.h @@ -26,7 +26,6 @@ #include #include #include -#include namespace Dali { @@ -80,12 +79,6 @@ public: */ static TextVisualPtr New( VisualFactoryCache& factoryCache ); - /** - * @brief Sets the text control interface which is needed to communicate with a control. - * @param[in] controlInterface Pointer to the control-interface. - */ - void SetTextControlInterface( Text::ControlInterface* controlInterface ); - public: // from Visual::Base /** @@ -157,22 +150,11 @@ private: */ void RenderText(); - /** - * @brief Stops the text auto scroll. - */ - void StopTextAutoScrolling(); - - /** - * @brief Set up Autoscrolling. - */ - void SetUpAutoScrolling(); - private: Text::ControllerPtr mController; ///< The text's controller. WeakHandle mSelf; Text::RendererPtr mRenderer; - Text::TextScrollerPtr mTextScroller; Actor mRenderableActor; int mRenderingBackend; diff --git a/docs/content/images/creating-custom-controls/control-handle-body.png b/docs/content/images/creating-custom-controls/control-handle-body.png index 4349789..14cfeb2 100644 Binary files a/docs/content/images/creating-custom-controls/control-handle-body.png and b/docs/content/images/creating-custom-controls/control-handle-body.png differ diff --git a/docs/content/shared-javascript-and-cpp-documentation/creating-custom-controls.md b/docs/content/shared-javascript-and-cpp-documentation/creating-custom-controls.md index 27239b3..82345bb 100644 --- a/docs/content/shared-javascript-and-cpp-documentation/creating-custom-controls.md +++ b/docs/content/shared-javascript-and-cpp-documentation/creating-custom-controls.md @@ -13,13 +13,26 @@ Custom controls are created using the [handle/body idiom](@ref handle-body-idiom ![ ](../assets/img/creating-custom-controls/control-handle-body.png) ![ ](creating-custom-controls/control-handle-body.png) +Namespaces are important ++ The handle & body classes should have the same name but in different namespaces ++ TypeRegistry relies on this convention ++ Here our custom control requires + + MyControl + + Internal::MyControl + ### General Guidelines: + Try to avoid adding C++ APIs as they become difficult to maintain. + Use **properties** as much as possible as Controls should be data driven. + These controls will be used through JavaScript and JSON files so need to be compatible. -+ Bear in mind that the Control is required to update when the properties change, not just the first time they are set (to deal with style change). ++ Bear in mind that the Control can be updated when the properties change (e.g. style change) + + Ensure control deals with these property changes gracefully + + Not just the first time they are set ++ Use Visuals rather than creating several child Actors + + DALi rendering pipeline more efficient + Accessibility actions should be considered when designing the Control. + Consider using signals if the application needs to be react to changes in the control state. ++ Use of Gestures should be preferred over analysing raw touch events ++ Check if you need to chain up to base class if overriding certain methods ___________________________________________________________________________________________________ @@ -125,7 +138,8 @@ This should be overridden by the custom ui control. // C++ void MyUIControlImpl::OnInitialize() { - // Create visuals, register events etc. + // Create visuals using the VisualFactory, register events etc. + // Register any created visuals with Control base class } ~~~ ___________________________________________________________________________________________________ @@ -134,13 +148,14 @@ ________________________________________________________________________________ Dali::Toolkit::Internal::Control provides several behaviours which are specified through its constructor (@ref Dali::Toolkit::Internal::Control::Control()). -| Behaviour | Description | -|--------------------------------------|-------------------------------------------------------------------------| -| ACTOR_BEHAVIOUR_NONE | No behaviour required. | -| REQUIRES_HOVER_EVENTS | If our control requires [hover events](@ref creating-controls-events). | -| REQUIRES_WHEEL_EVENTS | If our control requires [wheel events](@ref creating-controls-events). | -| REQUIRES_STYLE_CHANGE_SIGNALS | True if need to monitor style change signals such as Theme/Font change. | -| REQUIRES_KEYBOARD_NAVIGATION_SUPPORT | True if need to support keyboard navigation. | +| Behaviour | Description | +|--------------------------------------|----------------------------------------------------------------------------------------------------------------| +| CONTROL_BEHAVIOUR_DEFAULT | Default behavior (size negotiation is on, style change is monitored, event callbacks are not called. | +| DISABLE_SIZE_NEGOTIATION | If our control does not need size negotiation, i.e. control will be skipped by the size negotiation algorithm. | +| REQUIRES_HOVER_EVENTS | If our control requires [hover events](@ref creating-controls-events). | +| REQUIRES_WHEEL_EVENTS | If our control requires [wheel events](@ref creating-controls-events). | +| DISABLE_STYLE_CHANGE_SIGNALS | True if control should not monitor style change signals such as Theme/Font change. | +| REQUIRES_KEYBOARD_NAVIGATION_SUPPORT | True if need to support keyboard navigation. | ___________________________________________________________________________________________________ ### Touch, Hover & Wheel Events {#creating-controls-events} @@ -373,31 +388,62 @@ void MyUIControlImpl::OnStageDisconnection() ___________________________________________________________________________________________________ -### Size {#creating-controls-size} +### Size Negotiation {#creating-controls-size-negotiation} -Methods are provided that can be overridden if notification is required when our control's size is manipulated. -An up call to the Control class is necessary if these methods are overridden. +The following methods must be overridden for size negotiation to work correctly with a custom control. ~~~{.cpp} // C++ -void MyUIControlImpl::OnSizeSet( const Vector3& targetSize ) +Vector3 MyUIControlImpl::GetNaturalSize() +{ + // Return the natural size of the control + // This depends on our layout + // If we have one visual, then we can return the natural size of that + // If we have more visuals, then we need to calculate their positions within our control and work out the overall size we would like our control to be + + // After working out the natural size of visuals that belong to this control, + // should also chain up to ensure other visuals belonging to the base class are + // also taken into account: + Vector2 baseSize = Control::GetNaturalSize(); // returns the size of the background. +} +~~~ +~~~{.cpp} +// C++ +float MyUIControlImpl::GetHeightForWidth( float width ) { - // Up call to Control - Control::OnSizeSet( targetSize ); + // Called by the size negotiation algorithm if we have a fixed width + // We should calculate the height we would like our control to be for that width + + // Should also chain up to determine the base class's preferred height: + float baseHeight = Control::GetHeightForWidth( width ); - // Do any other operations required upon size set } ~~~ ~~~{.cpp} // C++ -void MyUIControlImpl::OnSizeAnimation( Animation& animation, const Vector3& targetSize ) +float MyUIControlImpl::GetWidthForHeight( float height ) { - // Up call to Control - Control::OnSizeAnimation( animation, targetSize ); + // Called by the size negotiation algorithm if we have a fixed height + // We should calculate the width we would like our control to be for that height - // Do any other operations required upon size animation + // Should also chain up to determine the base class's preferred width: + float baseWidth = Control::GetWidth( height ); +} +~~~ +~~~{.cpp} +// C++ +void MyUIControlImpl::OnRelayout( const Vector2& size, RelayoutContainer& container ) +{ + // The size is what we have been given and what our control needs to fit into + // Here, we need to set the position and the size of our visuals + // If we have other controls/actors as children + // - Add the control/actor to the container paired with the size required + // - To ensure this works, you need to set up the control with a relayout policy of USE_ASSIGNED_SIZE + // - DO NOT CALL SetSize on this control: This will trigger another size negotiation calculation + // DO NOT chain up to base class. } ~~~ +More information on size negotiation can be found [here](@ref size-negotiation-controls). ___________________________________________________________________________________________________ diff --git a/docs/content/shared-javascript-and-cpp-documentation/visuals.md b/docs/content/shared-javascript-and-cpp-documentation/visuals.md index 3ae2c31..457d8e1 100644 --- a/docs/content/shared-javascript-and-cpp-documentation/visuals.md +++ b/docs/content/shared-javascript-and-cpp-documentation/visuals.md @@ -6,7 +6,7 @@ Visuals provide reusable rendering logic which can be used by all controls. This means that custom controls do not have to create actors, they can just reuse the existing visuals which increases performance. -Visuals reuse geometry, shaders etc. across controls and manages the renderer and material to exist only when the control is on-stage. +Visuals reuse geometry, shaders etc. across controls and manages the renderer and texture to exist only when the control is on-stage. Additionally, they respond to actor size and color change, while also providing clipping at the renderer level. DALi provides the following visuals: @@ -22,11 +22,71 @@ Controls can provide properties that allow users to specify the visual type ( vi Setting visual properties are done via a property map. The **visualType** field in the property map specifies the visual to use/create. This is required to avoid ambiguity as multiple visuals may be capable of rendering the same contents. + +Visuals have a **transform** field in the property map to allow layouting within a control. If this field is not set, then the visual defaults to filling the control. The **transform** field has a property map with the following keys: + +| Property | String | Type | Required | Description | +|-------------------------------------------------|----------|:-------:|:--------:|---------------------------| +| Dali::Toolkit::Visual::Transform::Property::OFFSET | offset | VECTOR2 | No | The offset of the visual. | +| Dali::Toolkit::Visual::Transform::Property::SIZE | size | VECTOR2 | No | The size of the visual. | +| Dali::Toolkit::Visual::Transform::Property::OFFSET_SIZE_MODE | offsetSizeMode | VECTOR4 | No | Whether the size or offset components are Relative or Absolute [More info](@ref offset-size-mode)| +| Dali::Toolkit::Visual::Transform::Property::ORIGIN | origin | INTEGER or STRING | No | The origin of the visual within the control's area. [More info](@ref align-type)] | +| Dali::Toolkit::Visual::Transform::Property::ANCHOR_POINT | anchorPoint | INTEGER or STRING | No | The anchor point of the visual. [More info](@ref align-type)| + + +## Offset & size modes {#offset-size-mode} + +The offset and size modes can be either Relative or Absolute. The offset modes are in the x and y components of the offsetSizeMode property, and map to the offset's x and y components respectively. The size modes are in the z and w components of the offsetSizeMode property, and map to the size's x and y components, respectively. + +A mode value of 0 represents a Relative mode, in which case the size or offset value represents a ratio of the control's size. A mode value of 1 represents an Absolute mode, in which case the size or offset value represents world units (pixels). + +For example, an offsetSizeMode of [0, 0, 1, 1], an offset of (0, 0.25) and a size of (20, 20) means the visual will be 20 pixels by 20 pixels in size, positioned 25% above the center of the control. + + +## Alignment {#align-type} +| Enumeration | String | Description | +|------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------| +| Dali::Toolkit::Align::TOP_BEGIN | TOP_BEGIN | Aligns to the top of the vertical axis and the beginning of the horizontal axis (The left or right edge in Left-To-Right or Right-to-Left layouts, respectively) | +| Dali::Toolkit::Align::TOP_CENTER | TOP_CENTER | Aligns to the top of the vertical axis and the center of the horizontal axis | +| Dali::Toolkit::Align::TOP_END | TOP_END | Aligns to the top of the vertical axis and end of the horizontal axis (The right or left edge in Left-To-Right or Right-to-Left layouts, respectively) | +| Dali::Toolkit::Align::CENTER_BEGIN | CENTER_BEGIN | Aligns to the center of the vertical axis and the beginning of the horizontal axis| +| Dali::Toolkit::Align::CENTER | CENTER | Aligns to the center of the control | +| Dali::Toolkit::Align::CENTER_END | CENTER_END | Aligns to the center of the vertical axis and end of the horizontal axis | +| Dali::Toolkit::Align::BOTTOM_BEGIN | BOTTOM_BEGIN | Aligns to the bottom of the vertical axis and the beginning of the horizontal axis| +| Dali::Toolkit::Align::BOTTOM_CENTER | BOTTOM_CENTER | Aligns to the bottom of the vertical axis and the center of the horizontal axis +| Dali::Toolkit::Align::BOTTOM_END | BOTTOM_END | Aligns to the bottom of the vertical axis and end of the horizontal axis | + +Visuals also have a custom **shader** property. Whilst it's possible to change the shader, please note that some visuals rely on the vertex shader to perform certain functions. For example, the NPatch visual uses the vertex shader to perform the stretching. The **shader** property is a Property::Map with the following keys: + + +| Property | String | Type | Required | Description | +|-------------------------------------------------|----------|:-------:|:--------:|---------------------------| +| Dali::Toolkit::Visual::Shader::Property::VERTEX_SHADER | vertexShader | STRING | No | The vertex shader code. | +| Dali::Toolkit::Visual::Shader::Property::FRAGMENT_SHADER | fragmentShader | STRING | No | The fragment shader code. | +| Dali::Toolkit::Visual::Shader::Property::SUBDIVIDE_GRID_X | subdivideGridX | INTEGER | No | How to subdivide the grid along the X-Axis. Defaults to 1 | +| Dali::Toolkit::Visual::Shader::Property::SUBDIVIDE_GRID_Y | subdivideGridY | INTEGER | No | How to subdivide the grid along the Y-Axis. Defaults to 1 | +| Dali::Toolkit::Visual::Shader::Property::HINTS | hints | INTEGER or ARRAY of STRING | No | Shader hints bitmask [More info](@ref shader-hints) | + +## Shader hints {#shader-hints} + +This is a bitmask giving hints to the renderer about what the shader does, in order to help the rendering system optimise it's rendering. + +The bitmask can have the following values: + +| Value | Description | +|-------------------------------------------|----------------------------------------| +| Dali::Shader::Hint::NONE | No hints | +| Dali::Shader::Hint::OUTPUT_IS_TRANSPARENT | Might generate transparent alpha from opaque inputs | +| Dali::Shader::Hint::MODIFIES_GEOMETRY | Might change the position of vertices - this disables culling optimizations | + + +See also Dali::Shader::Hint::Value enumeration. + ___________________________________________________________________________________________________ ## Color Visual {#color-visual} -Renders a solid color to the control's quad. +Renders a color to the visual's quad geometry. ![ ](../assets/img/visuals/color-visual.png) ![ ](visuals/color-visual.png) @@ -37,7 +97,7 @@ Renders a solid color to the control's quad. | Property | String | Type | Required | Description | |-------------------------------------------------|----------|:-------:|:--------:|---------------------------| -| Dali::Toolkit::ColorVisual::Property::MIX_COLOR | mixColor | VECTOR4 | Yes | The solid color required. | +| Dali::Toolkit::ColorVisual::Property::MIX_COLOR | mixColor | VECTOR4 | Yes | The color required. | ### Usage @@ -66,7 +126,7 @@ ________________________________________________________________________________ ## Gradient Visual {#gradient-visual} -Renders a smooth transition of colors to the control's quad. +Renders a smooth transition of colors to the visual's quad geometry. Both Linear and Radial gradients are supported. @@ -108,9 +168,9 @@ Indicates what happens if the gradient starts or ends inside the bounds of the t | Enumeration | String | Description | |------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------| -| Dali::Toolkit::GradientVisual::SpreadMethod::PAD | PAD | *Default*. Uses the terminal colors of the gradient to fill the remainder of the quad. | -| Dali::Toolkit::GradientVisual::SpreadMethod::REFLECT | REFLECT | Reflect the gradient pattern start-to-end, end-to-start, start-to-end etc. until the quad is filled. | -| Dali::Toolkit::GradientVisual::SpreadMethod::REPEAT | REPEAT | Repeat the gradient pattern start-to-end, start-to-end, start-to-end etc. until the quad is filled. | +| Dali::Toolkit::GradientVisual::SpreadMethod::PAD | PAD | *Default*. Uses the terminal colors of the gradient to fill the remainder of the quad geometry. | +| Dali::Toolkit::GradientVisual::SpreadMethod::REFLECT | REFLECT | Reflect the gradient pattern start-to-end, end-to-start, start-to-end etc. until the quad geometry is filled. | +| Dali::Toolkit::GradientVisual::SpreadMethod::REPEAT | REPEAT | Repeat the gradient pattern start-to-end, start-to-end, start-to-end etc. until the quad geometry is filled. | ### Usage @@ -215,7 +275,7 @@ ________________________________________________________________________________ ## Image Visual {#image-visuals} -Renders an image into the control's quad. +Renders an image into the visual's geometry. Depending on the extension of the image, a different visual is provided to render the image onto the screen. @@ -227,7 +287,7 @@ ___________________________ ### Normal {#image-visual} -Renders a raster image ( jpg, png etc.) into the control's quad. +Renders a raster image ( jpg, png etc.) into the visual's quad geometry. ![ ](../assets/img/visuals/image-visual.png) ![ ](visuals/image-visual.png) @@ -271,7 +331,7 @@ ________________________________________________________________________________ ### N-Patch {#n-patch-visual} -Renders an n-patch or a 9-patch image into the control's quad. +Renders an n-patch or a 9-patch image. Uses non-quad geometry. Both geometry and texture are cached to reduce memory consumption if the same n-patch image is used elsewhere. ![ ](../assets/img/visuals/n-patch-visual.png) ![ ](visuals/n-patch-visual.png) @@ -314,7 +374,7 @@ ________________________________________________________________________________ ### SVG {#svg-visual} -Renders a svg image into the control's quad. +Renders a svg image into the visual's quad geometry. #### Features: SVG Tiny 1.2 specification @@ -384,7 +444,7 @@ ________________________________________________________________________________ ## Border Visual {#border-visual} -Renders a solid color as an internal border to the control's quad. +Renders a color as an internal border to the visual's geometry. ![ ](../assets/img/visuals/border-visual.png) ![ ](visuals/border-visual.png) @@ -611,7 +671,7 @@ ________________________________________________________________________________ ## Wireframe Visual {#wireframe-visual} -Renders a wireframe around a control's quad. +Renders a wireframe around a quad geometry. Is mainly used for debugging and is the visual that replaces all other visuals when [Visual Debug Rendering](@ref debugrendering) is turned on. ![ ](../assets/img/visuals/wireframe-visual.png)