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