Further Setter/Getter public API removal from Dali::Actor
[platform/core/uifw/dali-demo.git] / examples / frame-callback / frame-callback-example.cpp
1 /*
2  * Copyright (c) 2018 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 // EXTERNAL INCLUDES
19 #include <dali-toolkit/dali-toolkit.h>
20 #include <dali/devel-api/common/stage-devel.h>
21
22 // INTERNAL INCLUDES
23 #include "frame-callback.h"
24
25 using namespace Dali;
26 using namespace Dali::Toolkit;
27
28 namespace
29 {
30 const char * IMAGE_NAME = DEMO_IMAGE_DIR "application-icon-1.png";
31
32 const char * TEXT_ENABLED( "FrameCallback: ON" );
33 const char * TEXT_DISABLED( "FrameCallback: OFF" );
34 Vector4 TEXT_COLOR_ENABLED( Color::BLACK );
35 Vector4 TEXT_COLOR_DISABLED( Color::RED );
36
37 float ANIMATION_TIME( 4.0f );
38 float ANIMATION_PROGRESS_MULTIPLIER( 0.02f );
39 } // unnamed namespace
40
41 /**
42  * @brief An example of how to set/unset the FrameCallbackInterface in DALi.
43  *
44  * Creates a scene with several image-views which are animated from side-to-side.
45  * With the frame-callback enabled, the image-views' sizes expand as they hits the sides and the opacity
46  * changes to transparent as they go to the middle.
47  */
48 class FrameCallbackController : public ConnectionTracker
49 {
50 public:
51
52   /**
53    * @brief Constructor.
54    * @param[in]  application  The application.
55    */
56   FrameCallbackController( Application& application )
57   : mApplication( application ),
58     mStage(),
59     mFrameCallback(),
60     mTextLabel(),
61     mTapDetector(),
62     mFrameCallbackEnabled( false )
63   {
64     // Connect to the Application's Init signal
65     mApplication.InitSignal().Connect( this, &FrameCallbackController::Create );
66   }
67
68 private:
69
70   /**
71    * @brief Creates the scene.
72    *
73    * Creates several image-views and places them appropriately.
74    * Animate all image-views.
75    * Set the FrameCallbackInterface on the stage.
76    * Tapping on the stage enables/disables the FrameCallback.
77    */
78   void Create( Application& /* application */ )
79   {
80     // Hide the indicator bar.
81     mApplication.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
82
83     // Set the stage background color and connect to the stage's key signal to allow Back and Escape to exit.
84     mStage = Stage::GetCurrent();
85     mStage.SetBackgroundColor( Color::WHITE );
86     mStage.KeyEventSignal().Connect( this, &FrameCallbackController::OnKeyEvent );
87
88     // Notify mFrameCallback about the stage width.
89     // Can call methods in mFrameCallback directly as we have not set it on the stage yet.
90     Vector2 stageSize = mStage.GetSize();
91     mFrameCallback.SetStageWidth( stageSize.width );
92
93     // Detect taps on the root layer.
94     mTapDetector = TapGestureDetector::New();
95     mTapDetector.Attach( mStage.GetRootLayer() );
96     mTapDetector.DetectedSignal().Connect( this, &FrameCallbackController::OnTap );
97
98     // Create some key-frames to be used by all animations.
99     KeyFrames keyFrames = KeyFrames::New();
100     keyFrames.Add( 0.0f,   0.0f );
101     keyFrames.Add( 0.25f,  stageSize.width * 0.5f );
102     keyFrames.Add( 0.75f, -stageSize.width * 0.5f );
103     keyFrames.Add( 1.0f,   0.0f );
104
105     float yPos = 0.0f;
106     for( int i = 0; yPos < stageSize.height; ++i )
107     {
108       ImageView imageView = ImageView::New( IMAGE_NAME );
109       imageView.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_CENTER );
110       imageView.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER );
111       imageView.SetProperty( Actor::Property::POSITION_Y,  yPos );
112       yPos += imageView.GetNaturalSize().height;
113
114       // Add the ID of the created ImageView to mFrameCallback.
115       // Again, can call methods in mFrameCallback directly as we have not set it on the stage yet.
116       mFrameCallback.AddId( imageView.GetId() );
117
118       mStage.Add( imageView );
119
120       // Create an animation and set the progress so that each image starts at a different point.
121       Animation animation = Animation::New( ANIMATION_TIME );
122       animation.SetLooping( true );
123       animation.AnimateBetween( Property( imageView, Actor::Property::POSITION_X ), keyFrames );
124       animation.SetCurrentProgress( std::min( 1.0f, ANIMATION_PROGRESS_MULTIPLIER * i ) );
125       animation.Play();
126     }
127
128     // Create a text-label to display whether the FrameCallback is enabled/disabled.
129     mTextLabel = TextLabel::New( TEXT_ENABLED );
130     mTextLabel.SetProperty( TextLabel::Property::TEXT_COLOR, TEXT_COLOR_ENABLED );
131     mTextLabel.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
132     mTextLabel.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
133     mTextLabel.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
134     mStage.Add( mTextLabel );
135
136     // Set the FrameCallbackInterface on the root layer.
137     DevelStage::AddFrameCallback( mStage, mFrameCallback, mStage.GetRootLayer() );
138     mFrameCallbackEnabled = true;
139   }
140
141   /**
142    * @brief Called when a tap on the stage occurs.
143    *
144    * Toggle enabling/disabling of the FrameCallbackInterface
145    */
146   void OnTap( Actor /* actor */, const TapGesture& /* tap */ )
147   {
148     if( mFrameCallbackEnabled )
149     {
150       DevelStage::RemoveFrameCallback( mStage, mFrameCallback );
151       mTextLabel.SetProperty( TextLabel::Property::TEXT, TEXT_DISABLED );
152       mTextLabel.SetProperty( TextLabel::Property::TEXT_COLOR, TEXT_COLOR_DISABLED );
153     }
154     else
155     {
156       DevelStage::AddFrameCallback( mStage, mFrameCallback, mStage.GetRootLayer() );
157       mTextLabel.SetProperty( TextLabel::Property::TEXT, TEXT_ENABLED );
158       mTextLabel.SetProperty( TextLabel::Property::TEXT_COLOR, TEXT_COLOR_ENABLED );
159     }
160
161     mFrameCallbackEnabled = !mFrameCallbackEnabled;
162   }
163
164   /**
165    * @brief Called when any key event is received
166    *
167    * Will use this to quit the application if Back or the Escape key is received
168    * @param[in] event The key event information
169    */
170   void OnKeyEvent( const KeyEvent& event )
171   {
172     if( event.state == KeyEvent::Down )
173     {
174       if ( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
175       {
176         mApplication.Quit();
177       }
178     }
179   }
180
181 private:
182   Application&        mApplication;          ///< A reference to the application instance.
183   Stage               mStage;                ///< The stage we enable the FrameCallback on.
184   FrameCallback       mFrameCallback;        ///< An instance of our implementation of the FrameCallbackInterface.
185   TextLabel           mTextLabel;            ///< Text label which shows whether the frame-callback is enabled/disabled.
186   TapGestureDetector  mTapDetector;          ///< Tap detector to enable/disable the FrameCallbackInterface.
187   bool                mFrameCallbackEnabled; ///< Stores whether the FrameCallbackInterface is enabled/disabled.
188 };
189
190 int DALI_EXPORT_API main( int argc, char **argv )
191 {
192   Application application = Application::New( &argc, &argv );
193   FrameCallbackController controller( application );
194   application.MainLoop();
195   return 0;
196 }