[dali_1.1.45] Merge branch 'devel/master'
[platform/core/uifw/dali-demo.git] / examples / text-scrolling / text-scrolling-example.cpp
1 /*
2  * Copyright (c) 2016 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
26 using namespace Dali;
27 using namespace Dali::Toolkit;
28
29 namespace
30 {
31 const char* DESKTOP_IMAGE( DEMO_IMAGE_DIR "woodEffect.jpg" );
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   {
59     // Connect to the Application's Init signal
60     mApplication.InitSignal().Connect( this, &TextScrollingExample::Create );
61   }
62
63   ~TextScrollingExample()
64   {
65     // Nothing to do here.
66   }
67
68
69   void CreateBox( const std::string& name, Actor& box, Actor parent, const Vector2& size )
70   {
71     box.SetName(name);
72     box.SetAnchorPoint( AnchorPoint::CENTER );
73     box.SetParentOrigin( ParentOrigin::CENTER );
74     box.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT );
75     box.SetResizePolicy( ResizePolicy::FIXED, Dimension::WIDTH );
76     box.SetSize( size.width, 0.f );
77     parent.Add( box );
78
79     Dali::Property::Map border;
80     border.Insert( Visual::Property::TYPE,  Visual::BORDER );
81     border.Insert( BorderVisual::Property::COLOR,  Color::WHITE );
82     border.Insert( BorderVisual::Property::SIZE,  1.f );
83     box.SetProperty( Control::Property::BACKGROUND, border );
84   }
85
86   void CreateLabel( Actor& label, const std::string text, Actor parent, bool scrollOnStart, PushButton button )
87   {
88     label = TextLabel::New( text );
89     label.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
90     label.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
91     label.SetPadding( Padding( 1.0f, 1.0f, 1.0f, 1.0f ) );
92     label.SetAnchorPoint( AnchorPoint::CENTER );
93     label.SetParentOrigin( ParentOrigin::CENTER );
94     parent.Add( label );
95
96     if ( scrollOnStart )
97     {
98       label.SetProperty(TextLabel::Property::ENABLE_AUTO_SCROLL, true);
99     }
100
101     button.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
102     button.SetSize(BOX_SIZE.height,BOX_SIZE.height);
103     button.SetParentOrigin( ParentOrigin::TOP_RIGHT );
104     button.SetAnchorPoint( AnchorPoint::TOP_LEFT );
105     parent.Add(button);
106   }
107
108
109   /**
110    * One-time setup in response to Application InitSignal.
111    */
112   void Create( Application& application )
113   {
114     Stage stage = Stage::GetCurrent();
115     mStageSize = stage.GetSize();
116
117     stage.KeyEventSignal().Connect(this, &TextScrollingExample::OnKeyEvent);
118
119     // Create Root actor
120     Actor rootActor = Actor::New();
121     rootActor.SetName("rootActor");
122     rootActor.SetResizePolicy( ResizePolicy::FIXED,  Dimension::ALL_DIMENSIONS );
123     rootActor.SetSize( mStageSize );
124     rootActor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
125
126     stage.Add( rootActor );
127
128     const Size mTargetActorSize( mStageSize.width, DESKTOP_SIZE.height );
129
130     // Create Desktop
131     ImageView desktop = ImageView::New();
132     Property::Map imageMap;
133     imageMap[ "url" ] = DESKTOP_IMAGE;
134     imageMap[ "synchronousLoading" ] = true;
135     desktop.SetProperty( ImageView::Property::IMAGE, imageMap );
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::WHITE );
176     mSmallLabel.SetProperty( TextLabel::Property::SHADOW_OFFSET, Vector2( 1.0f, 1.0f ) );
177     mSmallLabel.SetProperty( TextLabel::Property::SHADOW_COLOR, Color::BLACK );
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
191
192     mPanGestureDetector = PanGestureDetector::New();
193     mPanGestureDetector.DetectedSignal().Connect(this, &TextScrollingExample::OnPanGesture );
194     mPanGestureDetector.Attach( desktop );
195   }
196
197   void EnableScrolling( Labels labels )
198     {
199       Actor label;
200       switch( labels )
201       {
202         case LARGE:
203         {
204           label = mLargeLabel;
205           break;
206         }
207         case RTL:
208         {
209           label = mRtlLabel;
210           break;
211         }
212         case SMALL:
213         {
214           label = mSmallLabel;
215           break;
216         }
217         case RTL_LONG:
218         {
219           label = mRtlLongLabel;
220           break;
221         }
222         case NONE:
223         {
224           return;
225         }
226       }
227
228       if ( labels != NONE )
229       {
230         Property::Value value = label.GetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL);
231         if (value.Get< bool >())
232         {
233           label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, false  );
234         }
235         else
236         {
237           label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, true  );
238         }
239       }
240     }
241
242   bool OnButtonClickedSmall( Toolkit::Button button )
243   {
244     EnableScrolling( SMALL );
245     return true;
246   }
247
248   bool OnButtonClickedLarge( Toolkit::Button button )
249   {
250     EnableScrolling( LARGE );
251     return true;
252   }
253
254   bool OnButtonClickedRtl( Toolkit::Button button )
255   {
256     EnableScrolling( RTL );
257     return true;
258   }
259
260   bool OnButtonClickedRtlLong( Toolkit::Button button )
261   {
262     EnableScrolling( RTL_LONG );
263     return true;
264   }
265
266   /**
267    * Main key event handler
268    */
269   void OnKeyEvent(const KeyEvent& event)
270   {
271     if(event.state == KeyEvent::Down)
272     {
273       if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) )
274       {
275         mApplication.Quit();
276       }
277     }
278   }
279
280   void OnPanGesture( Actor actor, const PanGesture& gesture )
281   {
282     if( gesture.state == Gesture::Continuing )
283     {
284       Vector2 position = Vector2( gesture.displacement );
285       mTargetActorPosition.y = mTargetActorPosition.y + position.y;
286       mTargetActorPosition.y = std::min( mTargetActorPosition.y, -mTargetActorSize.height );
287       mTargetActorPosition.y = std::max( mTargetActorPosition.y, ( mTargetActorSize.height - mStageSize.height*0.25f ) );
288       actor.SetPosition( 0.0f, mTargetActorPosition.y );
289     }
290   }
291
292 private:
293
294   Application& mApplication;
295   PanGestureDetector mPanGestureDetector;
296
297   Vector2 mTargetActorPosition;
298   Vector2 mTargetActorSize;
299   Vector2 mStageSize;
300
301   TextLabel mLargeLabel;
302   TextLabel mSmallLabel;
303   TextLabel mRtlLabel;
304   TextLabel mRtlLongLabel;
305 };
306
307 void RunTest( Application& application )
308 {
309   TextScrollingExample test( application );
310
311   application.MainLoop();
312 }
313
314 /** Entry point for Linux & Tizen applications */
315 int DALI_EXPORT_API main( int argc, char **argv )
316 {
317   Application application = Application::New( &argc, &argv, DEMO_THEME_PATH );
318
319   RunTest( application );
320
321   return 0;
322 }