Changes required after TextLabel Devel properties were made public
[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
178     CreateBox( "boxC", boxC, desktop, SCROLLING_BOX_SIZE );
179     boxC.SetPosition( 0.0f, -300.0f, 1.0f );
180     Toolkit::PushButton scrollSmallButton = Toolkit::PushButton::New();
181     scrollSmallButton.ClickedSignal().Connect( this, &TextScrollingExample::OnButtonClickedSmall );
182     CreateLabel( mSmallLabel, "Hello Text", boxC , true, scrollSmallButton );
183     mSmallLabel.SetProperty( TextLabel::Property::TEXT_COLOR, Color::BLACK );
184     mSmallLabel.SetProperty( TextLabel::Property::SHADOW_OFFSET, Vector2( 1.0f, 1.0f ) );
185     mSmallLabel.SetProperty( TextLabel::Property::SHADOW_COLOR, Color::CYAN );
186
187     CreateBox( "boxD", boxD, desktop, SCROLLING_BOX_SIZE );
188     boxD.SetPosition( 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 );
194
195     CreateBox( "boxE", boxE, desktop, SCROLLING_BOX_SIZE );
196     boxE.SetPosition( 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 );
204
205     mPanGestureDetector = PanGestureDetector::New();
206     mPanGestureDetector.DetectedSignal().Connect(this, &TextScrollingExample::OnPanGesture );
207     mPanGestureDetector.Attach( desktop );
208
209     Toolkit::PushButton colorButton = Toolkit::PushButton::New();
210     colorButton.SetProperty( Button::Property::TOGGLABLE, true );
211     colorButton.SetProperty( DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, Property::Map().Add ( Toolkit::Visual::Property::TYPE, Visual::COLOR ).Add( ColorVisual::Property::MIX_COLOR, Color::RED ) );
212     colorButton.SetProperty( DevelButton::Property::SELECTED_BACKGROUND_VISUAL, Property::Map().Add ( Toolkit::Visual::Property::TYPE, Visual::COLOR ).Add( ColorVisual::Property::MIX_COLOR, Color::BLACK ) );
213     colorButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
214     colorButton.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
215     colorButton.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
216     colorButton.SetSize(BOX_SIZE.height,BOX_SIZE.height);
217     colorButton.ClickedSignal().Connect( this, &TextScrollingExample::OnColorButtonClicked );
218     rootActor.Add( colorButton );
219
220     for( unsigned int i = 0; i < ALIGNMENT_TABLE_COUNT; ++i )
221     {
222       Toolkit::RadioButton alignButton = Toolkit::RadioButton::New( ALIGNMENT_TABLE[ i ] );
223       alignButton.ClickedSignal().Connect( this, &TextScrollingExample::OnAlignButtonClicked );
224       alignButton.SetName( ALIGNMENT_TABLE[ i ] );
225
226       // Place first button to left aligned, second center aligned and third right aligned
227       alignButton.SetAnchorPoint( Vector3( i * 0.5f, 0.0f, 0.5f ) );
228       alignButton.SetParentOrigin( Vector3( i * 0.5f, 0.0f, 0.5f ) );
229
230       rootActor.Add( alignButton );
231
232       if( i == 0 )
233       {
234         // Set the first button as selected
235         alignButton.SetProperty( Button::Property::SELECTED, true );
236       }
237     }
238   }
239
240   void EnableScrolling( Labels labels )
241     {
242       Actor label;
243       switch( labels )
244       {
245         case LARGE:
246         {
247           label = mLargeLabel;
248           break;
249         }
250         case RTL:
251         {
252           label = mRtlLabel;
253           break;
254         }
255         case SMALL:
256         {
257           label = mSmallLabel;
258           break;
259         }
260         case RTL_LONG:
261         {
262           label = mRtlLongLabel;
263           break;
264         }
265         case NONE:
266         {
267           return;
268         }
269       }
270
271       if ( labels != NONE )
272       {
273         Property::Value value = label.GetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL);
274         if (value.Get< bool >())
275         {
276           label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, false  );
277         }
278         else
279         {
280           label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, true  );
281         }
282       }
283     }
284
285   bool OnButtonClickedSmall( Toolkit::Button button )
286   {
287     EnableScrolling( SMALL );
288     return true;
289   }
290
291   bool OnButtonClickedLarge( Toolkit::Button button )
292   {
293     EnableScrolling( LARGE );
294     return true;
295   }
296
297   bool OnButtonClickedRtl( Toolkit::Button button )
298   {
299     EnableScrolling( RTL );
300     return true;
301   }
302
303   bool OnButtonClickedRtlLong( Toolkit::Button button )
304   {
305     EnableScrolling( RTL_LONG );
306     return true;
307   }
308
309   bool OnColorButtonClicked( Toolkit::Button button )
310   {
311     Vector4 color = Color::RED;
312
313     if ( mToggleColor )
314     {
315       color = Color::BLACK;
316       mToggleColor = false;
317     }
318     else
319     {
320       mToggleColor = true;
321     }
322
323     mSmallLabel.SetProperty( TextLabel::Property::SHADOW_COLOR, Color::BLACK );
324     mSmallLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
325     mRtlLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
326     mLargeLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
327     mRtlLongLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
328
329     return true;
330   }
331
332   bool OnAlignButtonClicked( Toolkit::Button button )
333   {
334     for( unsigned int index = 0; index < ALIGNMENT_TABLE_COUNT; ++index )
335     {
336       const std::string& buttonName = button.GetName();
337       if( buttonName == ALIGNMENT_TABLE[ index ] )
338       {
339         mSmallLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[ index ] );
340         mRtlLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[ index ] );
341         mLargeLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[ index ] );
342         mRtlLongLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, ALIGNMENT_TABLE[ index ] );
343         break;
344       }
345     }
346
347     return true;
348   }
349
350   /**
351    * Main key event handler
352    */
353   void OnKeyEvent(const KeyEvent& event)
354   {
355     if(event.state == KeyEvent::Down)
356     {
357       if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) )
358       {
359         mApplication.Quit();
360       }
361       else
362       {
363         if ( event.keyPressedName == "2" )
364         {
365           mAnimation.AnimateTo( Property( mSmallLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
366           mAnimation.AnimateTo( Property( mLargeLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
367           mAnimation.AnimateTo( Property( mRtlLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
368           mAnimation.AnimateTo( Property( mRtlLongLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
369
370           mAnimation.Play();
371         }
372       }
373     }
374   }
375
376   void OnPanGesture( Actor actor, const PanGesture& gesture )
377   {
378     if( gesture.state == Gesture::Continuing )
379     {
380       Vector2 position = Vector2( gesture.displacement );
381       mTargetActorPosition.y = mTargetActorPosition.y + position.y;
382       mTargetActorPosition.y = std::min( mTargetActorPosition.y, -mTargetActorSize.height );
383       mTargetActorPosition.y = std::max( mTargetActorPosition.y, ( mTargetActorSize.height - mStageSize.height*0.25f ) );
384       actor.SetPosition( 0.0f, mTargetActorPosition.y );
385     }
386   }
387
388 private:
389
390   Application& mApplication;
391   PanGestureDetector mPanGestureDetector;
392
393   Vector2 mTargetActorPosition;
394   Vector2 mTargetActorSize;
395   Vector2 mStageSize;
396
397   TextLabel mLargeLabel;
398   TextLabel mSmallLabel;
399   TextLabel mRtlLabel;
400   TextLabel mRtlLongLabel;
401
402   Animation mAnimation;
403
404   bool mToggleColor;
405 };
406
407 void RunTest( Application& application )
408 {
409   TextScrollingExample test( application );
410
411   application.MainLoop();
412 }
413
414 /** Entry point for Linux & Tizen applications */
415 int DALI_EXPORT_API main( int argc, char **argv )
416 {
417   Application application = Application::New( &argc, &argv, DEMO_THEME_PATH );
418
419   RunTest( application );
420
421   return 0;
422 }