• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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