TextScrolling example allows text color changes
[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 enum Labels
39 {
40   SMALL = 1u,
41   RTL = 1u << 1,
42   LARGE = 1u << 2,
43   RTL_LONG = 1u << 4,
44   NONE = 1u << 6,
45 };
46 }
47 /**
48  * @brief The main class of the demo.
49  */
50 class TextScrollingExample : public ConnectionTracker
51 {
52 public:
53
54   TextScrollingExample( Application& application )
55   : mApplication( application ),
56     mTargetActorPosition(),
57     mTargetActorSize(),
58     mToggleColor( false )
59   {
60     // Connect to the Application's Init signal
61     mApplication.InitSignal().Connect( this, &TextScrollingExample::Create );
62   }
63
64   ~TextScrollingExample()
65   {
66     // Nothing to do here.
67   }
68
69
70   void CreateBox( const std::string& name, Actor& box, Actor parent, const Vector2& size )
71   {
72     box.SetName(name);
73     box.SetAnchorPoint( AnchorPoint::CENTER );
74     box.SetParentOrigin( ParentOrigin::CENTER );
75     box.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT );
76     box.SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
77     box.SetSize( size.width, 0.f );
78     parent.Add( box );
79
80     Dali::Property::Map border;
81     border.Insert( Visual::Property::TYPE,  Visual::BORDER );
82     border.Insert( BorderVisual::Property::COLOR,  Color::BLUE );
83     border.Insert( BorderVisual::Property::SIZE,  1.f );
84     box.SetProperty( Control::Property::BACKGROUND, border );
85   }
86
87   void CreateLabel( Actor& label, const std::string text, Actor parent, bool scrollOnStart, PushButton button )
88   {
89     label = TextLabel::New( text );
90     label.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
91     label.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
92     label.SetPadding( Padding( 1.0f, 1.0f, 1.0f, 1.0f ) );
93     label.SetAnchorPoint( AnchorPoint::CENTER );
94     label.SetParentOrigin( ParentOrigin::CENTER );
95     parent.Add( label );
96
97     if ( scrollOnStart )
98     {
99       label.SetProperty(TextLabel::Property::ENABLE_AUTO_SCROLL, true);
100     }
101
102     button.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
103     button.SetSize(BOX_SIZE.height,BOX_SIZE.height);
104     button.SetParentOrigin( ParentOrigin::TOP_RIGHT );
105     button.SetAnchorPoint( AnchorPoint::TOP_LEFT );
106     parent.Add(button);
107   }
108
109
110   /**
111    * One-time setup in response to Application InitSignal.
112    */
113   void Create( Application& application )
114   {
115     Stage stage = Stage::GetCurrent();
116     mStageSize = stage.GetSize();
117
118     stage.KeyEventSignal().Connect(this, &TextScrollingExample::OnKeyEvent);
119
120     // Create Root actor
121     Actor rootActor = Actor::New();
122     rootActor.SetName("rootActor");
123     rootActor.SetResizePolicy( ResizePolicy::FIXED,  Dimension::ALL_DIMENSIONS );
124     rootActor.SetSize( mStageSize );
125     rootActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
126
127     stage.Add( rootActor );
128
129     mAnimation = Animation::New( 1.0f );
130
131     const Size mTargetActorSize( mStageSize.width, DESKTOP_SIZE.height );
132
133     // Create Desktop
134     Control desktop = Control::New();
135     desktop.SetBackgroundColor( Color::WHITE );
136     desktop.SetName("desktopActor");
137     desktop.SetAnchorPoint( AnchorPoint::TOP_LEFT );
138     desktop.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
139     desktop.SetSize( mTargetActorSize );
140
141     rootActor.Add( desktop ); // Add desktop (content) to offscreen actor
142
143     // Create Boxes
144     Control boxA = Control::New();
145     Control boxB = Control::New();
146     Control boxC = Control::New();
147     Control boxD = Control::New();
148     Control boxE = Control::New();
149
150     CreateBox( "boxA", boxA, desktop, BOX_SIZE );
151     boxA.SetPosition( 0.0f, -500.0f, 1.0f );
152
153     // Create TextField
154     TextField field = TextField::New();
155     field.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
156     field.SetPadding( Padding( 1.0f, 1.0f, 1.0f, 1.0f ) );
157     field.SetAnchorPoint( AnchorPoint::TOP_LEFT );
158     field.SetProperty( TextField::Property::PLACEHOLDER_TEXT, "Enter Folder Name" );
159     field.SetProperty( TextField::Property::DECORATION_BOUNDING_BOX, Rect<int>( SCREEN_BORDER, SCREEN_BORDER, mStageSize.width - SCREEN_BORDER*2, mStageSize.height - SCREEN_BORDER*2 ) );
160     boxA.Add( field );
161     boxA.SetSize(BOX_SIZE);
162
163     CreateBox( "boxB", boxB, desktop, SCROLLING_BOX_SIZE );
164     boxB.SetPosition( 0.0f, -400.0f, 1.0f );
165     Toolkit::PushButton scrollLargeButton = Toolkit::PushButton::New();
166     scrollLargeButton.ClickedSignal().Connect( this, &TextScrollingExample::OnButtonClickedLarge );
167     CreateLabel( mLargeLabel, "A Quick Brown Fox Jumps Over The Lazy Dog", boxB, false ,scrollLargeButton );
168
169
170     CreateBox( "boxC", boxC, desktop, SCROLLING_BOX_SIZE );
171     boxC.SetPosition( 0.0f, -300.0f, 1.0f );
172     Toolkit::PushButton scrollSmallButton = Toolkit::PushButton::New();
173     scrollSmallButton.ClickedSignal().Connect( this, &TextScrollingExample::OnButtonClickedSmall );
174     CreateLabel( mSmallLabel, "A Quick Brown Fox", boxC , true, scrollSmallButton );
175     mSmallLabel.SetProperty( TextLabel::Property::TEXT_COLOR, Color::BLACK );
176     mSmallLabel.SetProperty( TextLabel::Property::SHADOW_OFFSET, Vector2( 1.0f, 1.0f ) );
177     mSmallLabel.SetProperty( TextLabel::Property::SHADOW_COLOR, Color::CYAN );
178
179     CreateBox( "boxD", boxD, desktop, SCROLLING_BOX_SIZE );
180     boxD.SetPosition( 0.0f, -200.0f, 1.0f );
181     Toolkit::PushButton scrollRtlButton = Toolkit::PushButton::New();
182     scrollRtlButton.ClickedSignal().Connect( this, &TextScrollingExample::OnButtonClickedRtl );
183     CreateLabel( mRtlLabel, "مرحبا بالعالم", boxD , true, scrollRtlButton );
184
185     CreateBox( "boxE", boxE, desktop, SCROLLING_BOX_SIZE );
186     boxE.SetPosition( 0.0f, -100.0f, 1.0f );
187     Toolkit::PushButton scrollRtlLongButton = Toolkit::PushButton::New();
188     scrollRtlLongButton.ClickedSignal().Connect( this, &TextScrollingExample::OnButtonClickedRtlLong );
189     CreateLabel( mRtlLongLabel, " مرحبا بالعالم مرحبا بالعالم مرحبا بالعالم مرحبا بالعالم مرحبا بالعالم مرحبا بالعالم مرحبا بالعالم مرحبا بالعالم مرحبا بالعالم", boxE , false, scrollRtlLongButton );
190     mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_SPEED, 500);
191     mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_GAP, 500);
192     mRtlLongLabel.SetProperty(TextLabel::Property::AUTO_SCROLL_LOOP_COUNT, 3);
193
194     mPanGestureDetector = PanGestureDetector::New();
195     mPanGestureDetector.DetectedSignal().Connect(this, &TextScrollingExample::OnPanGesture );
196     mPanGestureDetector.Attach( desktop );
197
198     Toolkit::PushButton colorButton = Toolkit::PushButton::New();
199     colorButton.SetProperty( Button::Property::TOGGLABLE, true );
200     colorButton.SetProperty( DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, Property::Map().Add ( Visual::Property::TYPE, Visual::COLOR ).Add( ColorVisual::Property::MIX_COLOR, Color::RED ) );
201     colorButton.SetProperty( DevelButton::Property::SELECTED_BACKGROUND_VISUAL, Property::Map().Add ( Visual::Property::TYPE, Visual::COLOR ).Add( ColorVisual::Property::MIX_COLOR, Color::BLACK ) );
202     colorButton.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
203     colorButton.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
204     colorButton.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
205     colorButton.SetSize(BOX_SIZE.height,BOX_SIZE.height);
206     colorButton.ClickedSignal().Connect( this, &TextScrollingExample::OnColorButtonClicked );
207     rootActor.Add( colorButton );
208   }
209
210   void EnableScrolling( Labels labels )
211     {
212       Actor label;
213       switch( labels )
214       {
215         case LARGE:
216         {
217           label = mLargeLabel;
218           break;
219         }
220         case RTL:
221         {
222           label = mRtlLabel;
223           break;
224         }
225         case SMALL:
226         {
227           label = mSmallLabel;
228           break;
229         }
230         case RTL_LONG:
231         {
232           label = mRtlLongLabel;
233           break;
234         }
235         case NONE:
236         {
237           return;
238         }
239       }
240
241       if ( labels != NONE )
242       {
243         Property::Value value = label.GetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL);
244         if (value.Get< bool >())
245         {
246           label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, false  );
247         }
248         else
249         {
250           label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, true  );
251         }
252       }
253     }
254
255   bool OnButtonClickedSmall( Toolkit::Button button )
256   {
257     EnableScrolling( SMALL );
258     return true;
259   }
260
261   bool OnButtonClickedLarge( Toolkit::Button button )
262   {
263     EnableScrolling( LARGE );
264     return true;
265   }
266
267   bool OnButtonClickedRtl( Toolkit::Button button )
268   {
269     EnableScrolling( RTL );
270     return true;
271   }
272
273   bool OnButtonClickedRtlLong( Toolkit::Button button )
274   {
275     EnableScrolling( RTL_LONG );
276     return true;
277   }
278
279   bool OnColorButtonClicked( Toolkit::Button button )
280  {
281    Vector4 color = Color::RED;
282
283   if ( mToggleColor )
284   {
285     color = Color::BLACK;
286     mToggleColor = false;
287   }
288   else
289   {
290     mToggleColor = true;
291   }
292
293   mSmallLabel.SetProperty( TextLabel::Property::SHADOW_COLOR, Color::BLACK );
294   mSmallLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
295   mLargeLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
296   mRtlLongLabel.SetProperty( TextLabel::Property::TEXT_COLOR, color );
297
298   return true;
299  }
300
301   /**
302    * Main key event handler
303    */
304   void OnKeyEvent(const KeyEvent& event)
305   {
306     if(event.state == KeyEvent::Down)
307     {
308       if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) )
309       {
310         mApplication.Quit();
311       }
312       else
313       {
314         if ( event.keyPressedName == "2" )
315         {
316           mAnimation.AnimateTo( Property( mSmallLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
317           mAnimation.AnimateTo( Property( mLargeLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
318           mAnimation.AnimateTo( Property( mRtlLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
319           mAnimation.AnimateTo( Property( mRtlLongLabel, Actor::Property::SCALE ), Vector3(1.2f, 1.2f, 0.0f), AlphaFunction::BOUNCE, TimePeriod( 1.0f, 1.0f ) );
320
321           mAnimation.Play();
322         }
323       }
324     }
325   }
326
327   void OnPanGesture( Actor actor, const PanGesture& gesture )
328   {
329     if( gesture.state == Gesture::Continuing )
330     {
331       Vector2 position = Vector2( gesture.displacement );
332       mTargetActorPosition.y = mTargetActorPosition.y + position.y;
333       mTargetActorPosition.y = std::min( mTargetActorPosition.y, -mTargetActorSize.height );
334       mTargetActorPosition.y = std::max( mTargetActorPosition.y, ( mTargetActorSize.height - mStageSize.height*0.25f ) );
335       actor.SetPosition( 0.0f, mTargetActorPosition.y );
336     }
337   }
338
339 private:
340
341   Application& mApplication;
342   PanGestureDetector mPanGestureDetector;
343
344   Vector2 mTargetActorPosition;
345   Vector2 mTargetActorSize;
346   Vector2 mStageSize;
347
348   TextLabel mLargeLabel;
349   TextLabel mSmallLabel;
350   TextLabel mRtlLabel;
351   TextLabel mRtlLongLabel;
352
353   Animation mAnimation;
354
355   bool mToggleColor;
356 };
357
358 void RunTest( Application& application )
359 {
360   TextScrollingExample test( application );
361
362   application.MainLoop();
363 }
364
365 /** Entry point for Linux & Tizen applications */
366 int DALI_EXPORT_API main( int argc, char **argv )
367 {
368   Application application = Application::New( &argc, &argv, DEMO_THEME_PATH );
369
370   RunTest( application );
371
372   return 0;
373 }