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 <iostream>
17 #include <surface.h>
18
19 #include "include/core/SkBitmap.h"
20 #include "include/core/SkCanvas.h"
21 #include "include/core/SkColor.h"
22 #include "include/core/SkImage.h"
23 #include "include/core/SkImageInfo.h"
24 #include "include/core/SkPaint.h"
25 #include "include/core/SkRect.h"
26 #include "include/core/SkTileMode.h"
27 #include "wm/window.h"
28
29 #include "animation/rs_ui_animation_manager.h"
30 #include "modifier/rs_extended_modifier.h"
31 #include "modifier/rs_property_modifier.h"
32 #include "render/rs_border.h"
33 #include "transaction/rs_transaction.h"
34 #include "ui/rs_display_node.h"
35 #include "ui/rs_root_node.h"
36 #include "ui/rs_surface_extractor.h"
37 #include "ui/rs_surface_node.h"
38 #include "ui/rs_ui_director.h"
39
40 using namespace OHOS;
41 using namespace OHOS::Rosen;
42 using namespace std;
43
44 std::shared_ptr<RSNode> rootNode;
45 std::vector<std::shared_ptr<RSCanvasNode>> nodes;
46
Init(std::shared_ptr<RSUIDirector> rsUiDirector,int width,int height)47 void Init(std::shared_ptr<RSUIDirector> rsUiDirector, int width, int height)
48 {
49 std::cout << "rs app demo Init Rosen Backend!" << std::endl;
50
51 rootNode = RSRootNode::Create();
52 rootNode->SetBounds(0, 0, width, height);
53 rootNode->SetFrame(0, 0, width, height);
54 rootNode->SetBackgroundColor(SK_ColorYELLOW);
55
56 nodes.emplace_back(RSCanvasNode::Create());
57 nodes[0]->SetBounds(0, 0, 100, 100);
58 nodes[0]->SetFrame(0, 0, 100, 100);
59 nodes[0]->SetBackgroundColor(SK_ColorBLUE);
60
61 rootNode->AddChild(nodes[0], -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 SkBitmap bitmap;
101 bitmap.allocN32Pixels(100, 100);
102 bitmap.eraseColor(0xffff7f3f);
103 bitmap.erase(0xff3fff7f, SkIRect::MakeWH(50, 50));
104 bitmap.erase(0xffff3f7f, SkIRect::MakeXYWH(50, 50, 50, 50));
105 SkPaint p;
106 p.setShader(bitmap.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat));
107 auto animatableProperty = std::static_pointer_cast<RSAnimatableProperty<MyData>>(property_);
108 p.setAlphaf(animatableProperty->Get().data);
109 std::cout << "MyModifier Draw property get " << animatableProperty->Get().data << std::endl;
110 context.canvas->drawRect(SkRect::MakeWH(context.width, context.height), p);
111 }
112 };
113
114 class CustomModifier : public RSContentStyleModifier {
115 public:
116 CustomModifier() = default;
117 ~CustomModifier() = default;
118
Draw(RSDrawingContext & context) const119 void Draw(RSDrawingContext& context) const override
120 {
121 if (!alpha_ || !width_ || !height_ || !backgroundColor_) {
122 SkRect rect = SkRect::MakeXYWH(0, 0, 0, 0);
123 SkPaint p;
124 context.canvas->drawRect(rect, p);
125 return;
126 }
127 SkRect rect = SkRect::MakeXYWH(0, 0, width_->Get(), height_->Get());
128 SkPaint p;
129 p.setColor(backgroundColor_->Get().AsArgbInt());
130 p.setAlphaf(alpha_->Get());
131 context.canvas->drawRect(rect, p);
132
133 std::cout << "Draw Get alpha_ " << alpha_->Get() << std::endl;
134 std::cout << "Draw Get width_ " << width_->Get() << std::endl;
135 std::cout << "Draw Get height_ " << height_->Get() << std::endl;
136 std::cout << "Draw Get backgroundColor_ " << std::hex << backgroundColor_->Get().AsArgbInt() << std::endl;
137 }
138
SetAlpha(float alpha)139 void SetAlpha(float alpha)
140 {
141 if (alpha_ == nullptr) {
142 alpha_ = std::make_shared<RSAnimatableProperty<float>>(alpha);
143 AttachProperty(alpha_);
144 } else {
145 alpha_->Set(alpha);
146 }
147 }
148
SetWidth(float width)149 void SetWidth(float width)
150 {
151 if (width_ == nullptr) {
152 width_ = std::make_shared<RSAnimatableProperty<float>>(width);
153 AttachProperty(width_);
154 } else {
155 width_->Set(width);
156 }
157 }
158
SetHeight(float height)159 void SetHeight(float height)
160 {
161 if (height_ == nullptr) {
162 height_ = std::make_shared<RSAnimatableProperty<float>>(height);
163 AttachProperty(height_);
164 } else {
165 height_->Set(height);
166 }
167 }
168
SetBackgroundColor(Color color)169 void SetBackgroundColor(Color color)
170 {
171 if (backgroundColor_ == nullptr) {
172 backgroundColor_ = std::make_shared<RSAnimatableProperty<Color>>(color);
173 AttachProperty(backgroundColor_);
174 } else {
175 backgroundColor_->Set(color);
176 }
177 }
178
179 private:
180 std::shared_ptr<RSAnimatableProperty<float>> alpha_;
181 std::shared_ptr<RSAnimatableProperty<float>> width_;
182 std::shared_ptr<RSAnimatableProperty<float>> height_;
183 std::shared_ptr<RSAnimatableProperty<Color>> backgroundColor_;
184 };
185
main()186 int main()
187 {
188 int cnt = 0;
189
190 // Init demo env
191 std::cout << "rs app demo start!" << std::endl;
192 sptr<WindowOption> option = new WindowOption();
193 option->SetWindowType(WindowType::WINDOW_TYPE_FLOAT);
194 option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
195 option->SetWindowRect({ 0, 0, 720, 1280 });
196 auto window = Window::Create("app_demo", option);
197 window->Show();
198 auto rect = window->GetRect();
199 while (rect.width_ == 0 && rect.height_ == 0) {
200 std::cout << "rs app demo create window failed: " << rect.width_ << " " << rect.height_ << std::endl;
201 window->Hide();
202 window->Destroy();
203 window = Window::Create("app_demo", option);
204 window->Show();
205 rect = window->GetRect();
206 }
207 std::cout << "rs app demo create window " << rect.width_ << " " << rect.height_ << std::endl;
208 auto surfaceNode = window->GetSurfaceNode();
209
210 // Build rosen renderThread & create nodes
211 std::cout << "rs app demo stage " << cnt++ << std::endl;
212 auto rsUiDirector = RSUIDirector::Create();
213 rsUiDirector->Init();
214 RSTransaction::FlushImplicitTransaction();
215 rsUiDirector->SetRSSurfaceNode(surfaceNode);
216 Init(rsUiDirector, rect.width_, rect.height_);
217
218 // change property in nodes [setter using modifier]
219 std::cout << "rs app demo stage " << cnt++ << std::endl;
220 nodes[0]->SetBounds(0, 0, 200, 200);
221 nodes[0]->SetFrame(0, 0, 200, 200);
222 nodes[0]->SetBorderColor(SK_ColorBLACK);
223 nodes[0]->SetBorderWidth(10);
224 nodes[0]->SetBorderStyle((uint32_t)BorderStyle::SOLID);
225 rsUiDirector->SendMessages();
226 sleep(1);
227
228 std::cout << "rs app demo stage " << cnt++ << std::endl;
229
230 // multi-property modifier
231 auto customModifier = std::make_shared<CustomModifier>();
232 // add modifier to node
233 nodes[0]->AddModifier(customModifier);
234 // init property
235 customModifier->SetAlpha(0);
236 customModifier->SetWidth(0);
237 customModifier->SetHeight(0);
238 customModifier->SetBackgroundColor(Color(0, 0, 255));
239
240 RSAnimationTimingProtocol protocol;
241 protocol.SetDuration(3000);
242
243 // create property animation
244 RSNode::OpenImplicitAnimation(protocol, RSAnimationTimingCurve::LINEAR, []() {});
245 customModifier->SetAlpha(0.8);
246 RSNode::CloseImplicitAnimation();
247
248 RSNode::OpenImplicitAnimation(protocol, RSAnimationTimingCurve::LINEAR, []() {});
249 customModifier->SetWidth(720);
250 RSNode::CloseImplicitAnimation();
251
252 RSNode::OpenImplicitAnimation(protocol, RSAnimationTimingCurve::LINEAR, []() {});
253 customModifier->SetHeight(1280);
254 RSNode::CloseImplicitAnimation();
255
256 RSNode::OpenImplicitAnimation(protocol, RSAnimationTimingCurve::LINEAR, []() {});
257 customModifier->SetBackgroundColor(Color(255, 0, 0));
258 RSNode::CloseImplicitAnimation();
259
260 int64_t startNum = 80825861106;
261 bool hasRunningAnimation = true;
262 while (hasRunningAnimation) {
263 hasRunningAnimation = rsUiDirector->RunningCustomAnimation(startNum);
264 rsUiDirector->SendMessages();
265 startNum += 100000000;
266 usleep(100000);
267 }
268
269 // dump property via modifiers
270 std::cout << "rs app demo stage " << cnt++ << std::endl;
271 std::cout << nodes[0]->GetStagingProperties().Dump() << std::endl;
272 std::cout << "rs app demo end!" << std::endl;
273 sleep(3);
274
275 window->Hide();
276 window->Destroy();
277 return 0;
278 }
279