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