1 /*
2 * Copyright (c) 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 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_image_animator_bridge.h"
16
17 #include "base/geometry/dimension.h"
18 #include "base/geometry/ng/offset_t.h"
19 #include "base/memory/referenced.h"
20 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
21 #include "bridge/declarative_frontend/jsview/js_image_animator.h"
22 #include "core/components/declaration/image/image_animator_declaration.h"
23
24 namespace OHOS::Ace::NG {
25 constexpr int32_t DEFAULT_DURATION = 1000; // ms
26
27 constexpr int NUM_0 = 0;
28 constexpr int NUM_1 = 1;
29 constexpr int NUM_2 = 2;
30 constexpr int NUM_3 = 3;
31 constexpr int NUM_4 = 4;
32 constexpr int NUM_5 = 5;
33 constexpr int NUM_6 = 6;
34 constexpr int NUM_7 = 7;
35 constexpr int32_t IMAGE_SIZE = 4;
36 constexpr FillMode DEFAULT_FILL_MODE = FillMode::FORWARDS;
SetState(ArkUIRuntimeCallInfo * runtimeCallInfo)37 ArkUINativeModuleValue ImageAnimatorBridge::SetState(ArkUIRuntimeCallInfo* runtimeCallInfo)
38 {
39 EcmaVM* vm = runtimeCallInfo->GetVM();
40 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
41 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
42 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
43 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
44 int32_t state = static_cast<int32_t>(Animator::Status::IDLE);
45 if (secondArg->IsNumber()) {
46 state = secondArg->Int32Value(vm);
47 if (state < static_cast<int32_t>(Animator::Status::IDLE) ||
48 state > static_cast<int32_t>(Animator::Status::STOPPED)) {
49 state = static_cast<int32_t>(Animator::Status::IDLE);
50 }
51 GetArkUINodeModifiers()->getImageAnimatorModifier()->setState(nativeNode, state);
52 } else {
53 GetArkUINodeModifiers()->getImageAnimatorModifier()->resetState(nativeNode);
54 }
55
56 return panda::JSValueRef::Undefined(vm);
57 }
58
ResetState(ArkUIRuntimeCallInfo * runtimeCallInfo)59 ArkUINativeModuleValue ImageAnimatorBridge::ResetState(ArkUIRuntimeCallInfo* runtimeCallInfo)
60 {
61 EcmaVM* vm = runtimeCallInfo->GetVM();
62 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
63 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
64 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
65 GetArkUINodeModifiers()->getImageAnimatorModifier()->resetState(nativeNode);
66 return panda::JSValueRef::Undefined(vm);
67 }
68
SetDuration(ArkUIRuntimeCallInfo * runtimeCallInfo)69 ArkUINativeModuleValue ImageAnimatorBridge::SetDuration(ArkUIRuntimeCallInfo* runtimeCallInfo)
70 {
71 EcmaVM* vm = runtimeCallInfo->GetVM();
72 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
73 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
74 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
75 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
76 int32_t duration = DEFAULT_DURATION;
77 if (secondArg->IsNumber()) {
78 duration = secondArg->Int32Value(vm);
79 if (duration < 0) {
80 duration = DEFAULT_DURATION;
81 }
82 }
83 GetArkUINodeModifiers()->getImageAnimatorModifier()->setDuration(nativeNode, duration);
84 return panda::JSValueRef::Undefined(vm);
85 }
86
ResetDuration(ArkUIRuntimeCallInfo * runtimeCallInfo)87 ArkUINativeModuleValue ImageAnimatorBridge::ResetDuration(ArkUIRuntimeCallInfo* runtimeCallInfo)
88 {
89 EcmaVM* vm = runtimeCallInfo->GetVM();
90 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
91 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
92 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
93 int32_t duration = DEFAULT_DURATION;
94 GetArkUINodeModifiers()->getImageAnimatorModifier()->setDuration(nativeNode, duration);
95 return panda::JSValueRef::Undefined(vm);
96 }
97
SetFixedSize(ArkUIRuntimeCallInfo * runtimeCallInfo)98 ArkUINativeModuleValue ImageAnimatorBridge::SetFixedSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
99 {
100 EcmaVM* vm = runtimeCallInfo->GetVM();
101 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
102 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
103 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
104 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
105
106 uint32_t fixedSize = 1;
107 if (secondArg->IsBoolean()) {
108 fixedSize = static_cast<uint32_t>(secondArg->ToBoolean(vm)->Value());
109 GetArkUINodeModifiers()->getImageAnimatorModifier()->setFixedSize(nativeNode, fixedSize);
110 } else {
111 GetArkUINodeModifiers()->getImageAnimatorModifier()->resetFixedSize(nativeNode);
112 }
113
114 return panda::JSValueRef::Undefined(vm);
115 }
116
ResetFixedSize(ArkUIRuntimeCallInfo * runtimeCallInfo)117 ArkUINativeModuleValue ImageAnimatorBridge::ResetFixedSize(ArkUIRuntimeCallInfo* runtimeCallInfo)
118 {
119 EcmaVM* vm = runtimeCallInfo->GetVM();
120 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
121 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
122 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
123 GetArkUINodeModifiers()->getImageAnimatorModifier()->resetFixedSize(nativeNode);
124 return panda::JSValueRef::Undefined(vm);
125 }
126
SetFillMode(ArkUIRuntimeCallInfo * runtimeCallInfo)127 ArkUINativeModuleValue ImageAnimatorBridge::SetFillMode(ArkUIRuntimeCallInfo* runtimeCallInfo)
128 {
129 EcmaVM* vm = runtimeCallInfo->GetVM();
130 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
131 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
132 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
133 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
134
135 if (secondArg->IsNumber()) {
136 int32_t fillMode = secondArg->Int32Value(vm);
137 if (fillMode < static_cast<int32_t>(FillMode::NONE) || fillMode > static_cast<int32_t>(FillMode::BOTH)) {
138 fillMode = static_cast<int32_t>(DEFAULT_FILL_MODE);
139 }
140 GetArkUINodeModifiers()->getImageAnimatorModifier()->setFillMode(nativeNode, fillMode);
141 } else {
142 GetArkUINodeModifiers()->getImageAnimatorModifier()->resetFillMode(nativeNode);
143 }
144 return panda::JSValueRef::Undefined(vm);
145 }
146
ResetFillMode(ArkUIRuntimeCallInfo * runtimeCallInfo)147 ArkUINativeModuleValue ImageAnimatorBridge::ResetFillMode(ArkUIRuntimeCallInfo* runtimeCallInfo)
148 {
149 EcmaVM* vm = runtimeCallInfo->GetVM();
150 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
151 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
152 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
153 GetArkUINodeModifiers()->getImageAnimatorModifier()->resetFillMode(nativeNode);
154 return panda::JSValueRef::Undefined(vm);
155 }
156
SetReverse(ArkUIRuntimeCallInfo * runtimeCallInfo)157 ArkUINativeModuleValue ImageAnimatorBridge::SetReverse(ArkUIRuntimeCallInfo* runtimeCallInfo)
158 {
159 EcmaVM* vm = runtimeCallInfo->GetVM();
160 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
161 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
162 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
163 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
164
165 if (secondArg->IsBoolean()) {
166 uint32_t value = static_cast<uint32_t>(secondArg->ToBoolean(vm)->Value());
167 GetArkUINodeModifiers()->getImageAnimatorModifier()->setReverse(nativeNode, value);
168 } else {
169 GetArkUINodeModifiers()->getImageAnimatorModifier()->resetReverse(nativeNode);
170 }
171
172 return panda::JSValueRef::Undefined(vm);
173 }
174
ResetReverse(ArkUIRuntimeCallInfo * runtimeCallInfo)175 ArkUINativeModuleValue ImageAnimatorBridge::ResetReverse(ArkUIRuntimeCallInfo* runtimeCallInfo)
176 {
177 EcmaVM* vm = runtimeCallInfo->GetVM();
178 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
179 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
180 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
181 GetArkUINodeModifiers()->getImageAnimatorModifier()->resetReverse(nativeNode);
182 return panda::JSValueRef::Undefined(vm);
183 }
184
SetImages(ArkUIRuntimeCallInfo * runtimeCallInfo)185 ArkUINativeModuleValue ImageAnimatorBridge::SetImages(ArkUIRuntimeCallInfo* runtimeCallInfo)
186 {
187 EcmaVM* vm = runtimeCallInfo->GetVM();
188 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
189 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
190 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(NUM_1);
191 Local<JSValueRef> thirdArg = runtimeCallInfo->GetCallArgRef(NUM_2);
192 Local<JSValueRef> fourthArg = runtimeCallInfo->GetCallArgRef(NUM_3);
193 Local<JSValueRef> fifthArg = runtimeCallInfo->GetCallArgRef(NUM_4);
194 Local<JSValueRef> sixthArg = runtimeCallInfo->GetCallArgRef(NUM_5);
195 Local<JSValueRef> seventhArg = runtimeCallInfo->GetCallArgRef(NUM_6);
196 Local<JSValueRef> eighthArg = runtimeCallInfo->GetCallArgRef(NUM_7);
197 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
198
199 if (!eighthArg->IsNumber() || eighthArg->Int32Value(vm) <= 0) {
200 return panda::JSValueRef::Undefined(vm);
201 }
202 int32_t arrayLength = eighthArg->Int32Value(vm);
203
204 if (secondArg->IsNull() || !secondArg->IsArray(vm) || thirdArg->IsNull() || !thirdArg->IsArray(vm) ||
205 fourthArg->IsNull() || !fourthArg->IsArray(vm) || fifthArg->IsNull() || !fifthArg->IsArray(vm) ||
206 sixthArg->IsNull() || !sixthArg->IsArray(vm) || seventhArg->IsNull() || !seventhArg->IsArray(vm)) {
207 return panda::JSValueRef::Undefined(vm);
208 }
209 auto parseDimensionStruct = [](const EcmaVM* vm, const Local<JSValueRef>& arg) {
210 CalcDimension val(0.0, DimensionUnit::VP);
211 ArkTSUtils::ParseJsDimensionVp(vm, arg, val);
212 return val;
213 };
214 auto parseInt32 = [](const EcmaVM* vm, const Local<JSValueRef>& arg) {
215 if (arg->IsNumber()) {
216 return arg->Int32Value(vm);
217 }
218 return 0;
219 };
220 auto srcArray = std::make_unique<std::string[]>(arrayLength);
221 auto calcDimension = std::make_unique<CalcDimension[]>(arrayLength * 4);
222 auto durationArray = std::make_unique<int32_t[]>(arrayLength);
223 if (!ArkTSUtils::ParseStringArray(vm, secondArg, srcArray.get(), arrayLength) ||
224 !ArkTSUtils::ParseArray<CalcDimension>(
225 vm, thirdArg, calcDimension.get() + arrayLength * NUM_0, arrayLength, parseDimensionStruct) ||
226 !ArkTSUtils::ParseArray<CalcDimension>(
227 vm, fourthArg, calcDimension.get() + arrayLength * NUM_1, arrayLength, parseDimensionStruct) ||
228 !ArkTSUtils::ParseArray<CalcDimension>(
229 vm, fifthArg, calcDimension.get() + arrayLength * NUM_2, arrayLength, parseDimensionStruct) ||
230 !ArkTSUtils::ParseArray<CalcDimension>(
231 vm, sixthArg, calcDimension.get() + arrayLength * NUM_3, arrayLength, parseDimensionStruct) ||
232 !ArkTSUtils::ParseArray<int32_t>(vm, seventhArg, durationArray.get(), arrayLength, parseInt32)) {
233 return panda::JSValueRef::Undefined(vm);
234 }
235 auto images = std::make_unique<ArkUIImagePropertiesStruct[]>(arrayLength);
236 for (int32_t i = 0; i < arrayLength; i++) {
237 images[i].src = srcArray[i].c_str();
238 for (int32_t j = 0; j < IMAGE_SIZE; j++) {
239 images[i].number[j] = calcDimension[arrayLength * j + i].Value();
240 images[i].unit[j] = static_cast<int8_t>(calcDimension[arrayLength * j + i].Unit());
241 images[i].calc[j] = const_cast<char*>(calcDimension[arrayLength * j + i].CalcValue().c_str());
242 }
243 images[i].duration = *(durationArray.get() + i);
244 }
245 GetArkUINodeModifiers()->getImageAnimatorModifier()->setImages(nativeNode, images.get(), arrayLength);
246 return panda::JSValueRef::Undefined(vm);
247 }
248
ResetImages(ArkUIRuntimeCallInfo * runtimeCallInfo)249 ArkUINativeModuleValue ImageAnimatorBridge::ResetImages(ArkUIRuntimeCallInfo* runtimeCallInfo)
250 {
251 EcmaVM* vm = runtimeCallInfo->GetVM();
252 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
253 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
254 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
255 GetArkUINodeModifiers()->getImageAnimatorModifier()->resetImages(nativeNode);
256 return panda::JSValueRef::Undefined(vm);
257 }
258
SetIteration(ArkUIRuntimeCallInfo * runtimeCallInfo)259 ArkUINativeModuleValue ImageAnimatorBridge::SetIteration(ArkUIRuntimeCallInfo* runtimeCallInfo)
260 {
261 EcmaVM* vm = runtimeCallInfo->GetVM();
262 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
263 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
264 Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
265 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
266 int32_t value ;
267 if (secondArg->IsNumber()) {
268 value = secondArg->Int32Value(vm);
269 } else {
270 return panda::JSValueRef::Undefined(vm);
271 }
272
273 GetArkUINodeModifiers()->getImageAnimatorModifier()->setImageAnimatorIteration(nativeNode, value);
274 return panda::JSValueRef::Undefined(vm);
275 }
276
ResetIteration(ArkUIRuntimeCallInfo * runtimeCallInfo)277 ArkUINativeModuleValue ImageAnimatorBridge::ResetIteration(ArkUIRuntimeCallInfo* runtimeCallInfo)
278 {
279 EcmaVM* vm = runtimeCallInfo->GetVM();
280 CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
281 Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
282 auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
283 GetArkUINodeModifiers()->getImageAnimatorModifier()->resetImageAnimatorIteration(nativeNode);
284 return panda::JSValueRef::Undefined(vm);
285 }
286 } // namespace OHOS::Ace::NG
287