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 "common/common.h"
17 #include "../manager/plugin_manager.h"
18 #include "list_scroll_to_test.h"
19 #include <arkui/native_node.h>
20 #include <string>
21 #include <arkui/native_node_napi.h>
22
23 namespace ArkUICapiTest {
24 static int g_num2 = 2;
25 static int g_num3 = 3;
26 static int g_num7 = 7;
27 static int g_num10 = 10;
28 static int g_num30 = 30;
29 static int g_num38 = 38;
30 static int g_num40 = 40;
31 static int g_num50 = 50;
32 static int g_num100 = 100;
33 static int g_num200 = 200;
34 static int g_num250 = 250;
35 static int g_num500 = 500;
36 static ArkUI_NativeNodeAPI_1 *nodeAPI;
37 static ArkUI_NodeHandle list1;
38 static ArkUI_NodeHandle listItemGroup1;
39 static ArkUI_NodeHandle list2;
CreateButton(ArkUI_NativeNodeAPI_1 * nodeAPI,std::string buttonName,int eventId)40 ArkUI_NodeHandle ListScrollToTest::CreateButton(ArkUI_NativeNodeAPI_1 *nodeAPI, std::string buttonName, int eventId)
41 {
42 auto button = nodeAPI->createNode(ARKUI_NODE_BUTTON);
43 ArkUI_AttributeItem LABEL_Item = {.string = buttonName.c_str()};
44 nodeAPI->setAttribute(button, NODE_BUTTON_LABEL, &LABEL_Item);
45 nodeAPI->registerNodeEvent(button, NODE_ON_CLICK, eventId, nullptr);
46 ArkUI_AttributeItem buttonId = {.string = buttonName.c_str()};
47 nodeAPI->setAttribute(button, NODE_ID, &buttonId);
48 return button;
49 }
50
ProcessEvent(ArkUI_NativeNodeAPI_1 * nodeAPI,int eventId)51 void ListScrollToTest::ProcessEvent(ArkUI_NativeNodeAPI_1 *nodeAPI, int eventId)
52 {
53 if (eventId == 0) {
54 ArkUI_NumberValue value[] = {-1, 40, 50, 80};
55 value[0].i32 = g_num10;
56 value[1].i32 = 1;
57 value[g_num2].i32 = 0;
58 value[g_num3].f32 = g_num30;
59 ArkUI_AttributeItem item = {value, 4};
60 nodeAPI->setAttribute(list1, NODE_LIST_SCROLL_TO_INDEX, &item);
61 } else if (eventId == 1) {
62 ArkUI_NumberValue value[] = {2, -1, -1, 0};
63 value[0].i32 = g_num7;
64 value[1].i32 = g_num2;
65 value[g_num2].i32 = 1;
66 value[g_num3].i32 = 0;
67 ArkUI_AttributeItem item = {value, 4};
68 nodeAPI->setAttribute(list2, NODE_LIST_SCROLL_TO_INDEX_IN_GROUP, &item);
69 } else if (eventId == g_num2) {
70 ArkUI_NumberValue value[] = {-1, 40, 50, 80};
71 value[0].i32 = g_num38;
72 value[1].i32 = 1;
73 value[g_num2].i32 = 0;
74 value[g_num3].f32 = 0;
75 ArkUI_AttributeItem item = {value, 4};
76 nodeAPI->setAttribute(list1, NODE_LIST_SCROLL_TO_INDEX, &item);
77 } else if (eventId == g_num3) {
78 nodeAPI->resetAttribute(listItemGroup1, NODE_LIST_ITEM_GROUP_SET_HEADER);
79 nodeAPI->resetAttribute(listItemGroup1, NODE_LIST_ITEM_GROUP_SET_FOOTER);
80 }
81 }
82
AddListItem(ArkUI_NativeNodeAPI_1 * nodeAPI,ArkUI_NodeHandle & list)83 void ListScrollToTest::AddListItem(ArkUI_NativeNodeAPI_1 *nodeAPI, ArkUI_NodeHandle &list)
84 {
85 ArkUI_NumberValue value[] = {1};
86 ArkUI_AttributeItem item = {value, 1};
87 value[0].f32 = g_num200;
88 nodeAPI->setAttribute(list, NODE_WIDTH, &item);
89 value[0].f32 = g_num500;
90 nodeAPI->setAttribute(list, NODE_HEIGHT, &item);
91 value[0].u32 = 0xFFFF1CAE;
92 nodeAPI->setAttribute(list, NODE_BACKGROUND_COLOR, &item);
93 ArkUI_AttributeItem listId = {.string = "ListId1"};
94 nodeAPI->setAttribute(list, NODE_ID, &listId);
95 for (int i = 1; i < g_num40; i++) {
96 auto listItem = nodeAPI->createNode(ARKUI_NODE_LIST_ITEM);
97 ArkUI_NumberValue value[] = {250};
98 ArkUI_AttributeItem item = {value, 1};
99 value[0].f32 = g_num200;
100 nodeAPI->setAttribute(listItem, NODE_WIDTH, &item);
101 value[0].f32 = g_num50;
102 nodeAPI->setAttribute(listItem, NODE_HEIGHT, &item);
103 value[0].u32 = (i % g_num2 == 0 ? 0xFF0000FF : 0xFF00FF00);
104 nodeAPI->setAttribute(listItem, NODE_BACKGROUND_COLOR, &item);
105 ArkUI_NodeHandle text = nodeAPI->createNode(ARKUI_NODE_TEXT);
106 std::string str = "第" + std::to_string(i - 1) + "个";
107 ArkUI_AttributeItem content = {.string = str.c_str()};
108 nodeAPI->setAttribute(text, NODE_TEXT_CONTENT, &content);
109 nodeAPI->addChild(listItem, text);
110 str = "listItem" + std::to_string(i - 1);
111 ArkUI_AttributeItem nodeId = {.string = str.c_str()};
112 nodeAPI->setAttribute(listItem, NODE_ID, &nodeId);
113 nodeAPI->addChild(list, listItem);
114 }
115 AddListItemGroup1(nodeAPI, list);
116 }
117
AddListItemGroup1(ArkUI_NativeNodeAPI_1 * nodeAPI,ArkUI_NodeHandle & list)118 void ListScrollToTest::AddListItemGroup1(ArkUI_NativeNodeAPI_1 *nodeAPI, ArkUI_NodeHandle &list)
119 {
120 listItemGroup1 = nodeAPI->createNode(ARKUI_NODE_LIST_ITEM_GROUP);
121 ArkUI_NodeHandle textTemp = nodeAPI->createNode(ARKUI_NODE_TEXT);
122 ArkUI_AttributeItem content = { .string = "setHeader" };
123 nodeAPI->setAttribute(textTemp, NODE_TEXT_CONTENT, &content);
124 nodeAPI->setAttribute(textTemp, NODE_ID, &content);
125 ArkUI_AttributeItem header = {.object = textTemp};
126 nodeAPI->setAttribute(listItemGroup1, NODE_LIST_ITEM_GROUP_SET_HEADER, &header);
127 for (int i = 1; i < g_num3; i++) {
128 auto listItem = nodeAPI->createNode(ARKUI_NODE_LIST_ITEM);
129 ArkUI_NumberValue value[] = {250};
130 ArkUI_AttributeItem item = {value, 1};
131 value[0].f32 = g_num200;
132 nodeAPI->setAttribute(listItem, NODE_WIDTH, &item);
133 value[0].f32 = g_num50;
134 nodeAPI->setAttribute(listItem, NODE_HEIGHT, &item);
135 value[0].u32 = (i % g_num2 == 0 ? 0xFF0000FF : 0xFF00FF00);
136 nodeAPI->setAttribute(listItem, NODE_BACKGROUND_COLOR, &item);
137 ArkUI_NodeHandle text = nodeAPI->createNode(ARKUI_NODE_TEXT);
138 std::string str = "Group第" + std::to_string(i - 1) + "个";
139 ArkUI_AttributeItem content = {.string = str.c_str()};
140 nodeAPI->addChild(listItemGroup1, listItem);
141 }
142 ArkUI_NodeHandle textTemp2 = nodeAPI->createNode(ARKUI_NODE_TEXT);
143 ArkUI_AttributeItem content2 = { .string = "setFooter" };
144 nodeAPI->setAttribute(textTemp2, NODE_TEXT_CONTENT, &content2);
145 nodeAPI->setAttribute(textTemp2, NODE_ID, &content2);
146 ArkUI_AttributeItem footer = {.object = textTemp2};
147 nodeAPI->setAttribute(listItemGroup1, NODE_LIST_ITEM_GROUP_SET_FOOTER, &footer);
148 nodeAPI->addChild(list, listItemGroup1);
149 }
150
AddListItemGroup(ArkUI_NativeNodeAPI_1 * nodeAPI,ArkUI_NodeHandle & list2)151 void ListScrollToTest::AddListItemGroup(ArkUI_NativeNodeAPI_1 *nodeAPI, ArkUI_NodeHandle &list2)
152 {
153 ArkUI_NumberValue value[] = {1};
154 ArkUI_AttributeItem item = {value, 1};
155 value[0].f32 = g_num200;
156 nodeAPI->setAttribute(list2, NODE_WIDTH, &item);
157 value[0].f32 = g_num500;
158 nodeAPI->setAttribute(list2, NODE_HEIGHT, &item);
159 value[0].u32 = 0xFFFF1CAE;
160 nodeAPI->setAttribute(list2, NODE_BACKGROUND_COLOR, &item);
161 ArkUI_AttributeItem listId = {.string = "ListId2"};
162 nodeAPI->setAttribute(list2, NODE_ID, &listId);
163 for (int i = 1; i < g_num10; i++) {
164 auto listItemGroup = nodeAPI->createNode(ARKUI_NODE_LIST_ITEM_GROUP);
165 for (int j = 1; j < g_num10; j++) {
166 auto listItem = nodeAPI->createNode(ARKUI_NODE_LIST_ITEM);
167 ArkUI_NumberValue value[] = {250};
168 ArkUI_AttributeItem item = {value, 1};
169 value[0].f32 = g_num200;
170 nodeAPI->setAttribute(listItem, NODE_WIDTH, &item);
171 value[0].f32 = g_num50;
172 nodeAPI->setAttribute(listItem, NODE_HEIGHT, &item);
173 value[0].u32 = (i % g_num2 == 0 ? 0xFF0000FF : 0xFF00FF00);
174 nodeAPI->setAttribute(listItem, NODE_BACKGROUND_COLOR, &item);
175 ArkUI_NodeHandle text = nodeAPI->createNode(ARKUI_NODE_TEXT);
176 std::string str = "第" + std::to_string(i - 1) + "组第" + std::to_string(j - 1) + "个";
177 ArkUI_AttributeItem content = {.string = str.c_str()};
178 nodeAPI->setAttribute(text, NODE_TEXT_CONTENT, &content);
179 nodeAPI->addChild(listItem, text);
180 str = "listItem" + std::to_string(i - 1) + "to" + std::to_string(j - 1);
181 ArkUI_AttributeItem listItemId = {.string = str.c_str()};
182 nodeAPI->setAttribute(listItem, NODE_ID, &listItemId);
183 nodeAPI->addChild(listItemGroup, listItem);
184 }
185 nodeAPI->addChild(list2, listItemGroup);
186 }
187 }
188
CreateChildNode(ArkUI_NativeNodeAPI_1 * nodeAPI)189 ArkUI_NodeHandle ListScrollToTest::CreateChildNode(ArkUI_NativeNodeAPI_1 *nodeAPI)
190 {
191 ArkUI_NodeHandle stack = nodeAPI->createNode(ARKUI_NODE_COLUMN);
192 ArkUI_NodeHandle row = nodeAPI->createNode(ARKUI_NODE_ROW);
193 ArkUI_NodeHandle column1 = nodeAPI->createNode(ARKUI_NODE_COLUMN);
194 ArkUI_NodeHandle column2 = nodeAPI->createNode(ARKUI_NODE_COLUMN);
195 ArkUI_NodeHandle row1 = nodeAPI->createNode(ARKUI_NODE_ROW);
196 ArkUI_NumberValue value[] = {250};
197 ArkUI_AttributeItem item = {value, 1};
198 value[0].f32 = g_num250;
199 nodeAPI->setAttribute(column1, NODE_WIDTH, &item);
200 nodeAPI->setAttribute(column2, NODE_WIDTH, &item);
201 value[0].f32 = g_num100;
202 nodeAPI->setAttribute(row, NODE_HEIGHT, &item);
203 ArkUI_NodeHandle column3 = nodeAPI->createNode(ARKUI_NODE_COLUMN);
204 auto scrollToIndex10 = CreateButton(nodeAPI, "scrollToIndex10", 0);
205 nodeAPI->addChild(column3, scrollToIndex10);
206 auto scrollTo7In2 = CreateButton(nodeAPI, "scrollTo7In2", 1);
207 nodeAPI->addChild(column3, scrollTo7In2);
208 nodeAPI->addChild(row, column3);
209 ArkUI_NodeHandle column4 = nodeAPI->createNode(ARKUI_NODE_COLUMN);
210 auto scrollToEnd = CreateButton(nodeAPI, "scrollToEnd", 2);
211 nodeAPI->addChild(column4, scrollToEnd);
212 auto resetHeaderFooter = CreateButton(nodeAPI, "resetHeaderFooter", 3);
213 nodeAPI->addChild(column4, resetHeaderFooter);
214 nodeAPI->addChild(row, column4);
215
216 list1 = nodeAPI->createNode(ARKUI_NODE_LIST);
217 AddListItem(nodeAPI, list1);
218 nodeAPI->addChild(column1, list1);
219 nodeAPI->addChild(row1, column1);
220
221 list2 = nodeAPI->createNode(ARKUI_NODE_LIST);
222 AddListItemGroup(nodeAPI, list2);
223 nodeAPI->addChild(column2, list2);
224 nodeAPI->addChild(row1, column2);
225 nodeAPI->addChild(stack, row);
226 nodeAPI->addChild(stack, row1);
227 return stack;
228 }
229
ListScrollToIndexTest(napi_env env,napi_callback_info info)230 napi_value ListScrollToTest::ListScrollToIndexTest(napi_env env, napi_callback_info info)
231 {
232 size_t argc = PARAM_1;
233 napi_value args[PARAM_1] = {nullptr};
234 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
235 size_t length = PARAM_64;
236 size_t strLength = PARAM_0;
237 char xComponentID[PARAM_64] = {PARAM_0};
238 napi_get_value_string_utf8(env, args[PARAM_0], xComponentID, length, &strLength);
239 if ((env == nullptr) || (info == nullptr)) {
240 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ListScrollToTest", "GetContext env or info is null");
241 return nullptr;
242 }
243 OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, nodeAPI);
244 auto testNode = CreateChildNode(nodeAPI);
245 nodeAPI->registerNodeEventReceiver([](ArkUI_NodeEvent *event) {
246 auto eventId = OH_ArkUI_NodeEvent_GetTargetId(event);
247 ArkUI_NumberValue background_color_value[] = {{.u32 = COLOR_GREEN}};
248 ArkUI_AttributeItem background_color_item = {background_color_value,
249 sizeof(background_color_value) / sizeof(ArkUI_NumberValue)};
250 auto nodeHandler = OH_ArkUI_NodeEvent_GetNodeHandle(event);
251 nodeAPI->setAttribute(nodeHandler, NODE_BACKGROUND_COLOR, &background_color_item);
252 ProcessEvent(nodeAPI, eventId);
253 });
254 std::string id(xComponentID);
255 auto nativeXComponent = PluginManager::GetInstance()->GetNativeXComponent(id);
256 if (OH_NativeXComponent_AttachNativeRootNode(nativeXComponent, testNode) == INVALID_PARAM) {
257 OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ListScrollToTest",
258 "OH_NativeXComponent_AttachNativeRootNode failed");
259 }
260 napi_value exports;
261 if (napi_create_object(env, &exports) != napi_ok) {
262 napi_throw_type_error(env, nullptr, "napi_create_object failed");
263 return nullptr;
264 }
265 return exports;
266 }
267 } // namespace ArkUICapiTest