• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "include/core/SkCanvas.h"
21 #include "include/core/SkColor.h"
22 #include "window.h"
23 
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(SK_ColorYELLOW);
47 
48     nodes.emplace_back(RSCanvasNode::Create());
49     nodes[0]->SetBounds(10, 10, 100, 100);
50     nodes[0]->SetFrame(10, 10, 100, 100);
51     nodes[0]->SetBackgroundColor(SK_ColorBLUE);
52 
53     rootNode->AddChild(nodes[0], -1);
54 
55     rootNode->AddChild(nodes[0], -1);
56     rsUiDirector->SetRSRootNode(rootNode->ReinterpretCastTo<RSRootNode>());
57 }
58 
59 class NodeModifier : public RSNodeModifier {
60 public:
61     NodeModifier() = default;
62     virtual ~NodeModifier() = default;
63 
Modify(RSNode & target) const64     void Modify(RSNode& target) const override
65     {
66         target.SetTranslate(translate_->Get());
67     }
68 
SetTranslate(Vector2f translate)69     void SetTranslate(Vector2f translate)
70     {
71         if (translate_ == nullptr) {
72             translate_ = std::make_shared<RSAnimatableProperty<Vector2f>>(translate);
73             AttachProperty(translate_);
74         } else {
75             translate_->Set(translate);
76         }
77     }
78 
GetTranslate() const79     Vector2f GetTranslate() const
80     {
81         return currentTranslateValue_;
82     }
83 
SetTranslateCallBack()84     bool SetTranslateCallBack()
85     {
86         if (!translate_) {
87             return false;
88         }
89 
90         // add callback for each frame
91         translate_->SetUpdateCallback([&](Vector2f vec) { currentTranslateValue_ = vec; });
92         return true;
93     }
94 
95     Vector2f currentTranslateValue_ = Vector2f(0.0f, 0.0f);
96 
97 private:
98     std::shared_ptr<RSAnimatableProperty<Vector2f>> translate_;
99 };
100 
main()101 int main()
102 {
103     int cnt = 0;
104 
105     // Init demo env
106     std::cout << "rs app demo start!" << std::endl;
107     sptr<WindowOption> option = new WindowOption();
108     option->SetWindowType(WindowType::WINDOW_TYPE_FLOAT);
109     option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
110     option->SetWindowRect({ 0, 0, 720, 1280 });
111     auto window = Window::Create("app_demo", option);
112     window->Show();
113     auto rect = window->GetRect();
114     while (rect.width_ == 0 && rect.height_ == 0) {
115         std::cout << "rs app demo create window failed: " << rect.width_ << " " << rect.height_ << std::endl;
116         window->Hide();
117         window->Destroy();
118         window = Window::Create("app_demo", option);
119         window->Show();
120         rect = window->GetRect();
121     }
122     std::cout << "rs app demo create window " << rect.width_ << " " << rect.height_ << std::endl;
123     auto surfaceNode = window->GetSurfaceNode();
124 
125     // Build rosen renderThread & create nodes
126     std::cout << "rs app demo stage " << cnt++ << std::endl;
127     auto rsUiDirector = RSUIDirector::Create();
128     rsUiDirector->Init();
129     auto runner = OHOS::AppExecFwk::EventRunner::Create(true);
130     auto handler = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
131     rsUiDirector->SetUITaskRunner(
132         [handler](const std::function<void()>& task, uint32_t delay) { handler->PostTask(task); });
133     runner->Run();
134     RSTransaction::FlushImplicitTransaction();
135     rsUiDirector->SetRSSurfaceNode(surfaceNode);
136     Init(rsUiDirector, rect.width_, rect.height_);
137 
138     std::cout << "rs app demo stage " << cnt++ << std::endl;
139 
140     // simulate sliding trajecity
141     int pointsNum = 30;
142     vector<Vector2f> handPoint(pointsNum);
143     for (int i = 0; i < handPoint.size(); i++) {
144         handPoint[i].data_[0] = 0.0f;
145         handPoint[i].data_[1] = 0.5f * i * i;
146     }
147 
148     // simulate sliding stage
149     for (auto vec : handPoint) {
150         nodes[0]->SetTranslate(vec);
151         rsUiDirector->SendMessages();
152         usleep(30000);
153     }
154 
155     // calculate sliding velocity
156     auto velocity = (handPoint[pointsNum - 1] - handPoint[pointsNum - 2]) * (1.0f / (30000.0f * 1e-6));
157 
158     // calculate final points
159     Vector2f finalTrans = handPoint[pointsNum - 1] + velocity * 0.5;
160 
161     std::cout << "rs app demo stage " << cnt++ << std::endl;
162 
163     auto nodeModifier = std::make_shared<NodeModifier>();
164     nodes[0]->AddModifier(nodeModifier);
165 
166     // init property
167     nodes[0]->SetTranslate(handPoint[pointsNum - 1]);
168 
169     RSAnimationTimingProtocol protocol;
170     // duration is not effective when the curve is interpolatingSpring
171     protocol.SetDuration(3000);
172 
173     auto timingCurve = RSAnimationTimingCurve::CreateInterpolatingSpring(1.0f, 225.0f, 30.0f, 2.0f);
174 
175     // create property animation
176     RSNode::Animate(
177         protocol, timingCurve,
178         [&]() {
179             std::cout << "the end tranlate of sliding animation is " << finalTrans.data_[0] << ", "
180                       << finalTrans.data_[1] << std::endl;
181             nodeModifier->SetTranslate(finalTrans);
182         },
183         []() { std::cout << "sliding animation finish callback" << std::endl; });
184 
185     int64_t startNum = 80825861106;
186     int64_t interruptNum = 80825861106 * 15;
187 
188     bool hasRunningAnimation = true;
189     bool stopSignal = true;
190 
191     while (hasRunningAnimation) {
192         hasRunningAnimation = rsUiDirector->FlushAnimation(startNum);
193         rsUiDirector->FlushModifier();
194         rsUiDirector->SendMessages();
195         std::cout << "the current translate is " << nodeModifier->GetTranslate().data_[0] << ", "
196                   << nodeModifier->GetTranslate().data_[1] << endl;
197 
198         // simulate to stop animation by gesture
199         if ((startNum >= interruptNum) && stopSignal) {
200             std::cout << "stop sliding animation in current translate " << nodeModifier->GetTranslate().data_[0] << ", "
201                       << nodeModifier->GetTranslate().data_[1] << endl;
202 
203             // set duration to 0
204             protocol.SetDuration(0);
205 
206             // create interrupt animation
207             RSNode::Animate(
208                 protocol, RSAnimationTimingCurve::EASE_IN_OUT,
209                 [&]() { nodeModifier->SetTranslate(nodeModifier->GetTranslate()); },
210                 [&]() {
211                     std::cout << "interrupt animation finish callback, the end translate is "
212                               << nodeModifier->GetTranslate().data_[0] << ", " << nodeModifier->GetTranslate().data_[1]
213                               << std::endl;
214                 });
215 
216             stopSignal = false;
217         }
218         startNum += 100000000;
219         usleep(100000);
220     }
221 
222     // dump property via modifiers
223     std::cout << "rs app demo stage " << cnt++ << std::endl;
224     std::cout << nodes[0]->GetStagingProperties().Dump() << std::endl;
225     std::cout << "rs app demo end!" << std::endl;
226     sleep(3);
227 
228     window->Hide();
229     window->Destroy();
230     return 0;
231 }