Remove deprecated APIs in Tizen 3.0
[platform/core/uifw/dali-demo.git] / examples / text-scrolling / text-scrolling-example.cpp
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 /**
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
21  */
22
23 // EXTERNAL INCLUDES
24 #include <dali-toolkit/dali-toolkit.h>
25 #include <dali-toolkit/devel-api/controls/buttons/button-devel.h>
26
27 using namespace Dali;
28 using namespace Dali::Toolkit;
29
30 namespace
31 {
32 const Vector2 DESKTOP_SIZE( Vector2( 1440.f, 1600.f ) );
33 const Vector2 BOX_SIZE( Vector2(330.0f, 80.0f ) );
34 const Vector2 SCROLLING_BOX_SIZE( Vector2(330.0f, 40.0f ) );
35 const float MAX_OFFSCREEN_RENDERING_SIZE = 2048.f;
36 const float SCREEN_BORDER = 5.0f; // Border around screen that Popups and handles will not exceed
37
38 const char * ALIGNMENT_TABLE[] =
39 {
40   "BEGIN",
41   "CENTER",
42   "END"
43 };
44 const unsigned int ALIGNMENT_TABLE_COUNT = sizeof( ALIGNMENT_TABLE ) / sizeof( ALIGNMENT_TABLE[ 0 ] );
45
46 enum Labels
47 {
48   SMALL = 1u,
49   RTL = 1u << 1,
50   LARGE = 1u << 2,
51   RTL_LONG = 1u << 4,
52   NONE = 1u << 6,
53 };
54 }
55 /**
56  * @brief The main class of the demo.
57  */
58 class TextScrollingExample : public ConnectionTracker
59 {
60 public:
61
62   TextScrollingExample( Application& application )
63   : mApplication( application ),
64     mTargetActorPosition(),
65     mTargetActorSize(),
66     mToggleColor( false )
67   {
68     // Connect to the Application's Init signal
69     mApplication.InitSignal().Connect( this, &TextScrollingExample::Create );
70   }
71
72   ~TextScrollingExample()
73   {
74     // Nothing to do here.
75   }
76
77
78   void CreateBox( const std::string& name, Actor& box, Actor parent, const Vector2& size )
79   {
80     box.SetName(name);
81     box.SetAnchorPoint( AnchorPoint::CENTER );
82     box.SetParentOrigin( ParentOrigin::CENTER );
83     box.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT );
84     box.SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
85     box.SetSize( size.width, 0.f );
86     parent.Add( box );
87
88     Dali::Property::Map border;
89     border.Insert( Toolkit::Visual::Property::TYPE,  Visual::BORDER );
90     border.Insert( BorderVisual::Property::COLOR,  Color::BLUE );
91     border.Insert( BorderVisual::Property::SIZE,  1.f );
92     box.SetProperty( Control::Property::BACKGROUND, border );
93   }
94
95   void CreateLabel( Actor& label, const std::string text, Actor parent, bool scrollOnStart, PushButton button )
96   {
97     label = TextLabel::New( text );
98     label.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
99     label.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
100     label.SetPadding( Padding( 1.0f, 1.0f, 1.0f, 1.0f ) );
101     label.SetAnchorPoint( AnchorPoint::CENTER );
102     label.SetParentOrigin( ParentOrigin::CENTER );
103     parent.Add( label );
104
105     if ( scrollOnStart )
106     {
107       label.SetProperty(TextLabel::Property::ENABLE_AUTO_SCROLL, true);
108     }
109
110     button.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
111     button.SetSize(BOX_SIZE.height,BOX_SIZE.height);
112     button.SetParentOrigin( ParentOrigin::TOP_RIGHT );
113     button.SetAnchorPoint( AnchorPoint::TOP_LEFT );
114     parent.Add(button);
115   }
116
117
118   /**
119    * One-time setup in response to Application InitSignal.
120    */
121   void Create( Application& application )
122   {
123     Stage stage = Stage::GetCurrent();
124     mStageSize = stage.GetSize();
125
126     stage.KeyEventSignal().Connect(this, &TextScrollingExample::OnKeyEvent);
127
128     // Create Root actor
129     Actor rootActor = Actor::New();
130     rootActor.SetName("rootActor");
131     rootActor.SetResizePolicy( ResizePolicy::FIXED,  Dimension::ALL_DIMENSIONS );
132     rootActor.SetSize( mStageSize );
133     rootActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
134
135     stage.Add( rootActor );
136
137     mAnimation = Animation::New( 1.0f );
138
139     const Size mTargetActorSize( mStageSize.width, DESKTOP_SIZE.height );
140
141     // Create Desktop
142     Control desktop = Control::New();
143     desktop.SetBackgroundColor( Color::WHITE );
144     desktop.SetName("desktopActor");
145     desktop.SetAnchorPoint( AnchorPoint::TOP_LEFT );
146     desktop.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
147     desktop.SetSize( mTargetActorSize );
148
149     rootActor.Add( desktop ); // Add desktop (content) to offscreen actor
150
151     // Create Boxes
152     Control boxA = Control::New();
153     Control boxB = Control::New();
154     Control boxC = Control::New();
155     Control boxD = Control::New();
156     Control boxE = Control::New();
157
158     CreateBox( "boxA", boxA, desktop, BOX_SIZE );
159     boxA.SetPosition( 0.0f, -500.0f, 1.0f );
160
161     // Create TextField
162     TextField field = TextField::New();
163     field.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
164     field.SetPadding( Padding( 1.0f, 1.0f, 1.0f, 1.0f ) );
165     field.SetAnchorPoint( AnchorPoint::TOP_LEFT );
166     field.SetProperty( TextField::Property::PLACEHOLDER_TEXT, "Enter Folder Name" );
167     field.SetProperty( TextField::Property::DECORATION_BOUNDING_BOX, Rect<int>( SCREEN_BORDER, SCREEN_BORDER, mStageSize.width - SCREEN_BORDER*2, mStageSize.height - SCREEN_BORDER*2 ) );
168     boxA.Add( field );
169     boxA.SetSize(BOX_SIZE);
170
171     CreateBox( "boxB", boxB, desktop, SCROLLING_BOX_SIZE );
172     boxB.SetPosition( 0.0f, -400.0f, 1.0f );
173     Toolkit::PushButton scrollLargeButton = Toolkit::PushButton::New();
174     scrollLargeButton.ClickedSignal().Connect( this, &TextScrollingExample::OnButtonClickedLarge );
175     CreateLabel( mLargeLabel, "A Quick Brown Fox Jumps Over The Lazy Dog", boxB, false ,scrollLargeButton );
176
177     CreateBox( "boxC", boxC, desktop, SCROLLING_BOX_SIZE );
178     boxC.SetPosition( 0.0f, -300.0f, 1.0f );
179     Toolkit::PushButton scrollSmallButton = Toolkit::PushButton::New();
180     scrollSmallButton.ClickedSignal().Connect( this, &TextScrollingExample::OnButtonClickedSmall );
181     CreateLabel( mSmallLabel, "Hello Text", boxC , true, scrollSmallButton );
182     mSmallLabel.SetProperty( TextLabel::Property::TEXT_COLOR, Color::BLACK );
183     Property::Map shadowMap;
184     shadowMap.Insert( "color", Color::CYAN );
185     shadowMap.Insert( "offset", Vector2( 1.0f, 1.0f ) );
186     mSmallLabel.SetProperty( TextLabel::Property::SHADOW, shadowMap );
187
188     CreateBox( "boxD", boxD, desktop, SCROLLING_BOX_SIZE );
189     boxD.SetPosition( 0.0f, -200.0f, 1.0f );
190     Toolkit::PushButton scrollRtlButton = Toolkit::PushButton::New();
191     scrollRtlButton.ClickedSignal().Connect( this, &TextScrollingExample::OnButtonClickedRtl );
192     CreateLabel( mRtlLabel, "مرحبا بالعالم", boxD , true, scrollRtlButton );
193     mRtlLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_STOP_MODE, TextLabel::AutoScrollStopMode::IMMEDIATE );
194     mRtlLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_LOOP_DELAY, 0.3f );
195
196     CreateBox( "boxE", boxE, desktop, SCROLLING_BOX_SIZE );
197     boxE.SetPosition( 0.0f, -100.0f, 1.0f );
198     Toolkit::PushButton scrollRtlLongButton = Toolkit::PushButton::New();
199     scrollRtlLongButton.ClickedSignal().Connect( this, &TextScrollingExample::OnButtonClickedRtlLong );
200     CreateLabel( mRtlLongLabel, " مرحبا بالعالم مرحبا بالعالم مرحبا بالعالم مرحبا بالعالم مرحبا بالعالم مرحبا بالعالم مرحبا بالعالم مرحبا بالعالم مرحبا بالعالم", boxE , false, scrollRtlLongButton );
201     mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_SPEED, 500);
202     mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_GAP, 500);
203     mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_LOOP_COUNT, 3);
204     mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_STOP_MODE, TextLabel::AutoScrollStopMode::FINISH_LOOP );
205
206     mPanGestureDetector = PanGestureDetector::New();
207     mPanGestureDetector.DetectedSignal().Connect(this, &TextScrollingExample::OnPanGesture );
208     mPanGestureDetector.Attach( desktop );
209
210     Toolkit::PushButton colorButton = Toolkit::PushButton::New();
211     colorButton.SetProperty( Button::Property::TOGGLABLE, true );
212     colorButton.SetProperty( DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, Property::Map().Add ( Toolkit::Visual::Property::TYPE, Visual::COLOR ).Add( ColorVisual::Property::MIX_COLOR, Color::RED ) );
213     colorButton.SetProperty( DevelButton::Property::SELECTED_BACKGROUND_VISUAL, Property::Map().Add ( Toolkit::Visual::Property::TYPE, Visual::COLOR ).Add( ColorVisual::Property::MIX_COLOR, Color::BLACK ) );
214     colorButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
215     colorButton.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
216     colorButton.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
217     colorButton.SetSize(BOX_SIZE.height,BOX_SIZE.height);
218     colorButton.ClickedSignal().Connect( this, &TextScrollingExample::OnColorButtonClicked );
219     rootActor.Add( colorButton );
220
221     for( unsigned int i = 0; i < ALIGNMENT_TABLE_COUNT; ++i )
222     {
223       Toolkit::RadioButton alignButton = Toolkit::RadioButton::New( ALIGNMENT_TABLE[ i ] );
224       alignButton.ClickedSignal().Connect( this, &TextScrollingExample::OnAlignButtonClicked );
225       alignButton.SetName( ALIGNMENT_TABLE[ i ] );
226
227       // Place first button to left aligned, second center aligned and third right aligned
228       alignButton.SetAnchorPoint( Vector3( i * 0.5f, 0.0f, 0.5f ) );
229       alignButton.SetParentOrigin( Vector3( i * 0.5f, 0.0f, 0.5f ) );
230
231       rootActor.Add( alignButton );
232
233       if( i == 0 )
234       {
235         // Set the first button as selected
236         alignButton.SetProperty( Button::Property::SELECTED, true );
237       }
238     }
239   }
240
241   void EnableScrolling( Labels labels )
242     {
243       Actor label;
244       switch( labels )
245       {
246         case LARGE:
247         {
248           label = mLargeLabel;
249           break;
250         }
251         case RTL:
252         {
253           label = mRtlLabel;
254           break;
255         }
256         case SMALL:
257         {
258           label = mSmallLabel;
259           break;
260         }
261         case RTL_LONG:
262         {
263           label = mRtlLongLabel;
264           break;
265         }
266         case NONE:
267         {
268           return;
269         }
270       }
271
272       if ( labels != NONE )
273       {
274         Property::Value value = label.GetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL);
275         if (value.Get< bool >())
276         {
277           label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, false  );
278         }
279         else
280         {
281           label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, true  );
282         }
283       }
284     }
285
286   bool OnButtonClickedSmall( Toolkit::Button button )
287   {
288     EnableScrolling( SMALL );
289     return true;
290   }
291
292   bool OnButtonClickedLarge( Toolkit::Button button )
293   {
294     EnableScrolling( LARGE );
295     return true;
296   }
297
298   bool OnButtonClickedRtl( Toolkit::Button button )
299   {
300     EnableScrolling( RTL );
301     return true;
302   }
303
304   bool OnButtonClickedRtlLong( Toolkit::Button button )
305   {
306     EnableScrolling( RTL_LONG );
307     return true;
308   }
309
310   bool OnColorButtonClicked( Toolkit::Button button )
311   {
312     Vector4 color = Color::RED;
313
314     if ( mToggleColor )
315     {
316       color = Color::BLACK;
317       mToggleColor = false;
318     }
319     else
320     {
321       mToggleColor = true;
322     }
323
324     Property::Map shadowMap;
325     shadowMap.Insert( "color", Color::BLACK );
326     mSmallLabel.SetProperty( TextLabel::Property::SHADOW, shadowMap );
327     mSmallLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
328     mRtlLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
329     mLargeLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
330     mRtlLongLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
331
332     return true;
333   }
334
335   bool OnAlignButtonClicked( Toolkit::Button button )
336   {
337     for( unsigned int index = 0; index < ALIGNMENT_TABLE_COUNT; ++index )
338     {
339       const std::string& buttonName = button.GetName();
340       if( buttonName == ALIGNMENT_TABLE[ index ] )
341       {
342         mSmallLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[ index ] );
343         mRtlLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[ index ] );
344         mLargeLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[ index ] );
345         mRtlLongLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[ index ] );
346         break;
347       }
348     }
349
350     return true;
351   }
352
353   /**
354    * Main key event handler
355    */
356   void OnKeyEvent(const KeyEvent& event)
357   {
358     if(event.state == KeyEvent::Down)
359     {
360       if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) )
361       {
362         mApplication.Quit();
363       }
364       else
365       {
366         if ( event.keyPressedName == "2" )
367         {
368           mAnimation.AnimateTo( Property( mSmallLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
369           mAnimation.AnimateTo( Property( mLargeLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
370           mAnimation.AnimateTo( Property( mRtlLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
371           mAnimation.AnimateTo( Property( mRtlLongLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
372
373           mAnimation.Play();
374         }
375       }
376     }
377   }
378
379   void OnPanGesture( Actor actor, const PanGesture& gesture )
380   {
381     if( gesture.state == Gesture::Continuing )
382     {
383       Vector2 position = Vector2( gesture.displacement );
384       mTargetActorPosition.y = mTargetActorPosition.y + position.y;
385       mTargetActorPosition.y = std::min( mTargetActorPosition.y, -mTargetActorSize.height );
386       mTargetActorPosition.y = std::max( mTargetActorPosition.y, ( mTargetActorSize.height - mStageSize.height*0.25f ) );
387       actor.SetPosition( 0.0f, mTargetActorPosition.y );
388     }
389   }
390
391 private:
392
393   Application& mApplication;
394   PanGestureDetector mPanGestureDetector;
395
396   Vector2 mTargetActorPosition;
397   Vector2 mTargetActorSize;
398   Vector2 mStageSize;
399
400   TextLabel mLargeLabel;
401   TextLabel mSmallLabel;
402   TextLabel mRtlLabel;
403   TextLabel mRtlLongLabel;
404
405   Animation mAnimation;
406
407   bool mToggleColor;
408 };
409
410 int DALI_EXPORT_API main( int argc, char **argv )
411 {
412   Application application = Application::New( &argc, &argv, DEMO_THEME_PATH );
413   TextScrollingExample test( application );
414   application.MainLoop();
415   return 0;
416 }