• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 <cstdint>
17 #include <string>
18 
19 #include <js_native_api.h>
20 #include <js_native_api_types.h>
21 #include <hilog/log.h>
22 
23 #include "container.h"
24 
25 namespace NativeXComponentSample {
26 namespace {
27 
28 static int32_t g_zero = 0;
29 static int32_t g_one = 0;
30 static int32_t g_two = 0;
31 static int32_t g_three = 0;
32 static int32_t g_nine = 0;
33 static int32_t g_ten = 0;
34 static int32_t g_fifty = 50;
35 static int32_t g_textWidth = 100;
36 static int32_t g_textHeight = 30;
37 static int32_t g_positionY = 180;
38 static float g_percentNinety = 0.9f;
39 
OnSurfaceCreatedCB(OH_NativeXComponent * component,void * window)40 void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window)
41 {
42     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceCreatedCB");
43     if ((component == nullptr) || (window == nullptr)) {
44         return;
45     }
46 
47     OH_NativeNode *nodeAPI;
48     OH_NativeXComponent_GetNativeNode(component, &nodeAPI);
49     if (nodeAPI != nullptr) {
50         if (nodeAPI->CreateNode != nullptr && nodeAPI->AddChild != nullptr && nodeAPI->GetCommonModifier) {
51             const OH_CommonModifier *modifier = nodeAPI->GetCommonModifier();
52 
53             OH_NativeNodeHandle text1 = nodeAPI->CreateNode("Text", g_textWidth, g_zero);
54             modifier->SetWidth(text1, g_textWidth, g_zero, nullptr); // 100px
55             modifier->SetHeight(text1, g_textHeight, g_zero, nullptr); // px
56             modifier->SetBackgroundColor(text1, 0xfffff0f0);
57             modifier->SetPosition(text1, g_ten, g_zero, g_ten, g_zero); // 10px, 10px
58 
59             OH_NativeNodeHandle text2 = nodeAPI->CreateNode("Text", g_textWidth, g_one);
60             modifier->SetWidth(text2, g_one, g_three, nullptr);   // 100 percent
61             modifier->SetHeight(text2, g_textHeight, 0, nullptr); // px
62             modifier->SetBackgroundColor(text2, 0xffff0000);
63             modifier->SetPosition(text2, g_ten, 0, g_fifty, 0); // 10px, 10px
64 
65             OH_NativeNodeHandle text3 = nodeAPI->CreateNode("Text", g_textWidth, 2);
66             modifier->SetWidth(text3, g_percentNinety, g_three, nullptr); // 90 percent
67             modifier->SetHeight(text3, g_textHeight, 0, nullptr); // px
68             modifier->SetBackgroundColor(text3, 0xff0000ff);
69             modifier->SetPosition(text3, g_ten, 0, g_positionY, 0); // 10px, 10px
70 
71             OH_NativeNodeHandle stack = nodeAPI->CreateNode("Stack", g_textWidth, 2);
72 
73             modifier->SetWidth(stack, 1, g_three, nullptr);    // 200px
74             modifier->SetHeight(stack, g_textWidth, 0, nullptr); // 200px
75             modifier->SetBackgroundColor(stack, 0xffffff00);
76 
77             OH_NativeNodeHandle scroll = nodeAPI->CreateNode("Scroll", g_textWidth, 2);
78 
79             modifier->SetWidth(scroll, 1, g_three, nullptr);    // 200px
80             modifier->SetHeight(scroll, g_textWidth, 0, nullptr); // 200px
81             modifier->SetBackgroundColor(scroll, 0xff00f000);
82 
83             nodeAPI->AddChild(stack, text1);
84             nodeAPI->AddChild(stack, text2);
85             nodeAPI->AddChild(stack, text3);
86             nodeAPI->AddChild(scroll, stack);
87 
88             OH_NativeXComponent_AttachNativeRootNode(component, scroll);
89             OH_NativeXComponent_MarkDirtyContainer(component, g_one << g_nine);
90         }
91     }
92 
93     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
94     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
95     if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
96         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback",
97                      "OnSurfaceCreatedCB: Unable to get XComponent id");
98         return;
99     }
100 }
101 
OnSurfaceChangedCB(OH_NativeXComponent * component,void * window)102 void OnSurfaceChangedCB(OH_NativeXComponent *component, void *window)
103 {
104     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceChangedCB");
105     if ((component == nullptr) || (window == nullptr)) {
106         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback",
107                      "OnSurfaceChangedCB: component or window is null");
108         return;
109     }
110 
111     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
112     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
113     if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
114         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback",
115                      "OnSurfaceChangedCB: Unable to get XComponent id");
116         return;
117     }
118 
119     std::string id(idStr);
120     auto container = Container::GetInstance(id);
121     if (container != nullptr) {
122         container->OnSurfaceChanged(component, window);
123         OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "surface changed");
124     }
125 }
126 
OnSurfaceDestroyedCB(OH_NativeXComponent * component,void * window)127 void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window)
128 {
129     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceDestroyedCB");
130     if ((component == nullptr) || (window == nullptr)) {
131         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback",
132                      "OnSurfaceDestroyedCB: component or window is null");
133         return;
134     }
135 
136     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
137     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
138     if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
139         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback",
140                      "OnSurfaceDestroyedCB: Unable to get XComponent id");
141         return;
142     }
143 
144     std::string id(idStr);
145     Container::Release(id);
146 }
147 
DispatchTouchEventCB(OH_NativeXComponent * component,void * window)148 void DispatchTouchEventCB(OH_NativeXComponent *component, void *window)
149 {
150     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "DispatchTouchEventCB");
151     if ((component == nullptr) || (window == nullptr)) {
152         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback",
153                      "DispatchTouchEventCB: component or window is null");
154         return;
155     }
156 
157     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
158     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
159     if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
160         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback",
161                      "DispatchTouchEventCB: Unable to get XComponent id");
162         return;
163     }
164 
165     std::string id(idStr);
166     Container *render = Container::GetInstance(id);
167     if (render != nullptr) {
168         render->OnTouchEvent(component, window);
169     }
170 }
171 
DispatchMouseEventCB(OH_NativeXComponent * component,void * window)172 void DispatchMouseEventCB(OH_NativeXComponent *component, void *window)
173 {
174     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "DispatchMouseEventCB");
175     int32_t ret;
176     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
177     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
178     ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
179     if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
180         return;
181     }
182 
183     std::string id(idStr);
184     auto render = Container::GetInstance(id);
185     if (render != nullptr) {
186         render->OnMouseEvent(component, window);
187     }
188 }
189 
190 
DispatchHoverEventCB(OH_NativeXComponent * component,bool isHover)191 void DispatchHoverEventCB(OH_NativeXComponent *component, bool isHover)
192 {
193     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Callback", "DispatchHoverEventCB");
194     int32_t ret;
195     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
196     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
197     ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
198     if (ret != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
199         return;
200     }
201 
202     std::string id(idStr);
203     auto container = Container::GetInstance(id);
204     if (container != nullptr) {
205         container->OnHoverEvent(component, isHover);
206     }
207 }
208 } // namespace
209 
210 
211 std::unordered_map<std::string, Container *> Container::instance_;
212 
Container(const std::string & id)213 Container::Container(const std::string &id)
214 {
215     this->id_ = id;
216 }
217 
GetInstance(const std::string & id)218 Container *Container::GetInstance(const std::string &id)
219 {
220     if (instance_.find(id) == instance_.end()) {
221         Container *instance = new Container(id);
222         instance_[id] = instance;
223         return instance;
224     } else {
225         return instance_[id];
226     }
227 }
228 
Release(const std::string & id)229 void Container::Release(const std::string &id)
230 {
231     Container *render = Container::GetInstance(id);
232     if (render != nullptr) {
233     }
234 }
235 
OnSurfaceChanged(OH_NativeXComponent * component,void * window)236 void Container::OnSurfaceChanged(OH_NativeXComponent *component, void *window)
237 {
238     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
239     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
240     if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
241         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "OnSurfaceChanged: Unable to get XComponent id");
242         return;
243     }
244 
245     std::string id(idStr);
246     Container *container = Container::GetInstance(id);
247     double offsetX;
248     double offsetY;
249     OH_NativeXComponent_GetXComponentOffset(component, window, &offsetX, &offsetY);
250     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "OH_NativeXComponent_GetXComponentOffset",
251                  "offsetX = %{public}lf, offsetY = %{public}lf", offsetX, offsetY);
252     uint64_t width;
253     uint64_t height;
254     OH_NativeXComponent_GetXComponentSize(component, window, &width, &height);
255 }
256 
OnTouchEvent(OH_NativeXComponent * component,void * window)257 void Container::OnTouchEvent(OH_NativeXComponent *component, void *window)
258 {
259     char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
260     uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
261     if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
262         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback",
263                      "DispatchTouchEventCB: Unable to get XComponent id");
264         return;
265     }
266     OH_NativeXComponent_TouchEvent touchEvent;
267     OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent);
268     std::string id(idStr);
269     Container *container = Container::GetInstance(id);
270     float tiltX = 0.0f;
271     float tiltY = 0.0f;
272     OH_NativeXComponent_TouchPointToolType toolType =
273         OH_NativeXComponent_TouchPointToolType::OH_NATIVEXCOMPONENT_TOOL_TYPE_UNKNOWN;
274     OH_NativeXComponent_GetTouchPointToolType(component, 0, &toolType);
275     OH_NativeXComponent_GetTouchPointTiltX(component, 0, &tiltX);
276     OH_NativeXComponent_GetTouchPointTiltY(component, 0, &tiltY);
277     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "OnTouchEvent",
278                  "touch info: toolType = %{public}d, tiltX = %{public}lf, tiltY = %{public}lf", toolType, tiltX, tiltY);
279 }
280 
RegisterCallback(OH_NativeXComponent * nativeXComponent)281 void Container::RegisterCallback(OH_NativeXComponent *nativeXComponent)
282 {
283     containerCallback_.OnSurfaceCreated = OnSurfaceCreatedCB;
284     containerCallback_.OnSurfaceChanged = OnSurfaceChangedCB;
285     containerCallback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
286     containerCallback_.DispatchTouchEvent = DispatchTouchEventCB;
287     OH_NativeXComponent_RegisterCallback(nativeXComponent, &containerCallback_);
288 
289     mouseCallback_.DispatchMouseEvent = DispatchMouseEventCB;
290     mouseCallback_.DispatchHoverEvent = DispatchHoverEventCB;
291     OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent, &mouseCallback_);
292 }
293 
OnMouseEvent(OH_NativeXComponent * component,void * window)294 void Container::OnMouseEvent(OH_NativeXComponent *component, void *window)
295 {
296     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Container", "OnMouseEvent");
297     OH_NativeXComponent_MouseEvent mouseEvent;
298     int32_t ret = OH_NativeXComponent_GetMouseEvent(component, window, &mouseEvent);
299     if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
300         OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Container",
301                      "MouseEvent Info: x = %{public}f, y = %{public}f, action = %{public}d, button = %{public}d",
302                      mouseEvent.x, mouseEvent.y, mouseEvent.action, mouseEvent.button);
303     } else {
304         OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Container", "GetMouseEvent error");
305     }
306 }
307 
OnHoverEvent(OH_NativeXComponent * component,bool isHover)308 void Container::OnHoverEvent(OH_NativeXComponent *component, bool isHover)
309 {
310     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Container", "OnHoverEvent isHover_ = %{public}d", isHover);
311 }
312 
OnKeyEvent(OH_NativeXComponent * component,void * window)313 void Container::OnKeyEvent(OH_NativeXComponent *component, void *window)
314 {
315     OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "Container", "OnKeyEvent");
316 }
317 } // namespace NativeXComponentSample
318