1 /*
2 * Copyright (c) 2023-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 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_text_clock_bridge.h"
16
17 #include "base/utils/string_utils.h"
18 #include "base/utils/utils.h"
19 #include "core/components_ng/base/frame_node.h"
20 #include "core/components_ng/pattern/text_clock/text_clock_model_ng.h"
21 #include "frameworks/base/geometry/calc_dimension.h"
22 #include "frameworks/base/geometry/dimension.h"
23 #include "frameworks/bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
24 #include "frameworks/bridge/declarative_frontend/jsview/js_text_clock.h"
25
26 namespace OHOS::Ace::NG {
27 namespace {
28 constexpr int32_t NUM_0 = 0;
29 constexpr int32_t NUM_1 = 1;
30 constexpr int32_t NUM_2 = 2;
31 constexpr int32_t NUM_3 = 3;
32 constexpr int32_t NUM_4 = 4;
33 constexpr int32_t NUM_5 = 5;
34 constexpr int32_t NUM_6 = 6;
35 constexpr int32_t NUM_7 = 7;
36 constexpr int32_t HOURS_WEST_LOWER_LIMIT = -14;
37 constexpr int32_t HOURS_WEST_UPPER_LIMIT = 12;
38 constexpr float HOURS_WEST[] = { 9.5f, 3.5f, -3.5f, -4.5f, -5.5f, -5.75f, -6.5f, -9.5f, -10.5f, -12.75f };
39 const std::string DEFAULT_STR = "-1";
40 const char* TEXTCLOCK_NODEPTR_OF_UINODE = "nodePtr_";
41 const std::string TEXTCLOCK_DATE_TIME_OPTIONS_HOUR = "hour";
42 const std::string TEXTCLOCK_DATE_TIME_OPTIONS_TWO_DIGIT_VAL = "2-digit";
43 const std::string TEXTCLOCK_DATE_TIME_OPTIONS_NUMERIC_VAL = "numeric";
44
HoursWestIsValid(int32_t hoursWest)45 bool HoursWestIsValid(int32_t hoursWest)
46 {
47 return !(hoursWest < HOURS_WEST_LOWER_LIMIT || hoursWest > HOURS_WEST_UPPER_LIMIT);
48 }
49
GetHoursWest(float hoursWest)50 float GetHoursWest(float hoursWest)
51 {
52 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_ELEVEN)) {
53 for (float i : HOURS_WEST) {
54 if (NearEqual(hoursWest, i)) {
55 return hoursWest;
56 }
57 }
58 }
59
60 return int32_t(hoursWest);
61 }
62
RemoveJSController(FrameNode * frameNode,const RefPtr<TextClockController> & controller,Framework::JSTextClockController * jsController)63 void RemoveJSController(
64 FrameNode* frameNode, const RefPtr<TextClockController>& controller, Framework::JSTextClockController* jsController)
65 {
66 CHECK_NULL_VOID(frameNode);
67 CHECK_NULL_VOID(controller);
68 CHECK_NULL_VOID(jsController);
69 auto pointer = TextClockModelNG::GetJSTextClockController(frameNode);
70 auto preController = static_cast<Framework::JSTextClockController*>(Referenced::RawPtr(pointer));
71 if (preController) {
72 preController->removeController(controller);
73 }
74 TextClockModelNG::SetJSTextClockController(frameNode, Referenced::Claim(static_cast<Referenced*>(jsController)));
75 }
76 } // namespace
77
SetFormat(ArkUIRuntimeCallInfo * runtimeCallInfo)78 ArkUINativeModuleValue TextClockBridge::SetFormat(ArkUIRuntimeCallInfo* runtimeCallInfo)
79 {
80 EcmaVM* vm = runtimeCallInfo->GetVM();
81 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
82 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
83 Local<JSValueRef> formatArg = runtimeCallInfo->GetCallArgRef(NUM_1);
84 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
85 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
86 std::string format;
87 RefPtr<ResourceObject> formatResObj;
88 ArkTSUtils::ParseJsString(vm, formatArg, format, formatResObj);
89 auto nodeModifiers = GetArkUINodeModifiers();
90 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
91 if (0 == format.length() || DEFAULT_STR == format) {
92 nodeModifiers->getTextClockModifier()->resetFormat(nativeNode);
93 } else if (!StringUtils::IsAscii(format) && Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
94 nodeModifiers->getTextClockModifier()->resetFormat(nativeNode);
95 } else {
96 auto formatRawPtr = AceType::RawPtr(formatResObj);
97 nodeModifiers->getTextClockModifier()->setFormatRes(nativeNode, format.c_str(), formatRawPtr);
98 }
99 return panda::JSValueRef::Undefined(vm);
100 }
101
ResetFormat(ArkUIRuntimeCallInfo * runtimeCallInfo)102 ArkUINativeModuleValue TextClockBridge::ResetFormat(ArkUIRuntimeCallInfo* runtimeCallInfo)
103 {
104 EcmaVM* vm = runtimeCallInfo->GetVM();
105 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
106 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
107 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
108 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
109 auto nodeModifiers = GetArkUINodeModifiers();
110 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
111 nodeModifiers->getTextClockModifier()->resetFormat(nativeNode);
112 return panda::JSValueRef::Undefined(vm);
113 }
114
SetFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)115 ArkUINativeModuleValue TextClockBridge::SetFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
116 {
117 EcmaVM* vm = runtimeCallInfo->GetVM();
118 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
119 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
120 Local<JSValueRef> fontColorArg = runtimeCallInfo->GetCallArgRef(NUM_1);
121 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
122 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
123 Color color;
124 RefPtr<ResourceObject> fontColorResObj;
125 auto nodeModifiers = GetArkUINodeModifiers();
126 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
127 auto nodeInfo = ArkTSUtils::MakeNativeNodeInfo(nativeNode);
128 if (!ArkTSUtils::ParseJsColorAlpha(vm, fontColorArg, color, fontColorResObj, nodeInfo)) {
129 nodeModifiers->getTextClockModifier()->resetFontColor(nativeNode);
130 } else {
131 auto fontColorRawPtr = AceType::RawPtr(fontColorResObj);
132 nodeModifiers->getTextClockModifier()->setFontColorRes(nativeNode, color.GetValue(), fontColorRawPtr);
133 }
134 return panda::JSValueRef::Undefined(vm);
135 }
136
ResetFontColor(ArkUIRuntimeCallInfo * runtimeCallInfo)137 ArkUINativeModuleValue TextClockBridge::ResetFontColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
138 {
139 EcmaVM* vm = runtimeCallInfo->GetVM();
140 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
141 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
142 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
143 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
144 auto nodeModifiers = GetArkUINodeModifiers();
145 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
146 nodeModifiers->getTextClockModifier()->resetFontColor(nativeNode);
147 return panda::JSValueRef::Undefined(vm);
148 }
149
SetFontSize(ArkUIRuntimeCallInfo * runtimeCallInfo)150 ArkUINativeModuleValue TextClockBridge::SetFontSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
151 {
152 EcmaVM* vm = runtimeCallInfo->GetVM();
153 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
154 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
155 Local<JSValueRef> fontSizeArg = runtimeCallInfo->GetCallArgRef(NUM_1);
156 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
157 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
158 CalcDimension fontSize;
159 RefPtr<ResourceObject> fontSizeResObj;
160 auto nodeModifiers = GetArkUINodeModifiers();
161 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
162 if (!ArkTSUtils::ParseJsDimensionNG(vm, fontSizeArg, fontSize, DimensionUnit::FP, fontSizeResObj, false) ||
163 fontSize.Value() < 0 || fontSize.Unit() == DimensionUnit::PERCENT) {
164 nodeModifiers->getTextClockModifier()->resetFontSize(nativeNode);
165 } else {
166 auto fontSizeRawPtr = AceType::RawPtr(fontSizeResObj);
167 nodeModifiers->getTextClockModifier()->setFontSizeRes(
168 nativeNode, fontSize.Value(), static_cast<int>(fontSize.Unit()), fontSizeRawPtr);
169 }
170 return panda::JSValueRef::Undefined(vm);
171 }
172
ResetFontSize(ArkUIRuntimeCallInfo * runtimeCallInfo)173 ArkUINativeModuleValue TextClockBridge::ResetFontSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
174 {
175 EcmaVM* vm = runtimeCallInfo->GetVM();
176 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
177 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
178 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
179 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
180 auto nodeModifiers = GetArkUINodeModifiers();
181 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
182 nodeModifiers->getTextClockModifier()->resetFontSize(nativeNode);
183 return panda::JSValueRef::Undefined(vm);
184 }
185
SetFontStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)186 ArkUINativeModuleValue TextClockBridge::SetFontStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
187 {
188 EcmaVM* vm = runtimeCallInfo->GetVM();
189 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
190 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
191 Local<JSValueRef> fontStyleArg = runtimeCallInfo->GetCallArgRef(NUM_1);
192 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
193 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
194 auto nodeModifiers = GetArkUINodeModifiers();
195 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
196 if (fontStyleArg->IsNumber()) {
197 uint32_t fontStyle = fontStyleArg->Uint32Value(vm);
198 if (fontStyle < static_cast<uint32_t>(OHOS::Ace::FontStyle::NORMAL) ||
199 fontStyle > static_cast<uint32_t>(OHOS::Ace::FontStyle::ITALIC)) {
200 fontStyle = static_cast<uint32_t>(OHOS::Ace::FontStyle::NORMAL);
201 }
202 nodeModifiers->getTextClockModifier()->setFontStyle(nativeNode, fontStyle);
203 } else {
204 nodeModifiers->getTextClockModifier()->resetFontStyle(nativeNode);
205 }
206 return panda::JSValueRef::Undefined(vm);
207 }
208
ResetFontStyle(ArkUIRuntimeCallInfo * runtimeCallInfo)209 ArkUINativeModuleValue TextClockBridge::ResetFontStyle(ArkUIRuntimeCallInfo* runtimeCallInfo)
210 {
211 EcmaVM* vm = runtimeCallInfo->GetVM();
212 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
213 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
214 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
215 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
216 auto nodeModifiers = GetArkUINodeModifiers();
217 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
218 nodeModifiers->getTextClockModifier()->resetFontStyle(nativeNode);
219 return panda::JSValueRef::Undefined(vm);
220 }
221
SetFontWeight(ArkUIRuntimeCallInfo * runtimeCallInfo)222 ArkUINativeModuleValue TextClockBridge::SetFontWeight(ArkUIRuntimeCallInfo* runtimeCallInfo)
223 {
224 EcmaVM* vm = runtimeCallInfo->GetVM();
225 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
226 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
227 Local<JSValueRef> fontWeightArg = runtimeCallInfo->GetCallArgRef(NUM_1);
228 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
229 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
230 std::string fontWeight;
231 RefPtr<ResourceObject> fontWeightResObj;
232 if (!fontWeightArg->IsNull()) {
233 if (fontWeightArg->IsNumber()) {
234 fontWeight = std::to_string(fontWeightArg->Int32Value(vm));
235 } else {
236 ArkTSUtils::ParseJsString(vm, fontWeightArg, fontWeight, fontWeightResObj);
237 }
238 }
239 auto nodeModifiers = GetArkUINodeModifiers();
240 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
241 auto fontWeightRawPtr = AceType::RawPtr(fontWeightResObj);
242 nodeModifiers->getTextClockModifier()->setFontWeightRes(nativeNode, fontWeight.c_str(), fontWeightRawPtr);
243 return panda::JSValueRef::Undefined(vm);
244 }
245
ResetFontWeight(ArkUIRuntimeCallInfo * runtimeCallInfo)246 ArkUINativeModuleValue TextClockBridge::ResetFontWeight(ArkUIRuntimeCallInfo* runtimeCallInfo)
247 {
248 EcmaVM* vm = runtimeCallInfo->GetVM();
249 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
250 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
251 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
252 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
253 auto nodeModifiers = GetArkUINodeModifiers();
254 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
255 nodeModifiers->getTextClockModifier()->resetFontWeight(nativeNode);
256 return panda::JSValueRef::Undefined(vm);
257 }
258
SetFontFamily(ArkUIRuntimeCallInfo * runtimeCallInfo)259 ArkUINativeModuleValue TextClockBridge::SetFontFamily(ArkUIRuntimeCallInfo* runtimeCallInfo)
260 {
261 EcmaVM* vm = runtimeCallInfo->GetVM();
262 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
263 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
264 Local<JSValueRef> fontFamilyArg = runtimeCallInfo->GetCallArgRef(NUM_1);
265 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
266 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
267
268 std::string fontFamilyStr;
269 RefPtr<ResourceObject> fontFamilyResObj;
270 auto nodeModifiers = GetArkUINodeModifiers();
271 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
272 if (!ArkTSUtils::ParseJsFontFamiliesToString(vm, fontFamilyArg, fontFamilyStr, fontFamilyResObj)) {
273 nodeModifiers->getTextClockModifier()->resetFontFamily(nativeNode);
274 return panda::JSValueRef::Undefined(vm);
275 }
276 auto fontFamilyRawPtr = AceType::RawPtr(fontFamilyResObj);
277 nodeModifiers->getTextClockModifier()->setFontFamilyRes(nativeNode, fontFamilyStr.c_str(), fontFamilyRawPtr);
278 return panda::JSValueRef::Undefined(vm);
279 }
280
ResetFontFamily(ArkUIRuntimeCallInfo * runtimeCallInfo)281 ArkUINativeModuleValue TextClockBridge::ResetFontFamily(ArkUIRuntimeCallInfo* runtimeCallInfo)
282 {
283 EcmaVM* vm = runtimeCallInfo->GetVM();
284 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
285 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
286 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
287 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
288
289 auto nodeModifiers = GetArkUINodeModifiers();
290 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
291 nodeModifiers->getTextClockModifier()->resetFontFamily(nativeNode);
292 return panda::JSValueRef::Undefined(vm);
293 }
294
SetFontFeature(ArkUIRuntimeCallInfo * runtimeCallInfo)295 ArkUINativeModuleValue TextClockBridge::SetFontFeature(ArkUIRuntimeCallInfo* runtimeCallInfo)
296 {
297 EcmaVM* vm = runtimeCallInfo->GetVM();
298 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
299 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
300 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
301 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
302 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
303 auto nodeModifiers = GetArkUINodeModifiers();
304 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
305 if (secondArg->IsString(vm)) {
306 auto value = secondArg->ToString(vm)->ToString(vm);
307 nodeModifiers->getTextClockModifier()->setFontFeature(nativeNode, value.c_str());
308 } else {
309 nodeModifiers->getTextClockModifier()->resetFontFeature(nativeNode);
310 }
311 return panda::JSValueRef::Undefined(vm);
312 }
313
ResetFontFeature(ArkUIRuntimeCallInfo * runtimeCallInfo)314 ArkUINativeModuleValue TextClockBridge::ResetFontFeature(ArkUIRuntimeCallInfo* runtimeCallInfo)
315 {
316 EcmaVM* vm = runtimeCallInfo->GetVM();
317 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
318 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
319 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
320 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
321 auto nodeModifiers = GetArkUINodeModifiers();
322 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
323 nodeModifiers->getTextClockModifier()->resetFontFeature(nativeNode);
324 return panda::JSValueRef::Undefined(vm);
325 }
326
SetTextShadow(ArkUIRuntimeCallInfo * runtimeCallInfo)327 ArkUINativeModuleValue TextClockBridge::SetTextShadow(ArkUIRuntimeCallInfo* runtimeCallInfo)
328 {
329 EcmaVM* vm = runtimeCallInfo->GetVM();
330 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
331 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
332 Local<JSValueRef> lengthArg = runtimeCallInfo->GetCallArgRef(NUM_7);
333 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
334 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
335 if (!lengthArg->IsNumber() || lengthArg->Uint32Value(vm) == 0) {
336 return panda::JSValueRef::Undefined(vm);
337 }
338 uint32_t length = lengthArg->Uint32Value(vm);
339 auto radiusArray = std::make_unique<double[]>(length);
340 auto typeArray = std::make_unique<uint32_t[]>(length);
341 auto colorArray = std::make_unique<uint32_t[]>(length);
342 auto offsetXArray = std::make_unique<double[]>(length);
343 auto offsetYArray = std::make_unique<double[]>(length);
344 auto fillArray = std::make_unique<uint32_t[]>(length);
345 std::vector<RefPtr<ResourceObject>> radiusResObjArray;
346 std::vector<RefPtr<ResourceObject>> colorResObjArray;
347 std::vector<RefPtr<ResourceObject>> offsetXResObjArray;
348 std::vector<RefPtr<ResourceObject>> offsetYResObjArray;
349 bool radiusParseResult = ArkTSUtils::ParseArrayWithResObj<double>(vm, runtimeCallInfo->GetCallArgRef(NUM_1),
350 radiusArray.get(), length, ArkTSUtils::parseShadowRadiusWithResObj, radiusResObjArray);
351 bool typeParseResult = ArkTSUtils::ParseArray<uint32_t>(
352 vm, runtimeCallInfo->GetCallArgRef(NUM_2), typeArray.get(), length, ArkTSUtils::parseShadowType);
353 bool colorParseResult = ArkTSUtils::ParseArrayWithResObj<uint32_t>(vm, runtimeCallInfo->GetCallArgRef(NUM_3),
354 colorArray.get(), length, ArkTSUtils::parseShadowColorWithResObj, colorResObjArray);
355 bool offsetXParseResult = ArkTSUtils::ParseArrayWithResObj<double>(vm, runtimeCallInfo->GetCallArgRef(NUM_4),
356 offsetXArray.get(), length, ArkTSUtils::parseShadowOffsetWithResObj, offsetXResObjArray);
357 bool offsetYParseResult = ArkTSUtils::ParseArrayWithResObj<double>(vm, runtimeCallInfo->GetCallArgRef(NUM_5),
358 offsetYArray.get(), length, ArkTSUtils::parseShadowOffsetWithResObj, offsetYResObjArray);
359 bool fillParseResult = ArkTSUtils::ParseArray<uint32_t>(
360 vm, runtimeCallInfo->GetCallArgRef(NUM_6), fillArray.get(), length, ArkTSUtils::parseShadowFill);
361 if (!radiusParseResult || !colorParseResult || !offsetXParseResult ||
362 !offsetYParseResult || !fillParseResult || !typeParseResult) {
363 return panda::JSValueRef::Undefined(vm);
364 }
365 auto textShadowArray = std::make_unique<ArkUITextShadowStruct[]>(length);
366 auto textShadowResArray = std::make_unique<ArkUITextShadowResStruct[]>(length);
367 CHECK_NULL_RETURN(textShadowArray && textShadowResArray, panda::JSValueRef::Undefined(vm));
368 for (uint32_t i = 0; i < length; i++) {
369 textShadowArray[i] = { radiusArray[i], typeArray[i], colorArray[i], offsetXArray[i], offsetYArray[i],
370 fillArray[i] };
371 textShadowResArray[i] = { AceType::RawPtr(radiusResObjArray[i]), AceType::RawPtr(colorResObjArray[i]),
372 AceType::RawPtr(offsetXResObjArray[i]), AceType::RawPtr(offsetYResObjArray[i]) };
373 }
374 GetArkUINodeModifiers()->getTextClockModifier()->setTextShadowRes(
375 nativeNode, textShadowArray.get(), textShadowResArray.get(), length);
376 return panda::JSValueRef::Undefined(vm);
377 }
378
ResetTextShadow(ArkUIRuntimeCallInfo * runtimeCallInfo)379 ArkUINativeModuleValue TextClockBridge::ResetTextShadow(ArkUIRuntimeCallInfo* runtimeCallInfo)
380 {
381 EcmaVM* vm = runtimeCallInfo->GetVM();
382 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
383 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
384 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
385 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
386 auto nodeModifiers = GetArkUINodeModifiers();
387 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
388 nodeModifiers->getTextClockModifier()->resetTextShadow(nativeNode);
389 return panda::JSValueRef::Undefined(vm);
390 }
391
SetContentModifierBuilder(ArkUIRuntimeCallInfo * runtimeCallInfo)392 ArkUINativeModuleValue TextClockBridge::SetContentModifierBuilder(ArkUIRuntimeCallInfo* runtimeCallInfo)
393 {
394 EcmaVM* vm = runtimeCallInfo->GetVM();
395 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
396 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
397 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
398 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
399 void* nativeNode = firstArg->ToNativePointer(vm)->Value();
400 auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
401 if (!secondArg->IsObject(vm)) {
402 TextClockModelNG::SetBuilderFunc(frameNode, nullptr);
403 return panda::JSValueRef::Undefined(vm);
404 }
405 panda::CopyableGlobal<panda::ObjectRef> obj(vm, secondArg);
406 TextClockModelNG::SetBuilderFunc(frameNode,
407 [vm, frameNode, obj = std::move(obj), containerId = Container::CurrentId()](
408 TextClockConfiguration config) -> RefPtr<FrameNode> {
409 ContainerScope scope(containerId);
410 auto context = ArkTSUtils::GetContext(vm);
411 CHECK_EQUAL_RETURN(context->IsUndefined(), true, nullptr);
412 const char* keysOfTextClock[] = { "timeZoneOffset", "started", "enabled", "timeValue" };
413 Local<JSValueRef> valuesOfTextClock[] = { panda::NumberRef::New(vm, config.timeZoneOffset_),
414 panda::BooleanRef::New(vm, config.started_), panda::BooleanRef::New(vm, config.enabled_),
415 panda::NumberRef::New(vm, config.timeValue_) };
416 auto textClock = panda::ObjectRef::NewWithNamedProperties(
417 vm, ArraySize(keysOfTextClock), keysOfTextClock, valuesOfTextClock);
418 obj->SetNativePointerFieldCount(vm, 1);
419 obj->SetNativePointerField(vm, 0, static_cast<void*>(frameNode));
420 panda::Local<panda::JSValueRef> params[NUM_2] = { context, textClock };
421 LocalScope pandaScope(vm);
422 panda::TryCatch trycatch(vm);
423 auto jsObject = obj.ToLocal();
424 auto makeFunc = jsObject->Get(vm, panda::StringRef::NewFromUtf8(vm, "makeContentModifierNode"));
425 CHECK_EQUAL_RETURN(makeFunc->IsFunction(vm), false, nullptr);
426 panda::Local<panda::FunctionRef> func = makeFunc;
427 auto result = func->Call(vm, jsObject, params, NUM_2);
428 JSNApi::ExecutePendingJob(vm);
429 CHECK_EQUAL_RETURN(result.IsEmpty() || trycatch.HasCaught() || !result->IsObject(vm), true, nullptr);
430 auto resultObj = result->ToObject(vm);
431 panda::Local<panda::JSValueRef> nodeptr =
432 resultObj->Get(vm, panda::StringRef::NewFromUtf8(vm, TEXTCLOCK_NODEPTR_OF_UINODE));
433 CHECK_EQUAL_RETURN(nodeptr.IsEmpty() || nodeptr->IsUndefined() || nodeptr->IsNull(), true, nullptr);
434 auto* frameNode = reinterpret_cast<FrameNode*>(nodeptr->ToNativePointer(vm)->Value());
435 CHECK_NULL_RETURN(frameNode, nullptr);
436 return AceType::Claim(frameNode);
437 });
438 return panda::JSValueRef::Undefined(vm);
439 }
SetDateTimeOptions(ArkUIRuntimeCallInfo * runtimeCallInfo)440 ArkUINativeModuleValue TextClockBridge::SetDateTimeOptions(ArkUIRuntimeCallInfo* runtimeCallInfo)
441 {
442 EcmaVM* vm = runtimeCallInfo->GetVM();
443 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
444 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
445 Local<JSValueRef> hourArg = runtimeCallInfo->GetCallArgRef(NUM_1);
446 CHECK_NULL_RETURN(firstArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
447 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
448 ZeroPrefixType hourType = ZeroPrefixType::AUTO;
449 std::string hour = TEXTCLOCK_DATE_TIME_OPTIONS_HOUR;
450 if (hourArg->IsString(vm)) {
451 std::string hour = hourArg->ToString(vm)->ToString(vm);
452 if (hour == TEXTCLOCK_DATE_TIME_OPTIONS_TWO_DIGIT_VAL) {
453 hourType = ZeroPrefixType::SHOW;
454 } else if (hour == TEXTCLOCK_DATE_TIME_OPTIONS_NUMERIC_VAL) {
455 hourType = ZeroPrefixType::HIDE;
456 }
457 }
458 auto nodeModifiers = GetArkUINodeModifiers();
459 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
460 nodeModifiers->getTextClockModifier()->setDateTimeOptions(
461 nativeNode, static_cast<ArkUI_Int32>(hourType));
462 return panda::JSValueRef::Undefined(vm);
463 }
464
ResetDateTimeOptions(ArkUIRuntimeCallInfo * runtimeCallInfo)465 ArkUINativeModuleValue TextClockBridge::ResetDateTimeOptions(ArkUIRuntimeCallInfo* runtimeCallInfo)
466 {
467 EcmaVM* vm = runtimeCallInfo->GetVM();
468 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
469 Local<JSValueRef> nodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
470 CHECK_NULL_RETURN(nodeArg->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
471 auto nativeNode = nodePtr(nodeArg->ToNativePointer(vm)->Value());
472 auto nodeModifiers = GetArkUINodeModifiers();
473 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
474 nodeModifiers->getTextClockModifier()->resetDateTimeOptions(nativeNode);
475 return panda::JSValueRef::Undefined(vm);
476 }
477
SetTextClockTimeZoneOffset(ArkUIRuntimeCallInfo * runtimeCallInfo)478 ArkUINativeModuleValue TextClockBridge::SetTextClockTimeZoneOffset(ArkUIRuntimeCallInfo* runtimeCallInfo)
479 {
480 EcmaVM* vm = runtimeCallInfo->GetVM();
481 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
482 Local<JSValueRef> nodeVal = runtimeCallInfo->GetCallArgRef(NUM_0);
483 Local<JSValueRef> hourWestVal = runtimeCallInfo->GetCallArgRef(NUM_1);
484 CHECK_NULL_RETURN(nodeVal->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
485 auto nativeNode = nodePtr(nodeVal->ToNativePointer(vm)->Value());
486 float hourWest = NAN;
487 if (hourWestVal->IsNumber() && HoursWestIsValid(hourWestVal->Int32Value(vm))) {
488 hourWest = GetHoursWest(hourWestVal->ToNumber(vm)->Value());
489 }
490 auto nodeModifiers = GetArkUINodeModifiers();
491 CHECK_NULL_RETURN(nodeModifiers, panda::JSValueRef::Undefined(vm));
492 nodeModifiers->getTextClockModifier()->setTextClockTimeZoneOffset(nativeNode, hourWest);
493 return panda::JSValueRef::Undefined(vm);
494 }
495
SetTextClockController(ArkUIRuntimeCallInfo * runtimeCallInfo)496 ArkUINativeModuleValue TextClockBridge::SetTextClockController(ArkUIRuntimeCallInfo* runtimeCallInfo)
497 {
498 EcmaVM* vm = runtimeCallInfo->GetVM();
499 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
500 Local<JSValueRef> nodeVal = runtimeCallInfo->GetCallArgRef(NUM_0);
501 Local<JSValueRef> controllerVal = runtimeCallInfo->GetCallArgRef(NUM_1);
502 CHECK_NULL_RETURN(nodeVal->IsNativePointer(vm), panda::JSValueRef::Undefined(vm));
503 auto nativeNode = nodePtr(nodeVal->ToNativePointer(vm)->Value());
504
505 auto* frameNode = reinterpret_cast<FrameNode*>(nativeNode);
506 CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
507 auto controller = TextClockModelNG::InitTextController(frameNode);
508 if (!controllerVal->IsUndefined() && !controllerVal->IsNull() && controllerVal->IsObject(vm)) {
509 auto* jsController = Framework::JSRef<Framework::JSObject>(Framework::JSObject(controllerVal->ToObject(vm)))
510 ->Unwrap<Framework::JSTextClockController>();
511 if (jsController) {
512 jsController->SetInstanceId(Container::CurrentId());
513 if (controller) {
514 RemoveJSController(frameNode, controller, jsController);
515 jsController->AddController(controller);
516 }
517 }
518 } else if (controller) {
519 auto pointer = TextClockModelNG::GetJSTextClockController(frameNode);
520 auto preController = static_cast<Framework::JSTextClockController*>(Referenced::RawPtr(pointer));
521 if (preController) {
522 preController->removeController(controller);
523 }
524 TextClockModelNG::SetJSTextClockController(frameNode, nullptr);
525 }
526 return panda::JSValueRef::Undefined(vm);
527 }
528
SetTextClockOnDateChange(ArkUIRuntimeCallInfo * runtimeCallInfo)529 ArkUINativeModuleValue TextClockBridge::SetTextClockOnDateChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
530 {
531 EcmaVM* vm = runtimeCallInfo->GetVM();
532 CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
533 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
534 Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(1);
535 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
536
537 if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
538 GetArkUINodeModifiers()->getTextClockModifier()->resetTextClockOnDateChange(nativeNode);
539 return panda::JSValueRef::Undefined(vm);
540 }
541 auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
542 panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
543 CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
544 std::function<void(const std::string&)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)](
545 const std::string& value) {
546 panda::LocalScope pandaScope(vm);
547 panda::TryCatch trycatch(vm);
548 PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
549
550 panda::Local<panda::JSValueRef> params[1] = { panda::StringRef::NewFromUtf8(vm, value.c_str()) };
551 func->Call(vm, func.ToLocal(), params, 1);
552 };
553 GetArkUINodeModifiers()->getTextClockModifier()->setTextClockOnDateChange(
554 nativeNode, reinterpret_cast<void*>(&callback));
555 return panda::JSValueRef::Undefined(vm);
556 }
557
ResetTextClockOnDateChange(ArkUIRuntimeCallInfo * runtimeCallInfo)558 ArkUINativeModuleValue TextClockBridge::ResetTextClockOnDateChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
559 {
560 EcmaVM* vm = runtimeCallInfo->GetVM();
561 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
562 Local<JSValueRef> nativeNodeArg = runtimeCallInfo->GetCallArgRef(NUM_0);
563 auto nativeNode = nodePtr(nativeNodeArg->ToNativePointer(vm)->Value());
564 GetArkUINodeModifiers()->getTextClockModifier()->resetTextClockOnDateChange(nativeNode);
565 return panda::JSValueRef::Undefined(vm);
566 }
567 } // namespace OHOS::Ace::NG
568