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