Merge "Removing unused variables" into devel/master
[platform/core/uifw/dali-demo.git] / examples / pre-render-callback / pre-render-callback-example.cpp
1 /*
2  * Copyright (c) 2020 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 #include <dali-toolkit/dali-toolkit.h>
18 #include <dali/integration-api/adaptor-framework/adaptor.h>
19 #include <dali/devel-api/adaptor-framework/application-devel.h>
20 #include <dali-toolkit/devel-api/controls/control-devel.h>
21
22 using namespace Dali::Toolkit;
23
24 namespace Dali
25 {
26 const char* SCENE_IMAGE_1( DEMO_IMAGE_DIR "gallery-small-10.jpg");
27 const char* SCENE_IMAGE_2( DEMO_IMAGE_DIR "gallery-small-42.jpg");
28 const char* SCENE_IMAGE_3( DEMO_IMAGE_DIR "gallery-small-48.jpg");
29 const char* ROTATE_TEXT("-\\|/");
30 const float TEXT_HEIGHT = 40.0f;
31
32 void AddText( Control textContainer, std::string text, unsigned int yIndex )
33 {
34   auto label = TextLabel::New(text);
35   label.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_CENTER );
36   label.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
37   label.SetProperty( Actor::Property::SIZE, Vector2( 300,TEXT_HEIGHT ) );
38   label.SetProperty( Actor::Property::POSITION_Y,  yIndex*TEXT_HEIGHT );
39   textContainer.Add( label );
40 }
41
42 class PreRenderCallbackController : public ConnectionTracker
43 {
44 public:
45
46   /**
47    * @brief Constructor.
48    * @param[in]  application  The application.
49    */
50   PreRenderCallbackController ( Application& application )
51   : mApplication( application ),
52     mWindow(),
53     mTapDetector(),
54     mKeepPreRender(false),
55     mRotateTextCharacter(0),
56     mLastRTC(-1),
57     mImageActor1(),
58     mImageActor2(),
59     mImageActor3(),
60     mAngle1Index( Property::INVALID_INDEX ),
61     mAngle3Index( Property::INVALID_INDEX ),
62     mSceneActor(),
63     mSceneAnimation(),
64     mSpinner()
65   {
66     // Connect to the Application's Init signal
67     mApplication.InitSignal().Connect( this, &PreRenderCallbackController::Create );
68   }
69
70 private:
71   struct RotationConstraint
72   {
73     RotationConstraint(float sign)
74     : mSign(sign)
75     {
76     }
77
78     void operator()( Quaternion& current, const PropertyInputContainer& inputs )
79     {
80       Radian angle( inputs[0]->GetFloat() );
81       current = Quaternion( angle * mSign, Vector3::YAXIS );
82     }
83
84     float mSign;
85   };
86
87   /**
88    * @brief Creates the scene.
89    */
90   void Create( Application& application )
91   {
92     mWindow = application.GetWindow();
93     mWindow.SetBackgroundColor( Color::WHITE );
94     mWindow.KeyEventSignal().Connect( this, &PreRenderCallbackController::OnKeyEvent );
95
96     // Detect taps on the root layer.
97     mTapDetector = TapGestureDetector::New();
98     mTapDetector.Attach( mWindow.GetRootLayer() );
99     mTapDetector.DetectedSignal().Connect( this, &PreRenderCallbackController::OnTap );
100
101     CreateAnimatingScene();
102
103     auto textContainer = Control::New();
104     textContainer.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::TOP_LEFT);
105     AddText(textContainer, "Click to add callback", 1 );
106     AddText(textContainer, "Press 1 to add callback", 2 );
107     AddText(textContainer, "Press 2 to clear callback", 3 );
108     AddText(textContainer, "Press 3 to toggle keep alive", 4 );
109
110
111     mSpinner = TextLabel::New("");
112     mSpinner.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
113     mSpinner.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
114     mSpinner.SetProperty( Actor::Property::SIZE, Vector2(100,100) );
115
116     mWindow.Add(mSpinner);
117     mWindow.Add(textContainer);
118
119     DevelApplication::AddIdleWithReturnValue( application, MakeCallback( this, &PreRenderCallbackController::OnIdle ) );
120   }
121
122   void CreateAnimatingScene()
123   {
124     mSceneActor = Layer::New();
125     mSceneActor.SetProperty( Layer::Property::BEHAVIOR, Layer::LAYER_3D );
126     mSceneActor.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::CENTER);
127
128     // Create and add images to the scene actor:
129     mImageActor1 = ImageView::New( SCENE_IMAGE_1 );
130     mImageActor2 = ImageView::New( SCENE_IMAGE_2 );
131     mImageActor3 = ImageView::New( SCENE_IMAGE_3 );
132
133     mImageActor1.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
134     mImageActor2.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
135     mImageActor3.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
136
137     mImageActor2.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::CENTER);
138
139     mImageActor1.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::CENTER_LEFT);
140     mImageActor1.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::CENTER_RIGHT);
141
142     mImageActor3.SetProperty( Actor::Property::PARENT_ORIGIN,ParentOrigin::CENTER_RIGHT);
143     mImageActor3.SetProperty( Actor::Property::ANCHOR_POINT,AnchorPoint::CENTER_LEFT);
144
145     mSceneActor.Add(mImageActor2);
146     mImageActor2.Add(mImageActor1);
147     mImageActor2.Add(mImageActor3);
148
149     Property::Index angleIndex = mImageActor2.RegisterProperty("angle", Property::Value( Dali::ANGLE_30 ) );
150     Source angleSrc( mImageActor2, angleIndex );
151
152     Constraint constraint = Constraint::New<Quaternion>( mImageActor1, Actor::Property::ORIENTATION, RotationConstraint(-1.0f) );
153     constraint.AddSource( angleSrc );
154     constraint.Apply();
155
156     constraint = Constraint::New<Quaternion>( mImageActor3, Actor::Property::ORIENTATION, RotationConstraint(+1.0f) );
157     constraint.AddSource( angleSrc );
158     constraint.Apply();
159
160     mSceneAnimation = Animation::New(2.5f);
161
162     // Want to animate angle from 30 => -30 and back again smoothly.
163     mSceneAnimation.AnimateTo( Property( mImageActor2, angleIndex ), Property::Value(-Dali::ANGLE_30), AlphaFunction::SIN );
164
165     mSceneAnimation.SetLooping(true);
166     mSceneAnimation.Play();
167
168     mSceneActor.SetProperty( Actor::Property::SIZE, Vector2(250.0f, 250.0f) );
169     mSceneActor.SetProperty( Actor::Property::POSITION, Vector3( 0.0f, 0.0f, 130.0f ) );
170     Quaternion p( Degree( -6.0f ), Vector3::XAXIS );
171     Quaternion q( Degree( 20.0f ), Vector3::YAXIS );
172     mSceneActor.SetProperty( Actor::Property::ORIENTATION, p * q );
173
174     mWindow.Add( mSceneActor );
175   }
176
177   void OnTap( Actor /* actor */, const TapGesture& /* tap */ )
178   {
179     Adaptor::Get().SetPreRenderCallback( MakeCallback( this, &PreRenderCallbackController::OnPreRender ) );
180   }
181
182   /**
183    * @brief Called when any key event is received
184    *
185    * Will use this to quit the application if Back or the Escape key is received
186    * @param[in] event The key event information
187    */
188   void OnKeyEvent( const KeyEvent& event )
189   {
190     if( event.GetState() == KeyEvent::DOWN )
191     {
192       if ( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
193       {
194         mApplication.Quit();
195       }
196       else if( event.GetKeyName().compare("1") == 0)
197       {
198         Adaptor::Get().SetPreRenderCallback( MakeCallback( this, &PreRenderCallbackController::OnPreRender ) );
199       }
200       else if( event.GetKeyName().compare("2") == 0)
201       {
202         Adaptor::Get().SetPreRenderCallback( NULL );
203       }
204       else if( event.GetKeyName().compare("3") == 0)
205       {
206         mKeepPreRender = !mKeepPreRender;
207       }
208     }
209   }
210
211   bool OnPreRender()
212   {
213     // Called from Update/Render thread
214     printf("Pre-render callback\n");
215     ++mRotateTextCharacter;
216     return mKeepPreRender;
217   }
218
219   bool OnIdle()
220   {
221     // Called from Event thread on main loop
222     int rotation = mRotateTextCharacter;
223     if( rotation != mLastRTC )
224     {
225       mLastRTC = rotation;
226       mSpinner.SetProperty(TextLabel::Property::TEXT, std::string(1, ROTATE_TEXT[rotation%4]));
227     }
228     return true;
229   }
230
231
232 private:
233   Application& mApplication;
234   Window mWindow;
235   TapGestureDetector  mTapDetector;          ///< Tap detector to enable the PreRenderCallback
236   bool mKeepPreRender;
237   int mRotateTextCharacter;
238   int mLastRTC;
239
240   // Scene objects:
241   ImageView                 mImageActor1;
242   ImageView                 mImageActor2;
243   ImageView                 mImageActor3;
244   Property::Index           mAngle1Index;
245   Property::Index           mAngle3Index;
246   Layer                     mSceneActor;
247   Animation                 mSceneAnimation;
248   TextLabel                 mSpinner;
249 };
250
251 } // namespace Dali
252
253 int DALI_EXPORT_API main( int argc, char **argv )
254 {
255   Dali::Application application = Dali::Application::New( &argc, &argv );
256   Dali::PreRenderCallbackController controller( application );
257   application.MainLoop();
258   return 0;
259 }