const char* const PROPERTY_NAME_UNDERLINE_COLOR = "underlineColor";
const char* const PROPERTY_NAME_UNDERLINE_HEIGHT = "underlineHeight";
const char* const PROPERTY_NAME_ENABLE_MARKUP = "enableMarkup";
+const char* const PROPERTY_NAME_ENABLE_AUTO_SCROLL = "enableAutoScroll";
+const char* const PROPERTY_NAME_ENABLE_AUTO_SCROLL_SPEED = "autoScrollSpeed";
+const char* const PROPERTY_NAME_ENABLE_AUTO_SCROLL_LOOPS = "autoScrollLoopCount";
+const char* const PROPERTY_NAME_ENABLE_AUTO_SCROLL_GAP = "autoScrollGap";
const int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_UNDERLINE_COLOR ) == TextLabel::Property::UNDERLINE_COLOR );
DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_UNDERLINE_HEIGHT) == TextLabel::Property::UNDERLINE_HEIGHT );
DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_ENABLE_MARKUP) == TextLabel::Property::ENABLE_MARKUP );
+ DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_ENABLE_AUTO_SCROLL ) == TextLabel::Property::ENABLE_AUTO_SCROLL );
+ DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_ENABLE_AUTO_SCROLL_SPEED ) == TextLabel::Property::AUTO_SCROLL_SPEED );
+ DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_ENABLE_AUTO_SCROLL_LOOPS ) == TextLabel::Property::AUTO_SCROLL_LOOP_COUNT );
+ DALI_TEST_CHECK( label.GetPropertyIndex( PROPERTY_NAME_ENABLE_AUTO_SCROLL_GAP ) == TextLabel::Property::AUTO_SCROLL_GAP );
END_TEST;
}
label.SetProperty( TextLabel::Property::ENABLE_MARKUP, true );
DALI_TEST_CHECK( label.GetProperty<bool>( TextLabel::Property::ENABLE_MARKUP ) );
+ // Check autoscroll properties
+ const int SCROLL_SPEED = 80;
+ const int SCROLL_LOOPS = 4;
+ const float SCROLL_GAP = 50.0f;
+ label.SetProperty( TextLabel::Property::MULTI_LINE, false ); // Autoscroll only supported in single line
+ DALI_TEST_CHECK( !label.GetProperty<bool>( TextLabel::Property::ENABLE_AUTO_SCROLL ) );
+ label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, true );
+ DALI_TEST_CHECK( label.GetProperty<bool>( TextLabel::Property::ENABLE_AUTO_SCROLL ) );
+ label.SetProperty( TextLabel::Property::AUTO_SCROLL_SPEED, SCROLL_SPEED );
+ DALI_TEST_EQUALS( SCROLL_SPEED, label.GetProperty<int>( TextLabel::Property::AUTO_SCROLL_SPEED ), TEST_LOCATION );
+ label.SetProperty( TextLabel::Property::AUTO_SCROLL_LOOP_COUNT, SCROLL_LOOPS );
+ DALI_TEST_EQUALS( SCROLL_LOOPS, label.GetProperty<int>( TextLabel::Property::AUTO_SCROLL_LOOP_COUNT ), TEST_LOCATION );
+ label.SetProperty( TextLabel::Property::AUTO_SCROLL_GAP, SCROLL_GAP );
+ DALI_TEST_EQUALS( SCROLL_GAP, label.GetProperty<float>( TextLabel::Property::AUTO_SCROLL_GAP ), TEST_LOCATION );
END_TEST;
}
END_TEST;
}
+int UtcDaliToolkitTextlabelScrollingP(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextLabelScrollingP");
+ TextLabel label = TextLabel::New("Some text to scroll");
+ DALI_TEST_CHECK( label );
+ // Avoid a crash when core load gl resources.
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+ Stage::GetCurrent().Add( label );
+ // Turn on all the effects
+ label.SetProperty( TextLabel::Property::MULTI_LINE, false );
+ label.SetProperty( TextLabel::Property::AUTO_SCROLL_GAP, 50.0f );
+ label.SetProperty( TextLabel::Property::AUTO_SCROLL_LOOP_COUNT, 3 );
+ label.SetProperty( TextLabel::Property::AUTO_SCROLL_SPEED, 80.0f);
+
+ try
+ {
+ // Render some text with the shared atlas backend
+ label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, true );
+ application.SendNotification();
+ application.Render();
+ }
+ catch( ... )
+ {
+ tet_result(TET_FAIL);
+ }
+
+ END_TEST;
+}
#include <dali-toolkit/internal/text/rendering/text-backend.h>
#include <dali-toolkit/internal/text/text-font-style.h>
#include <dali-toolkit/internal/text/text-view.h>
+#include <dali-toolkit/internal/text/text-definitions.h>
#include <dali-toolkit/internal/styling/style-manager-impl.h>
using Dali::Toolkit::Text::LayoutEngine;
namespace
{
-#if defined(DEBUG_ENABLED)
- Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
+#if defined ( DEBUG_ENABLED )
+ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
#endif
const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
// Setup properties, signals and actions using the type-registry.
DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextLabel, Toolkit::Control, Create );
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "renderingBackend", INTEGER, RENDERING_BACKEND )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "text", STRING, TEXT )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontFamily", STRING, FONT_FAMILY )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontStyle", STRING, FONT_STYLE )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "pointSize", FLOAT, POINT_SIZE )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "multiLine", BOOLEAN, MULTI_LINE )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "horizontalAlignment", STRING, HORIZONTAL_ALIGNMENT )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "verticalAlignment", STRING, VERTICAL_ALIGNMENT )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "textColor", VECTOR4, TEXT_COLOR )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "shadowOffset", VECTOR2, SHADOW_OFFSET )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "shadowColor", VECTOR4, SHADOW_COLOR )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underlineEnabled", BOOLEAN, UNDERLINE_ENABLED )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underlineColor", VECTOR4, UNDERLINE_COLOR )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underlineHeight", FLOAT, UNDERLINE_HEIGHT )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "enableMarkup", BOOLEAN, ENABLE_MARKUP )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "renderingBackend", INTEGER, RENDERING_BACKEND )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "text", STRING, TEXT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontFamily", STRING, FONT_FAMILY )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "fontStyle", STRING, FONT_STYLE )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "pointSize", FLOAT, POINT_SIZE )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "multiLine", BOOLEAN, MULTI_LINE )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "horizontalAlignment", STRING, HORIZONTAL_ALIGNMENT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "verticalAlignment", STRING, VERTICAL_ALIGNMENT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "textColor", VECTOR4, TEXT_COLOR )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "shadowOffset", VECTOR2, SHADOW_OFFSET )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "shadowColor", VECTOR4, SHADOW_COLOR )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underlineEnabled", BOOLEAN, UNDERLINE_ENABLED )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underlineColor", VECTOR4, UNDERLINE_COLOR )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "underlineHeight", FLOAT, UNDERLINE_HEIGHT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "enableMarkup", BOOLEAN, ENABLE_MARKUP )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "enableAutoScroll", BOOLEAN, ENABLE_AUTO_SCROLL )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollSpeed", INTEGER, AUTO_SCROLL_SPEED )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollLoopCount", INTEGER, AUTO_SCROLL_LOOP_COUNT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "autoScrollGap", FLOAT, AUTO_SCROLL_GAP )
DALI_TYPE_REGISTRATION_END()
+
+
} // namespace
Toolkit::TextLabel TextLabel::New()
{
const std::string fontFamily = value.Get< std::string >();
- DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetProperty Property::FONT_FAMILY newFont(%s)\n", fontFamily.c_str() );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::SetProperty Property::FONT_FAMILY newFont(%s)\n", fontFamily.c_str() );
impl.mController->SetDefaultFontFamily( fontFamily );
}
break;
}
break;
}
+ case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL:
+ {
+ if( impl.mController )
+ {
+ const bool enableAutoScroll = value.Get<bool>();
+ // 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<int>() );
+ break;
+ }
+ case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT:
+ {
+ if( !impl.mTextScroller )
+ {
+ impl.mTextScroller = Text::TextScroller::New( impl );
+ }
+ impl.mTextScroller->SetLoopCount( value.Get<int>() );
+ break;
+ }
+ case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP:
+ {
+ if( !impl.mTextScroller )
+ {
+ impl.mTextScroller = Text::TextScroller::New( impl );
+ }
+ impl.mTextScroller->SetGap( value.Get<float>() );
+ break;
+ }
}
}
}
}
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 = impl.mTextScroller->GetLoopCount();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP:
+ {
+ TextLabel& impl( GetImpl( label ) );
+ if ( impl.mTextScroller )
+ {
+ value = impl.mTextScroller->GetGap();
+ }
+ break;
+ }
}
}
// Enable the text ellipsis.
LayoutEngine& engine = mController->GetLayoutEngine();
- engine.SetTextEllipsisEnabled( true );
+ 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::OnRelayout( const Vector2& size, RelayoutContainer& container )
{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnRelayout\n" );
+
if( mController->Relayout( size ) ||
!mRenderer )
{
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 );
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 Vector2& alignmentOffset = mController->GetAlignmentOffset();
+ const Text::CharacterDirection direction = mController->GetAutoScrollDirection();
+
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling alignmentOffset[%f] offScreenSize[%f]\n", alignmentOffset.x, offScreenSize.width);
+
+ 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 )
// Pure Virtual from TextController Interface, only needed when inputting text
}
+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( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
#include <dali-toolkit/internal/text/text-controller.h>
+#include <dali-toolkit/internal/text/text-scroller-interface.h>
#include <dali-toolkit/internal/text/rendering/text-renderer.h>
+#include <dali-toolkit/internal/text/text-scroller.h>
namespace Dali
{
/**
* @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:
*/
virtual void MaxLengthReached();
+private: // from TextScroller
+
+ /**
+ * @copydoc Text::ScrollerInterface::ScrollingFinished()
+ */
+ virtual void ScrollingFinished();
+
private: // Implementation
/**
*/
void RenderText();
+ /**
+ * @brief Set up Autoscrolling
+ */
+ void SetUpAutoScrolling();
+
private: // Data
Text::ControllerPtr mController;
Text::RendererPtr mRenderer;
+ Text::TextScrollerPtr mTextScroller;
Actor mRenderableActor;
int mRenderingBackend;
bool mHasBeenStaged:1;
$(toolkit_src_dir)/text/text-controller-impl.cpp \
$(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-interface.cpp \
$(toolkit_src_dir)/text/text-view.cpp \
$(toolkit_src_dir)/text/text-view-interface.cpp \
$(toolkit_src_dir)/text/visual-model-impl.cpp \
LayoutEngine::Layout LayoutEngine::GetLayout() const
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "GetLayout[%d]\n", mImpl->mLayout);
return mImpl->mLayout;
}
void LayoutEngine::SetTextEllipsisEnabled( bool enabled )
{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "-->LayoutEngine::SetTextEllipsisEnabled[%s]\n", (enabled)?"true":"false" );
mImpl->mEllipsisEnabled = enabled;
}
namespace
{
#if defined(DEBUG_ENABLED)
- Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_RENDERING");
+ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_RENDERING");
#endif
const float ZERO( 0.0f );
renderer.SetProperty( Dali::Renderer::Property::DEPTH_INDEX, depthIndex - 1 );
containerActor.Add( shadowActor );
containerActor.Add( actor );
+#if defined(DEBUG_ENABLED)
+ containerActor.SetName("TextContainer");
+#endif
actor = containerActor;
}
}
// Keep all of the origins aligned
actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
-
actor.SetSize( actorSize );
actor.RegisterProperty("uOffset", Vector2::ZERO );
return actor;
Actor AtlasRenderer::Render( Text::ViewInterface& view, int depth )
{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Text::AtlasRenderer::Render()\n" );
+
UnparentAndReset( mImpl->mActor );
Length numberOfGlyphs = view.GetNumberOfGlyphs();
mMaximumNumberOfCharacters( 50u ),
mRecalculateNaturalSize( true ),
mMarkupProcessorEnabled( false ),
- mClipboardHideEnabled( true )
+ mClipboardHideEnabled( true ),
+ mAutoScrollEnabled( false ),
+ mAutoScrollDirectionRTL( false )
{
mLogicalModel = LogicalModel::New();
mVisualModel = VisualModel::New();
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 mAutoScrollEnabled:1; ///< Whether auto text scrolling is enabled.
+ CharacterDirection mAutoScrollDirectionRTL:1; ///< Direction of auto scrolling, true if rtl
+
};
} // namespace Text
return mImpl->mMarkupProcessorEnabled;
}
+void Controller::SetAutoScrollEnabled( bool enable )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled[%s] SingleBox[%s]-> [%p]\n", (enable)?"true":"false", ( mImpl->mLayoutEngine.GetLayout() == LayoutEngine::SINGLE_LINE_BOX)?"true":"false", this );
+
+ if ( mImpl->mLayoutEngine.GetLayout() == LayoutEngine::SINGLE_LINE_BOX )
+ {
+ if ( enable )
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled for SINGLE_LINE_BOX\n" );
+ mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending |
+ LAYOUT |
+ ALIGN |
+ UPDATE_ACTUAL_SIZE |
+ UPDATE_DIRECTION |
+ REORDER );
+
+ }
+ else
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled Disabling autoscroll\n");
+ mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending |
+ LAYOUT |
+ ALIGN |
+ UPDATE_ACTUAL_SIZE |
+ REORDER );
+ }
+
+ mImpl->mAutoScrollEnabled = enable;
+ mImpl->RequestRelayout();
+ }
+ else
+ {
+ DALI_LOG_WARNING( "Attempted AutoScrolling on a non SINGLE_LINE_BOX, request ignored" );
+ mImpl->mAutoScrollEnabled = false;
+ }
+}
+
+bool Controller::IsAutoScrollEnabled() const
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::IsAutoScrollEnabled[%s]\n", (mImpl->mAutoScrollEnabled)?"true":"false" );
+
+ return mImpl->mAutoScrollEnabled;
+}
+
+CharacterDirection Controller::GetAutoScrollDirection() const
+{
+ return mImpl->mAutoScrollDirectionRTL;
+}
+
void Controller::SetText( const std::string& text )
{
DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::SetText\n" );
void Controller::UpdateAfterFontChange( const std::string& newDefaultFont )
{
- DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange");
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::UpdateAfterFontChange");
if( !mImpl->mFontDefaults->familyDefined ) // If user defined font then should not update when system font changes
{
bool Controller::Relayout( const Size& size )
{
- DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->Controller::Relayout %p size %f,%f\n", this, size.width, size.height );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->Controller::Relayout %p size %f,%f, autoScroll[%s]\n", this, size.width, size.height, (mImpl->mAutoScrollEnabled)?"true":"false" );
if( ( size.width < Math::MACHINE_EPSILON_1000 ) || ( size.height < Math::MACHINE_EPSILON_1000 ) )
{
if( NO_OPERATION != ( LAYOUT & operations ) )
{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->Controller::DoRelayout LAYOUT & operations\n");
+
// Some vectors with data needed to layout and reorder may be void
// after the first time the text has been laid out.
// Fill the vectors again.
mImpl->mVisualModel->mLines,
layoutSize );
+
if( viewUpdated )
{
+ if ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) )
+ {
+ mImpl->mAutoScrollDirectionRTL = false;
+ }
+
// Reorder the lines
if( NO_OPERATION != ( REORDER & operations ) )
{
requestedNumberOfCharacters,
glyphPositions );
+ if ( ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) ) && ( numberOfLines > 0 ) )
+ {
+ const LineRun* const firstline = mImpl->mVisualModel->mLines.Begin();
+ if ( firstline )
+ {
+ mImpl->mAutoScrollDirectionRTL = firstline->direction;
+ }
+ }
}
} // REORDER
viewUpdated = true;
}
-
+#if defined(DEBUG_ENABLED)
+ std::string currentText;
+ GetText( currentText );
+ 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;
}
REORDER = 0x0400,
ALIGN = 0x0800,
COLOR = 0x1000,
+ UPDATE_DIRECTION = 0x2000,
ALL_OPERATIONS = 0xFFFF
};
bool IsMarkupProcessorEnabled() const;
/**
+ * @brief Enables/disables the auto text scrolling
+ *
+ * By default is disabled.
+ *
+ * @param[in] enable Whether to enable the auto scrolling
+ */
+ void SetAutoScrollEnabled( bool enable );
+
+ /**
+ * @brief Retrieves whether auto text scrolling is enabled.
+ *
+ * By default is disabled.
+ *
+ * @return @e true if auto scrolling is enabled, otherwise returns @e false.
+ */
+ bool IsAutoScrollEnabled() const;
+
+ /**
+ * @brief Get direction of the text from the first line of text,
+ * @return bool rtl (right to left) is true
+ */
+ CharacterDirection GetAutoScrollDirection() const;
+
+ /**
* @brief Replaces any text previously set.
*
* @note This will be converted into UTF-32 when stored in the text model.
--- /dev/null
+/*
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/text/text-scroller-interface.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+ScrollerInterface::ScrollerInterface()
+{
+}
+
+ScrollerInterface::~ScrollerInterface()
+{
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_SCROLLER_INTERFACE_H__
+#define __DALI_TOOLKIT_TEXT_SCROLLER_INTERFACE_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.
+ *
+ */
+
+namespace Dali
+{
+
+class Actor;
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief An interface used by the text-controls which implement auto-scrolling
+ */
+class ScrollerInterface
+{
+public:
+
+ /**
+ * @brief Constructor.
+ */
+ ScrollerInterface();
+
+ /**
+ * @brief Virtual destructor.
+ */
+ virtual ~ScrollerInterface();
+
+ /**
+ * @brief Called when the scrolling finishes
+ */
+ virtual void ScrollingFinished() = 0;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_SCROLLER_INTERFACE_H__
--- /dev/null
+/*
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/text/text-scroller.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/rendering/geometry.h>
+#include <dali/devel-api/rendering/renderer.h>
+#include <dali/devel-api/rendering/sampler.h>
+#include <dali/devel-api/rendering/shader.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/images/frame-buffer-image.h>
+#include <dali/public-api/render-tasks/render-task-list.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/text-scroller-interface.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace
+{
+
+#if defined ( DEBUG_ENABLED )
+ 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
+ varying highp float vRatio;\n
+ uniform mediump mat4 uMvpMatrix;\n
+ uniform mediump vec3 uSize;\n
+ uniform mediump float uDelta;\n
+ uniform mediump vec2 uTextureSize;
+ uniform mediump float uGap;\n
+ uniform mediump float uRtl;\n
+ \n
+ void main()\n
+ {\n
+ {\n
+ mediump vec4 vertexPosition = vec4(aPosition*uSize.xy, 0.0, 1.0);\n
+ float smallTextPadding = max(uSize.x - uTextureSize.x, 0. );\n
+ float gap = max( uGap, smallTextPadding );\n
+ vTexCoord.x = ( uDelta + ( uRtl * ( uTextureSize.x - uSize.x ) ) + ( aPosition.x * uSize.x ) )/ ( uTextureSize.x+gap );\n
+ vTexCoord.y = aPosition.y;\n
+ vRatio = uTextureSize.x / ( uTextureSize.x + gap );\n
+ gl_Position = uMvpMatrix * vertexPosition;\n
+ }\n
+ }\n
+);
+
+const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
+ varying mediump vec2 vTexCoord;\n
+ varying highp float vRatio;\n
+ uniform sampler2D sTexture;\n
+ \n
+ void main()\n
+ {\n
+ mediump vec2 texCoord;\n
+ texCoord.y = vTexCoord.y;\n
+ texCoord.x = fract( vTexCoord.x ) / vRatio;\n
+ if ( texCoord.x > 1.0 )\n
+ discard;\n
+ \n
+ gl_FragColor = texture2D( sTexture, texCoord );\n
+ }\n
+);
+
+/**
+ * @brief Create and set up a camera for the render task to use
+ *
+ * @param[in] sizeOfTarget size of the source camera to look at
+ * @param[out] offscreenCamera custom camera
+ */
+void CreateCameraActor( const Size& sizeOfTarget, CameraActor& offscreenCamera )
+{
+ offscreenCamera = CameraActor::New();
+ offscreenCamera.SetOrthographicProjection( sizeOfTarget );
+ offscreenCamera.SetInvertYAxis( true );
+}
+
+/**
+ * @brief Create a render task
+ *
+ * @param[in] sourceActor actor to be used as source
+ * @param[in] cameraActor camera looking at source
+ * @param[in] offscreenTarget resulting image from render task
+ * @param[out] renderTask render task that has been setup
+ */
+void CreateRenderTask( Actor sourceActor, CameraActor cameraActor , FrameBufferImage offscreenTarget, RenderTask& renderTask )
+{
+ Stage stage = Stage::GetCurrent();
+ RenderTaskList taskList = stage.GetRenderTaskList();
+ renderTask = taskList.CreateTask();
+ renderTask.SetSourceActor( sourceActor );
+ renderTask.SetExclusive( true );
+ renderTask.SetInputEnabled( false );
+ renderTask.SetClearEnabled( true );
+ renderTask.SetCameraActor( cameraActor );
+ renderTask.SetTargetFrameBuffer( offscreenTarget );
+ renderTask.SetClearColor( Color::TRANSPARENT );
+ renderTask.SetCullMode( false );
+}
+
+/**
+ * @brief Create quad geometry for the mesh
+ *
+ * @param[out] geometry quad geometry that can be used for a mesh
+ */
+void CreateGeometry( Geometry& geometry )
+{
+ struct QuadVertex { Vector2 position; };
+
+ QuadVertex quadVertexData[4] =
+ {
+ { Vector2( 0.0f, 0.0f) },
+ { Vector2( 1.0f, 0.0f) },
+ { Vector2( 0.0f, 1.0f) },
+ { Vector2( 1.0f, 1.0f) },
+ };
+
+ const unsigned short indices[6] =
+ {
+ 3,1,0,0,2,3
+ };
+
+ Property::Map quadVertexFormat;
+ quadVertexFormat["aPosition"] = Property::VECTOR2;
+ PropertyBuffer quadVertices = PropertyBuffer::New( quadVertexFormat );
+ quadVertices.SetData(quadVertexData, 4 );
+
+ geometry = Geometry::New();
+ geometry.AddVertexBuffer( quadVertices );
+ geometry.SetIndexBuffer( indices, sizeof(indices)/sizeof(indices[0]) );
+}
+
+
+/**
+ * @brief Create a renderer
+ *
+ * @param[in] frameBufferImage texture to be used
+ * @param[out] renderer mesh renderer using the supplied texture
+ */
+void CreateRenderer( FrameBufferImage frameBufferImage, Dali::Renderer& renderer )
+{
+ Shader shader = Shader::New( VERTEX_SHADER_SCROLL , FRAGMENT_SHADER, Shader::HINT_NONE );
+
+ Sampler sampler = Sampler::New();
+ sampler.SetFilterMode(FilterMode::NEAREST, FilterMode::NEAREST );
+
+ TextureSet textureSet = TextureSet::New();
+ textureSet.SetImage( 0u, frameBufferImage );
+ textureSet.SetSampler( 0u, sampler );
+
+ Geometry meshGeometry;
+ CreateGeometry( meshGeometry );
+
+ renderer = Renderer::New( meshGeometry, shader );
+ renderer.SetTextures( textureSet );
+}
+
+} // namespace
+
+namespace Text
+{
+
+TextScrollerPtr TextScroller::New( ScrollerInterface& scrollerInterface )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::New\n" );
+
+ TextScrollerPtr textScroller( new TextScroller( scrollerInterface) );
+ return textScroller;
+}
+
+void TextScroller::SetGap( float gap )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetGap gap[%f]\n", gap );
+ mWrapGap = gap;
+}
+
+float TextScroller::GetGap() const
+{
+ return 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;
+}
+
+Actor TextScroller::GetScrollingText() const
+{
+ return mScrollingTextActor;
+}
+
+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" );
+}
+
+TextScroller::~TextScroller()
+{
+ CleanUp();
+}
+
+void TextScroller::SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, const Vector2 alignmentOffset )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters controlSize[%f,%f] offscreenSize[%f,%f] direction[%d] alignmentOffset[%f,%f]\n",
+ controlSize.x, controlSize.y, offScreenSize.x, offScreenSize.y, direction, alignmentOffset.x, alignmentOffset.y );
+
+ FrameBufferImage offscreenRenderTargetForText = FrameBufferImage::New( offScreenSize.width, offScreenSize.height, Pixel::RGBA8888, Dali::Image::UNUSED );
+ Renderer renderer;
+
+ CreateCameraActor( offScreenSize, mOffscreenCameraActor );
+ CreateRenderer( offscreenRenderTargetForText, renderer );
+ CreateRenderTask( sourceActor, mOffscreenCameraActor, offscreenRenderTargetForText, mRenderTask );
+
+ // Reposition camera to match alignment of target, RTL text has direction=true
+ if ( direction )
+ {
+ mOffscreenCameraActor.SetX( alignmentOffset.x + offScreenSize.width*0.5f );
+ }
+ else
+ {
+ mOffscreenCameraActor.SetX( offScreenSize.width * 0.5f );
+ }
+
+ mOffscreenCameraActor.SetY( offScreenSize.height * 0.5f );
+
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters mWrapGap[%f]\n", mWrapGap )
+
+ mScrollingTextActor = Actor::New();
+ mScrollingTextActor.AddRenderer( renderer );
+ 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( offScreenSize.width + mWrapGap, controlSize.width );
+ float scrollDuration = scrollAmount / mScrollSpeed;
+
+ if ( direction )
+ {
+ scrollAmount = -scrollAmount; // reverse direction of scrollung
+ }
+
+ StartScrolling( scrollAmount, scrollDuration, mLoopCount );
+}
+
+void TextScroller::AutoScrollAnimationFinished( Dali::Animation& animation )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::AutoScrollAnimationFinished\n" );
+ CleanUp();
+ 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() )
+ {
+ Stage stage = Stage::GetCurrent();
+ RenderTaskList taskList = stage.GetRenderTaskList();
+ UnparentAndReset( mScrollingTextActor );
+ UnparentAndReset( mOffscreenCameraActor );
+ taskList.RemoveTask( mRenderTask );
+ }
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_SCROLLER_H__
+#define __DALI_TOOLKIT_TEXT_SCROLLER_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 <dali/public-api/actors/camera-actor.h>
+#include <dali/public-api/animation/animation.h>
+#include <dali/public-api/render-tasks/render-task.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+class TextScroller;
+class ScrollerInterface;
+
+typedef IntrusivePtr<TextScroller> TextScrollerPtr;
+
+/**
+ * @brief A helper class for scrolling text
+ */
+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.
+ *
+ * @param[in] scrollerInterface scroller interface
+ */
+ static TextScrollerPtr New( ScrollerInterface& scrollerInterface );
+
+ /**
+ * @brief Set parameters relating to source required for scrolling
+ *
+ * @param[in] sourceActor source actor to be scrolled
+ * @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 SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, const Vector2 alignmentOffset );
+
+ /**
+ * @brief Set the gap distance to elapse before the text wraps around
+ * @param[in] gap distance to elapse
+ */
+ void SetGap( float gap );
+
+ /**
+ * @brief Get the distance before scrolling waps
+ * @return gap distance to elapse
+ */
+ float GetGap() const;
+
+ /**
+ * @brief Set speed the text should scroll
+ * @param[in] scrollSpeed pixels per second
+ */
+ void SetSpeed( int scrollSpeed );
+
+ /**
+ * @brief Get the speed of text scrolling
+ * @return speed in pixels per second
+ */
+ 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.
+ * @return camera Actor
+ */
+ Actor GetSourceCamera() const;
+
+ /**
+ * @brief Get the resulting scrolling text actor, add to target actor which will show scrolling text
+ * @return mesh Actor
+ */
+ Actor GetScrollingText() const;
+
+private: // Implementation
+
+ /**
+ * Constructor
+ */
+ TextScroller( ScrollerInterface& scrollerInterface );
+
+ /**
+ * Destructor
+ */
+ ~TextScroller();
+
+ // Undefined
+ TextScroller( const TextScroller& handle );
+
+ // Undefined
+ TextScroller& operator=( const TextScroller& handle );
+
+ /**
+ * @brief Callback for end of animation
+ * @param[in] animation Animation handle
+ */
+ 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();
+
+private:
+
+ RenderTask mRenderTask; // Renders full text to a FrameBuffer which is then scrolled.
+ CameraActor mOffscreenCameraActor; // Camera used by render task
+ Actor mScrollingTextActor; // Actor used to show scrolling text
+ ScrollerInterface& mScrollerInterface; // Interface implemented by control that requires scrolling
+ 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
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_SCROLLER_H__
+
struct GlyphRun;
/**
- * @brief Abstract interface to provide the information necessary displaying text.
+ * @brief Abstract interface to provide the information necessary to display text.
*
* This includes:
* - The font & glyph IDs needed to get bitmaps etc. from TextAbstraction
/**
* @brief Retrieves the target size of the UI control.
*
- * @return The text's size.
+ * @return The control's size.
*/
virtual const Vector2& GetControlSize() const = 0;
bool mUnderlineEnabled:1; ///< Underline enabled flag
bool mUnderlineColorSet:1; ///< Has the underline color been explicitly set?
-
};
} // namespace Text
UNDERLINE_ENABLED, ///< name "underlineEnabled", The underline enabled flag, type BOOLEAN @SINCE_1_0.0
UNDERLINE_COLOR, ///< name "underlineColor", The color of the underline, type VECTOR4 @SINCE_1_0.0
UNDERLINE_HEIGHT, ///< name "underlineHeight", Overrides the underline height from font metrics, type FLOAT @SINCE_1_0.0
- ENABLE_MARKUP ///< name "enableMarkup", Whether the mark-up processing is enabled. type BOOLEAN @SINCE_1_0.0
+ ENABLE_MARKUP, ///< name "enableMarkup", Whether the mark-up processing is enabled. type BOOLEAN @SINCE_1_0.0
+ ENABLE_AUTO_SCROLL, ///< name "enableAutoScroll", Whether to start auto text scrolling type BOOLEAN @SINCE_1_1.35
+ AUTO_SCROLL_SPEED, ///< name "autoScrollSpeed", Speed at which text should auto scroll type INT @SINCE_1_1.35
+ AUTO_SCROLL_LOOP_COUNT, ///< name "autoScrollLoopCount", Number of times the text should scroll (loop) type INT @SINCE_1_1.35
+ AUTO_SCROLL_GAP ///< name "autoScrollGap", Gap before text wraps around when scrolling type FLOAT @SINCE_1_1.35
};
};
{
"textlabel":
{
- "pointSize":18
+ "pointSize":18,
+ "enableAutoScroll":false,
+ "autoScrollLoopCount":2,
+ "autoScrollGap":50,
+ "autoScrollSpeed":80
},
"textlabelFontSize0":
{
"textlabel":
{
- "pointSize":18
+ "pointSize":18,
+ "enableAutoScroll":false,
+ "autoScrollLoopCount":2,
+ "autoScrollGap":50,
+ "autoScrollSpeed":80
},
"textlabelFontSize0":