1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <event_handler.h>
17 #include <iostream>
18 #include <surface.h>
19
20 #include "wm/window.h"
21
22 #include "modifier/rs_extended_modifier.h"
23 #include "modifier/rs_property_modifier.h"
24 #include "render/rs_border.h"
25 #include "transaction/rs_transaction.h"
26 #include "ui/rs_display_node.h"
27 #include "ui/rs_root_node.h"
28 #include "ui/rs_surface_extractor.h"
29 #include "ui/rs_surface_node.h"
30 #include "ui/rs_ui_director.h"
31
32 using namespace OHOS;
33 using namespace OHOS::Rosen;
34 using namespace std;
35
36 std::shared_ptr<RSNode> rootNode;
37 std::vector<std::shared_ptr<RSCanvasNode>> nodes;
38
Init(std::shared_ptr<RSUIDirector> rsUiDirector,int width,int height)39 void Init(std::shared_ptr<RSUIDirector> rsUiDirector, int width, int height)
40 {
41 std::cout << "rs app demo Init Rosen Backend!" << std::endl;
42
43 rootNode = RSRootNode::Create();
44 rootNode->SetBounds(0, 0, width, height);
45 rootNode->SetFrame(0, 0, width, height);
46 rootNode->SetBackgroundColor(Drawing::Color::COLOR_YELLOW);
47
48 nodes.emplace_back(RSCanvasNode::Create());
49 nodes[0]->SetBounds(0, 0, 100, 100);
50 nodes[0]->SetFrame(0, 0, 100, 100);
51 nodes[0]->SetBackgroundColor(Drawing::Color::COLOR_BLUE);
52
53 rootNode->AddChild(nodes[0], -1);
54
55 nodes.emplace_back(RSCanvasNode::Create());
56 nodes[1]->SetBounds(0, 200, 200, 200);
57 nodes[1]->SetFrame(0, 200, 200, 200);
58 nodes[1]->SetBackgroundColor(Drawing::Color::COLOR_BLUE);
59
60 rootNode->AddChild(nodes[0], -1);
61 rootNode->AddChild(nodes[1], -1);
62 rsUiDirector->SetRoot(rootNode->GetId());
63 }
64
65 class MyData : public RSAnimatableArithmetic<MyData> {
66 public:
MyData()67 MyData() : data(0.f) {}
MyData(const float num)68 explicit MyData(const float num) : data(num) {}
69 virtual ~MyData() = default;
70
Add(const MyData & value) const71 MyData Add(const MyData& value) const override
72 {
73 float res = data + value.data;
74 return MyData(res);
75 }
Minus(const MyData & value) const76 MyData Minus(const MyData& value) const override
77 {
78 float res = data - value.data;
79 return MyData(res);
80 }
Multiply(const float scale) const81 MyData Multiply(const float scale) const override
82 {
83 float res = data * scale;
84 return MyData(res);
85 }
IsEqual(const MyData & value) const86 bool IsEqual(const MyData& value) const override
87 {
88 return data == value.data;
89 }
90
91 float data;
92 };
93
94 class MyModifier : public RSOverlayStyleModifier {
95 public:
96 MyModifier() = default;
97 ~MyModifier() = default;
Draw(RSDrawingContext & context) const98 void Draw(RSDrawingContext& context) const override
99 {
100 Drawing::Bitmap bitmap;
101 bitmap.Build(100, 100, Drawing::BitmapFormat {
102 Drawing::ColorType::COLORTYPE_N32, Drawing::AlphaType::ALPHATYPE_PREMUL});
103 Drawing::Surface surface;
104 surface.Bind(bitmap);
105 auto tempCanvas = surface.GetCanvas();
106 tempCanvas->Clear(0xffff3f7f);
107
108 Drawing::Brush tempBrush;
109 tempBrush.SetColor(Drawing::Color(0xff3fff7f));
110 tempCanvas->AttachBrush(tempBrush);
111 tempCanvas->DrawRect(Drawing::Rect(0, 0, 50, 50));
112
113 tempBrush.SetColor(Drawing::Color(0xffff3f7f));
114 tempCanvas->AttachBrush(tempBrush);
115 tempCanvas->DrawRect(Drawing::Rect(50, 50, 100, 100));
116 tempCanvas->DetachBrush();
117
118 auto image = surface.GetImageSnapshot();
119 if (image == nullptr) {
120 return;
121 }
122 Drawing::SamplingOptions sampling;
123 Drawing::Matrix matrix;
124 Drawing::Brush brush;
125 brush.SetShaderEffect(Drawing::ShaderEffect::CreateImageShader(
126 *image, Drawing::TileMode::REPEAT, Drawing::TileMode::REPEAT, sampling, matrix));
127 auto animatableProperty = std::static_pointer_cast<RSAnimatableProperty<MyData>>(property_);
128 brush.SetAlphaF(animatableProperty->Get().data);
129
130 std::cout << "MyModifier Draw property get " << animatableProperty->Get().data << std::endl;
131 context.canvas->AttachBrush(brush);
132 context.canvas->DrawRect(Drawing::Rect(0, 0, context.width, context.height));
133 context.canvas->DetachBrush();
134 }
135 };
136
137 class TransModifier : public RSGeometryTransModifier {
138 public:
139 TransModifier() = default;
140 ~TransModifier() = default;
141
GeometryEffect(float width,float height) const142 Drawing::Matrix GeometryEffect(float width, float height) const override
143 {
144 Drawing::Matrix matrix;
145 if (distance_) {
146 matrix.PreTranslate(distance_->Get(), distance_->Get());
147 std::cout << "TransModifier GeometryEffect, distance:"<< distance_->Get() << std::endl;
148 }
149
150 return matrix;
151 }
152
SetTrans(float distance)153 void SetTrans(float distance)
154 {
155 if (distance_ == nullptr) {
156 distance_ = std::make_shared<RSAnimatableProperty<float>>(distance);
157 AttachProperty(distance_);
158 } else {
159 distance_->Set(distance);
160 }
161 }
162 private:
163 std::shared_ptr<RSAnimatableProperty<float>> distance_;
164 };
165
166 class CustomModifier : public RSContentStyleModifier {
167 public:
168 CustomModifier() = default;
169 ~CustomModifier() = default;
170
Draw(RSDrawingContext & context) const171 void Draw(RSDrawingContext& context) const override
172 {
173 if (!alpha_ || !width_ || !height_ || !backgroundColor_) {
174 Drawing::Rect rect;
175 Drawing::Brush brush;
176 context.canvas->AttachBrush(brush);
177 context.canvas->DrawRect(rect);
178 context.canvas->DetachBrush();
179 return;
180 }
181 Drawing::Rect rect(0, 0, width_->Get(), height_->Get());
182 Drawing::Brush brush;
183 brush.SetColor(backgroundColor_->Get().AsArgbInt());
184 brush.SetAlphaF(alpha_->Get());
185 context.canvas->AttachBrush(brush);
186 context.canvas->DrawRect(rect);
187 context.canvas->DetachBrush();
188
189 std::cout << "Draw Get alpha_ " << alpha_->Get() << std::endl;
190 std::cout << "Draw Get width_ " << width_->Get() << std::endl;
191 std::cout << "Draw Get height_ " << height_->Get() << std::endl;
192 std::cout << "Draw Get backgroundColor_ " << std::hex << backgroundColor_->Get().AsArgbInt() << std::endl;
193 }
194
SetAlpha(float alpha)195 void SetAlpha(float alpha)
196 {
197 if (alpha_ == nullptr) {
198 alpha_ = std::make_shared<RSAnimatableProperty<float>>(alpha);
199 AttachProperty(alpha_);
200 } else {
201 alpha_->Set(alpha);
202 }
203 }
204
SetWidth(float width)205 void SetWidth(float width)
206 {
207 if (width_ == nullptr) {
208 width_ = std::make_shared<RSAnimatableProperty<float>>(width);
209 AttachProperty(width_);
210 } else {
211 width_->Set(width);
212 }
213 }
214
SetHeight(float height)215 void SetHeight(float height)
216 {
217 if (height_ == nullptr) {
218 height_ = std::make_shared<RSAnimatableProperty<float>>(height);
219 AttachProperty(height_);
220 } else {
221 height_->Set(height);
222 }
223 }
224
SetBackgroundColor(Color color)225 void SetBackgroundColor(Color color)
226 {
227 if (backgroundColor_ == nullptr) {
228 backgroundColor_ = std::make_shared<RSAnimatableProperty<Color>>(color);
229 AttachProperty(backgroundColor_);
230 } else {
231 backgroundColor_->Set(color);
232 }
233 }
234
235 private:
236 std::shared_ptr<RSAnimatableProperty<float>> alpha_;
237 std::shared_ptr<RSAnimatableProperty<float>> width_;
238 std::shared_ptr<RSAnimatableProperty<float>> height_;
239 std::shared_ptr<RSAnimatableProperty<Color>> backgroundColor_;
240 };
241
242 class NodeModifier : public RSNodeModifier {
243 public:
244 NodeModifier() = default;
245 virtual ~NodeModifier() = default;
246
Modify(RSNode & target) const247 void Modify(RSNode& target) const override
248 {
249 target.SetAlpha(alpha_->Get());
250 target.SetScale(scale_->Get());
251 target.SetBackgroundColor(color_->Get().AsArgbInt());
252 }
253
SetAlpha(float alpha)254 void SetAlpha(float alpha)
255 {
256 if (alpha_ == nullptr) {
257 alpha_ = std::make_shared<RSAnimatableProperty<float>>(alpha);
258 AttachProperty(alpha_);
259 } else {
260 alpha_->Set(alpha);
261 }
262 }
263
SetScale(Vector2f scale)264 void SetScale(Vector2f scale)
265 {
266 if (scale_ == nullptr) {
267 scale_ = std::make_shared<RSAnimatableProperty<Vector2f>>(scale);
268 AttachProperty(scale_);
269 } else {
270 scale_->Set(scale);
271 }
272 }
273
SetColor(Color color)274 void SetColor(Color color)
275 {
276 if (color_ == nullptr) {
277 color_ = std::make_shared<RSAnimatableProperty<Color>>(color);
278 AttachProperty(color_);
279 } else {
280 color_->Set(color);
281 }
282 }
283
284 private:
285 std::shared_ptr<RSAnimatableProperty<float>> alpha_;
286 std::shared_ptr<RSAnimatableProperty<Vector2f>> scale_;
287 std::shared_ptr<RSAnimatableProperty<Color>> color_;
288 };
289
main()290 int main()
291 {
292 int cnt = 0;
293
294 // Init demo env
295 std::cout << "rs app demo start!" << std::endl;
296 sptr<WindowOption> option = new WindowOption();
297 option->SetWindowType(WindowType::WINDOW_TYPE_FLOAT);
298 option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
299 option->SetWindowRect({ 0, 0, 720, 1280 });
300 auto window = Window::Create("app_demo", option);
301 window->Show();
302 auto rect = window->GetRect();
303 while (rect.width_ == 0 && rect.height_ == 0) {
304 std::cout << "rs app demo create window failed: " << rect.width_ << " " << rect.height_ << std::endl;
305 window->Hide();
306 window->Destroy();
307 window = Window::Create("app_demo", option);
308 window->Show();
309 rect = window->GetRect();
310 }
311 std::cout << "rs app demo create window " << rect.width_ << " " << rect.height_ << std::endl;
312 auto surfaceNode = window->GetSurfaceNode();
313
314 // Build rosen renderThread & create nodes
315 std::cout << "rs app demo stage " << cnt++ << std::endl;
316 auto rsUiDirector = RSUIDirector::Create();
317 rsUiDirector->Init();
318 auto runner = OHOS::AppExecFwk::EventRunner::Create(true);
319 auto handler = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
320 rsUiDirector->SetUITaskRunner(
321 [handler](const std::function<void()>& task, uint32_t delay) { handler->PostTask(task); });
322 runner->Run();
323 RSTransaction::FlushImplicitTransaction();
324 rsUiDirector->SetRSSurfaceNode(surfaceNode);
325 Init(rsUiDirector, rect.width_, rect.height_);
326
327 // change property in nodes [setter using modifier]
328 std::cout << "rs app demo stage " << cnt++ << std::endl;
329 nodes[0]->SetBounds(0, 0, 200, 200);
330 nodes[0]->SetFrame(0, 0, 200, 200);
331 nodes[0]->SetBorderColor(Drawing::Color::COLOR_BLACK);
332 nodes[0]->SetBorderWidth(10);
333 nodes[0]->SetBorderStyle((uint32_t)BorderStyle::SOLID);
334 rsUiDirector->SendMessages();
335 sleep(1);
336
337 std::cout << "rs app demo stage " << cnt++ << std::endl;
338
339 // multi-property modifier
340 auto customModifier = std::make_shared<CustomModifier>();
341 // add modifier to node
342 nodes[0]->AddModifier(customModifier);
343 // init property
344 customModifier->SetAlpha(0);
345 customModifier->SetWidth(0);
346 customModifier->SetHeight(0);
347 customModifier->SetBackgroundColor(Color(0, 0, 255));
348
349 RSAnimationTimingProtocol protocol;
350 protocol.SetDuration(3000);
351
352 // create property animation
353 RSNode::Animate(protocol, RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
354 customModifier->SetAlpha(0.8);
355 customModifier->SetWidth(720);
356 customModifier->SetHeight(1280);
357 customModifier->SetBackgroundColor(Color(255, 0, 0));
358 }, []() {
359 std::cout<<"custom animation 1 finish callback"<<std::endl;
360 });
361
362 int64_t startNum = 80825861106;
363 bool hasRunningAnimation = true;
364 while (hasRunningAnimation) {
365 hasRunningAnimation = rsUiDirector->FlushAnimation(startNum);
366 rsUiDirector->FlushModifier();
367 rsUiDirector->SendMessages();
368 startNum += 100000000;
369 usleep(100000);
370 }
371 sleep(2);
372
373 auto nodeModifier = std::make_shared<NodeModifier>();
374 nodes[1]->AddModifier(nodeModifier);
375 nodeModifier->SetAlpha(1);
376 nodeModifier->SetScale(Vector2f(1.f, 1.f));
377 nodeModifier->SetColor(Color(0, 255, 0));
378 rsUiDirector->FlushAnimation(0);
379 rsUiDirector->FlushModifier();
380 rsUiDirector->SendMessages();
381 sleep(3);
382
383 // create property animation
384 RSNode::Animate(protocol, RSAnimationTimingCurve::EASE_IN_OUT, [&]() {
385 nodeModifier->SetAlpha(0.2);
386 nodeModifier->SetScale(Vector2f(3.f, 3.f));
387 nodeModifier->SetColor(Color(255, 0, 255));
388 }, []() {
389 std::cout<<"custom animation 2 finish callback"<<std::endl;
390 });
391
392 hasRunningAnimation = true;
393 while (hasRunningAnimation) {
394 hasRunningAnimation = rsUiDirector->FlushAnimation(startNum);
395 rsUiDirector->FlushModifier();
396 rsUiDirector->SendMessages();
397 startNum += 100000000;
398 usleep(100000);
399 }
400
401 // dump property via modifiers
402 std::cout << "rs app demo stage " << cnt++ << std::endl;
403 std::cout << nodes[0]->GetStagingProperties().Dump() << std::endl;
404 std::cout << "rs app demo end!" << std::endl;
405 sleep(3);
406
407 window->Hide();
408 window->Destroy();
409 return 0;
410 }
411