2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 * @file text-scrolling-example.cpp
20 * @brief Shows text labels with scrolling text and allows a text label and text field control to be scrolled vertically
24 #include <dali-toolkit/dali-toolkit.h>
27 using namespace Dali::Toolkit;
31 const float WINDOW_HEIGHT_MULTIPLIER( 1.5f );
32 const Vector2 BOX_SIZE( Vector2(330.0f, 80.0f ) );
33 const Vector2 SCROLLING_BOX_SIZE( Vector2(330.0f, 40.0f ) );
34 const float MAX_OFFSCREEN_RENDERING_SIZE = 2048.f;
35 const float SCREEN_BORDER = 5.0f; // Border around screen that Popups and handles will not exceed
37 const char * ALIGNMENT_TABLE[] =
43 const unsigned int ALIGNMENT_TABLE_COUNT = sizeof( ALIGNMENT_TABLE ) / sizeof( ALIGNMENT_TABLE[ 0 ] );
55 * @brief The main class of the demo.
57 class TextScrollingExample : public ConnectionTracker
61 TextScrollingExample( Application& application )
62 : mApplication( application ),
63 mTargetActorPosition(),
67 // Connect to the Application's Init signal
68 mApplication.InitSignal().Connect( this, &TextScrollingExample::Create );
71 ~TextScrollingExample()
73 // Nothing to do here.
77 void CreateBox( const std::string& name, Actor& box, Actor parent, const Vector2& size )
79 box.SetProperty( Dali::Actor::Property::NAME,name);
80 box.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
81 box.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
82 box.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT );
83 box.SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
84 box.SetProperty( Actor::Property::SIZE, Vector2( size.width, 0.f ) );
87 Dali::Property::Map border;
88 border.Insert( Toolkit::Visual::Property::TYPE, Visual::BORDER );
89 border.Insert( BorderVisual::Property::COLOR, Color::BLUE );
90 border.Insert( BorderVisual::Property::SIZE, 1.f );
91 box.SetProperty( Control::Property::BACKGROUND, border );
94 void CreateLabel( Actor& label, const std::string text, Actor parent, bool scrollOnStart, PushButton button )
96 label = TextLabel::New( text );
97 label.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
98 label.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
99 label.SetProperty( Actor::Property::PADDING, Padding( 1.0f, 1.0f, 1.0f, 1.0f ) );
100 label.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
101 label.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
106 label.SetProperty(TextLabel::Property::ENABLE_AUTO_SCROLL, true);
109 button.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
110 button.SetProperty( Actor::Property::SIZE, Vector2(BOX_SIZE.height,BOX_SIZE.height) );
111 button.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_RIGHT );
112 button.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
118 * One-time setup in response to Application InitSignal.
120 void Create( Application& application )
122 Window window = application.GetWindow();
123 mWindowSize = window.GetSize();
125 window.KeyEventSignal().Connect(this, &TextScrollingExample::OnKeyEvent);
128 Actor rootActor = Actor::New();
129 rootActor.SetProperty( Dali::Actor::Property::NAME,"rootActor");
130 rootActor.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
131 rootActor.SetProperty( Actor::Property::SIZE, mWindowSize );
132 rootActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
134 window.Add( rootActor );
136 mAnimation = Animation::New( 1.0f );
138 const Size mTargetActorSize( mWindowSize.width, mWindowSize.height * WINDOW_HEIGHT_MULTIPLIER );
141 Control desktop = Control::New();
142 desktop.SetBackgroundColor( Color::WHITE );
143 desktop.SetProperty( Dali::Actor::Property::NAME,"desktopActor");
144 desktop.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
145 desktop.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
146 desktop.SetProperty( Actor::Property::SIZE, mTargetActorSize );
148 rootActor.Add( desktop ); // Add desktop (content) to offscreen actor
151 Control boxA = Control::New();
152 Control boxB = Control::New();
153 Control boxC = Control::New();
154 Control boxD = Control::New();
155 Control boxE = Control::New();
157 CreateBox( "boxA", boxA, desktop, BOX_SIZE );
158 boxA.SetProperty( Actor::Property::POSITION, Vector3( 0.0f, -500.0f, 1.0f ));
161 TextField field = TextField::New();
162 field.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
163 field.SetProperty( Actor::Property::PADDING, Padding( 1.0f, 1.0f, 1.0f, 1.0f ) );
164 field.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
165 field.SetProperty( TextField::Property::PLACEHOLDER_TEXT, "Enter Folder Name" );
166 field.SetProperty( TextField::Property::DECORATION_BOUNDING_BOX, Rect<int>( SCREEN_BORDER, SCREEN_BORDER, mWindowSize.width - SCREEN_BORDER*2, mWindowSize.height - SCREEN_BORDER*2 ) );
168 boxA.SetProperty( Actor::Property::SIZE, BOX_SIZE);
170 CreateBox( "boxB", boxB, desktop, SCROLLING_BOX_SIZE );
171 boxB.SetProperty( Actor::Property::POSITION, Vector3( 0.0f, -400.0f, 1.0f ));
172 Toolkit::PushButton scrollLargeButton = Toolkit::PushButton::New();
173 scrollLargeButton.ClickedSignal().Connect( this, &TextScrollingExample::OnButtonClickedLarge );
174 CreateLabel( mLargeLabel, "A Quick Brown Fox Jumps Over The Lazy Dog", boxB, false ,scrollLargeButton );
176 CreateBox( "boxC", boxC, desktop, SCROLLING_BOX_SIZE );
177 boxC.SetProperty( Actor::Property::POSITION, Vector3( 0.0f, -300.0f, 1.0f ));
178 Toolkit::PushButton scrollSmallButton = Toolkit::PushButton::New();
179 scrollSmallButton.ClickedSignal().Connect( this, &TextScrollingExample::OnButtonClickedSmall );
180 CreateLabel( mSmallLabel, "Hello Text", boxC , true, scrollSmallButton );
181 mSmallLabel.SetProperty( TextLabel::Property::TEXT_COLOR, Color::BLACK );
182 Property::Map shadowMap;
183 shadowMap.Insert( "color", Color::CYAN );
184 shadowMap.Insert( "offset", Vector2( 1.0f, 1.0f ) );
185 mSmallLabel.SetProperty( TextLabel::Property::SHADOW, shadowMap );
187 CreateBox( "boxD", boxD, desktop, SCROLLING_BOX_SIZE );
188 boxD.SetProperty( Actor::Property::POSITION, Vector3( 0.0f, -200.0f, 1.0f ));
189 Toolkit::PushButton scrollRtlButton = Toolkit::PushButton::New();
190 scrollRtlButton.ClickedSignal().Connect( this, &TextScrollingExample::OnButtonClickedRtl );
191 CreateLabel( mRtlLabel, "مرØبا بالعالم", boxD , true, scrollRtlButton );
192 mRtlLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_STOP_MODE, TextLabel::AutoScrollStopMode::IMMEDIATE );
193 mRtlLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_LOOP_DELAY, 0.3f );
195 CreateBox( "boxE", boxE, desktop, SCROLLING_BOX_SIZE );
196 boxE.SetProperty( Actor::Property::POSITION, Vector3( 0.0f, -100.0f, 1.0f ));
197 Toolkit::PushButton scrollRtlLongButton = Toolkit::PushButton::New();
198 scrollRtlLongButton.ClickedSignal().Connect( this, &TextScrollingExample::OnButtonClickedRtlLong );
199 CreateLabel( mRtlLongLabel, " مرØبا بالعالم مرØبا بالعالم مرØبا بالعالم مرØبا بالعالم مرØبا بالعالم مرØبا بالعالم مرØبا بالعالم مرØبا بالعالم مرØبا بالعالم", boxE , false, scrollRtlLongButton );
200 mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_SPEED, 500);
201 mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_GAP, 500);
202 mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_LOOP_COUNT, 3);
203 mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_STOP_MODE, TextLabel::AutoScrollStopMode::FINISH_LOOP );
205 mPanGestureDetector = PanGestureDetector::New();
206 mPanGestureDetector.DetectedSignal().Connect(this, &TextScrollingExample::OnPanGesture );
207 mPanGestureDetector.Attach( desktop );
209 Toolkit::PushButton colorButton = Toolkit::PushButton::New();
210 colorButton.SetProperty( Button::Property::TOGGLABLE, true );
211 colorButton.SetProperty( Button::Property::UNSELECTED_BACKGROUND_VISUAL, Property::Map().Add ( Toolkit::Visual::Property::TYPE, Visual::COLOR ).Add( ColorVisual::Property::MIX_COLOR, Color::RED ) );
212 colorButton.SetProperty( Button::Property::SELECTED_BACKGROUND_VISUAL, Property::Map().Add ( Toolkit::Visual::Property::TYPE, Visual::COLOR ).Add( ColorVisual::Property::MIX_COLOR, Color::BLACK ) );
213 colorButton.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::BOTTOM_CENTER );
214 colorButton.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_CENTER );
215 colorButton.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
216 colorButton.SetProperty( Actor::Property::SIZE, Vector2(BOX_SIZE.height,BOX_SIZE.height) );
217 colorButton.ClickedSignal().Connect( this, &TextScrollingExample::OnColorButtonClicked );
218 rootActor.Add( colorButton );
220 for( unsigned int i = 0; i < ALIGNMENT_TABLE_COUNT; ++i )
222 Toolkit::RadioButton alignButton = Toolkit::RadioButton::New( ALIGNMENT_TABLE[ i ] );
223 alignButton.ClickedSignal().Connect( this, &TextScrollingExample::OnAlignButtonClicked );
224 alignButton.SetProperty( Dali::Actor::Property::NAME, ALIGNMENT_TABLE[ i ] );
226 // Place first button to left aligned, second center aligned and third right aligned
227 alignButton.SetProperty( Actor::Property::ANCHOR_POINT, Vector3( i * 0.5f, 0.0f, 0.5f ) );
228 alignButton.SetProperty( Actor::Property::PARENT_ORIGIN, Vector3( i * 0.5f, 0.0f, 0.5f ) );
230 rootActor.Add( alignButton );
234 // Set the first button as selected
235 alignButton.SetProperty( Button::Property::SELECTED, true );
240 void EnableScrolling( Labels labels )
262 label = mRtlLongLabel;
271 if ( labels != NONE )
273 Property::Value value = label.GetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL);
274 if (value.Get< bool >())
276 label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, false );
280 label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, true );
285 bool OnButtonClickedSmall( Toolkit::Button button )
287 EnableScrolling( SMALL );
291 bool OnButtonClickedLarge( Toolkit::Button button )
293 EnableScrolling( LARGE );
297 bool OnButtonClickedRtl( Toolkit::Button button )
299 EnableScrolling( RTL );
303 bool OnButtonClickedRtlLong( Toolkit::Button button )
305 EnableScrolling( RTL_LONG );
309 bool OnColorButtonClicked( Toolkit::Button button )
311 Vector4 color = Color::RED;
315 color = Color::BLACK;
316 mToggleColor = false;
323 Property::Map shadowMap;
324 shadowMap.Insert( "color", Color::BLACK );
325 mSmallLabel.SetProperty( TextLabel::Property::SHADOW, shadowMap );
326 mSmallLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
327 mRtlLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
328 mLargeLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
329 mRtlLongLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
334 bool OnAlignButtonClicked( Toolkit::Button button )
336 for( unsigned int index = 0; index < ALIGNMENT_TABLE_COUNT; ++index )
338 const std::string& buttonName = button.GetProperty< std::string >( Dali::Actor::Property::NAME );
339 if( buttonName == ALIGNMENT_TABLE[ index ] )
341 mSmallLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[ index ] );
342 mRtlLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[ index ] );
343 mLargeLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[ index ] );
344 mRtlLongLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[ index ] );
353 * Main key event handler
355 void OnKeyEvent(const KeyEvent& event)
357 if(event.GetState() == KeyEvent::Down)
359 if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) )
365 if ( event.GetKeyName() == "2" )
367 mAnimation.AnimateTo( Property( mSmallLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
368 mAnimation.AnimateTo( Property( mLargeLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
369 mAnimation.AnimateTo( Property( mRtlLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
370 mAnimation.AnimateTo( Property( mRtlLongLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
378 void OnPanGesture( Actor actor, const PanGesture& gesture )
380 if( gesture.state == Gesture::Continuing )
382 Vector2 position = Vector2( gesture.displacement );
383 mTargetActorPosition.y = mTargetActorPosition.y + position.y;
384 mTargetActorPosition.y = std::min( mTargetActorPosition.y, -mTargetActorSize.height );
385 mTargetActorPosition.y = std::max( mTargetActorPosition.y, ( mTargetActorSize.height - mWindowSize.height*0.25f ) );
386 actor.SetProperty( Actor::Property::POSITION, Vector2( 0.0f, mTargetActorPosition.y ));
392 Application& mApplication;
393 PanGestureDetector mPanGestureDetector;
395 Vector2 mTargetActorPosition;
396 Vector2 mTargetActorSize;
399 TextLabel mLargeLabel;
400 TextLabel mSmallLabel;
402 TextLabel mRtlLongLabel;
404 Animation mAnimation;
409 int DALI_EXPORT_API main( int argc, char **argv )
411 Application application = Application::New( &argc, &argv, DEMO_THEME_PATH );
412 TextScrollingExample test( application );
413 application.MainLoop();