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 "core/interfaces/native/node/image_animator_modifier.h"
16 
17 #include "base/geometry/calc_dimension.h"
18 #include "base/geometry/dimension.h"
19 #include "base/utils/utils.h"
20 #include "core/components/common/properties/alignment.h"
21 #include "core/components/declaration/image/image_animator_declaration.h"
22 #include "core/components_ng/base/frame_node.h"
23 #include "core/components_ng/base/view_abstract.h"
24 #include "core/components_ng/pattern/image_animator/image_animator_model_ng.h"
25 #include "core/pipeline/base/element_register.h"
26 
27 namespace OHOS::Ace::NG {
28 constexpr int32_t DEFAULT_DURATION = 1000; // ms
29 constexpr int32_t DEFAULT_ITERATION = 1;
30 constexpr FillMode DEFAULT_FILL_MODE = FillMode::FORWARDS;
31 constexpr uint32_t DEFAULT_ITERATIONS = 1;
32 constexpr int32_t IMAGES_LENGTH = 4;
33 constexpr int32_t DEFAULT_STATE = 0;
34 
35 namespace ImageAnimatorModifier {
ParseImage(CalcDimension * dimension,int32_t dimensionLength,const ArkUIImagePropertiesStruct * image)36 void ParseImage(CalcDimension* dimension, int32_t dimensionLength, const ArkUIImagePropertiesStruct* image)
37 {
38     for (int32_t i = 0; i < dimensionLength; i++) {
39         if (image->unit[i] == static_cast<int8_t>(DimensionUnit::CALC)) {
40             dimension[i].SetUnit(DimensionUnit::CALC);
41             dimension[i].SetValue(0.0);
42             dimension[i].SetCalcValue(std::string(image->calc[i]));
43         } else {
44             dimension[i].SetUnit(static_cast<DimensionUnit>(image->unit[i]));
45             dimension[i].SetValue(image->number[i]);
46         }
47     }
48 }
49 
SetState(ArkUINodeHandle node,int32_t state)50 void SetState(ArkUINodeHandle node, int32_t state)
51 {
52     auto* frameNode = reinterpret_cast<FrameNode*>(node);
53     CHECK_NULL_VOID(frameNode);
54 
55     int32_t value = state;
56     if (value < static_cast<int32_t>(Animator::Status::IDLE) ||
57         value > static_cast<int32_t>(Animator::Status::STOPPED)) {
58         value = static_cast<int32_t>(Animator::Status::IDLE);
59     }
60 
61     ImageAnimatorModelNG::SetState(frameNode, value);
62 }
63 
ResetState(ArkUINodeHandle node)64 void ResetState(ArkUINodeHandle node)
65 {
66     auto* frameNode = reinterpret_cast<FrameNode*>(node);
67     CHECK_NULL_VOID(frameNode);
68     ImageAnimatorModelNG::SetState(frameNode, static_cast<int32_t>(Animator::Status::IDLE));
69 }
70 
SetDuration(ArkUINodeHandle node,int32_t duration)71 void SetDuration(ArkUINodeHandle node, int32_t duration)
72 {
73     auto* frameNode = reinterpret_cast<FrameNode*>(node);
74     CHECK_NULL_VOID(frameNode);
75     if (duration < 0) {
76         duration = DEFAULT_DURATION;
77     }
78     ImageAnimatorModelNG::SetDuration(frameNode, duration);
79 }
80 
SetFixedSize(ArkUINodeHandle node,uint32_t fixedSize)81 void SetFixedSize(ArkUINodeHandle node, uint32_t fixedSize)
82 {
83     auto* frameNode = reinterpret_cast<FrameNode*>(node);
84     CHECK_NULL_VOID(frameNode);
85 
86     ImageAnimatorModelNG::SetFixedSize(frameNode, static_cast<bool>(fixedSize));
87 }
88 
ResetFixedSize(ArkUINodeHandle node)89 void ResetFixedSize(ArkUINodeHandle node)
90 {
91     auto* frameNode = reinterpret_cast<FrameNode*>(node);
92     CHECK_NULL_VOID(frameNode);
93 
94     ImageAnimatorModelNG::SetFixedSize(frameNode, true);
95 }
96 
SetFillMode(ArkUINodeHandle node,int32_t fillMode)97 void SetFillMode(ArkUINodeHandle node, int32_t fillMode)
98 {
99     auto* frameNode = reinterpret_cast<FrameNode*>(node);
100     CHECK_NULL_VOID(frameNode);
101 
102     int32_t value = fillMode;
103     if (value < static_cast<int32_t>(FillMode::NONE) || value > static_cast<int32_t>(FillMode::BOTH)) {
104         value = static_cast<int32_t>(DEFAULT_FILL_MODE);
105     }
106 
107     ImageAnimatorModelNG::SetFillMode(frameNode, value);
108 }
109 
ResetFillMode(ArkUINodeHandle node)110 void ResetFillMode(ArkUINodeHandle node)
111 {
112     auto* frameNode = reinterpret_cast<FrameNode*>(node);
113     CHECK_NULL_VOID(frameNode);
114     ImageAnimatorModelNG::SetFillMode(frameNode, static_cast<int32_t>(DEFAULT_FILL_MODE));
115 }
116 
SetReverse(ArkUINodeHandle node,uint32_t value)117 void SetReverse(ArkUINodeHandle node, uint32_t value)
118 {
119     auto* frameNode = reinterpret_cast<FrameNode*>(node);
120     CHECK_NULL_VOID(frameNode);
121     ImageAnimatorModelNG::SetIsReverse(frameNode, static_cast<bool>(value));
122 }
123 
ResetReverse(ArkUINodeHandle node)124 void ResetReverse(ArkUINodeHandle node)
125 {
126     auto* frameNode = reinterpret_cast<FrameNode*>(node);
127     CHECK_NULL_VOID(frameNode);
128     ImageAnimatorModelNG::SetIsReverse(frameNode, false);
129 }
130 
SetImages(ArkUINodeHandle node,struct ArkUIImagePropertiesStruct * images,int32_t length)131 void SetImages(ArkUINodeHandle node, struct ArkUIImagePropertiesStruct* images, int32_t length)
132 {
133     auto* frameNode = reinterpret_cast<FrameNode*>(node);
134     CHECK_NULL_VOID(frameNode);
135     if (length == 0) {
136         ImageAnimatorModelNG::SetImages(frameNode, std::vector<ImageProperties>());
137         return;
138     }
139     CHECK_NULL_VOID(images);
140     if (length <= 0) {
141         return;
142     }
143     std::vector<ImageProperties> imageList;
144     for (int32_t i = 0; i < length; i++) {
145         ArkUIImagePropertiesStruct* image = images + i;
146         CHECK_NULL_VOID(image);
147         CalcDimension dimension[IMAGES_LENGTH];
148         ParseImage(dimension, IMAGES_LENGTH, image);
149         ImageProperties property { std::string(image->src), nullptr, "", "", dimension[0], dimension[1], dimension[2],
150             dimension[3], image->duration };
151         imageList.emplace_back(property);
152     }
153     ImageAnimatorModelNG::SetImages(frameNode, imageList);
154 }
155 
ResetImages(ArkUINodeHandle node)156 void ResetImages(ArkUINodeHandle node)
157 {
158     auto* frameNode = reinterpret_cast<FrameNode*>(node);
159     CHECK_NULL_VOID(frameNode);
160     ImageAnimatorModelNG::SetImages(frameNode, std::vector<ImageProperties>());
161 }
162 
SetImageAnimatorIteration(ArkUINodeHandle node,int32_t value)163 void SetImageAnimatorIteration(ArkUINodeHandle node, int32_t value)
164 {
165     auto* frameNode = reinterpret_cast<FrameNode*>(node);
166     CHECK_NULL_VOID(frameNode);
167 
168     int32_t iteration = value;
169     if (iteration < -1) {
170         iteration = DEFAULT_ITERATIONS;
171     }
172 
173     ImageAnimatorModelNG::SetIteration(frameNode, iteration);
174 }
175 
ResetImageAnimatorIteration(ArkUINodeHandle node)176 void ResetImageAnimatorIteration(ArkUINodeHandle node)
177 {
178     auto* frameNode = reinterpret_cast<FrameNode*>(node);
179     CHECK_NULL_VOID(frameNode);
180     ImageAnimatorModelNG::SetIteration(frameNode, DEFAULT_ITERATION);
181 }
182 
SetImageAnimatorSrc(ArkUINodeHandle node,ArkUIImageFrameInfo * imageInfos,ArkUI_Int32 size)183 void SetImageAnimatorSrc(ArkUINodeHandle node, ArkUIImageFrameInfo* imageInfos, ArkUI_Int32 size)
184 {
185     auto* frameNode = reinterpret_cast<FrameNode*>(node);
186     CHECK_NULL_VOID(frameNode);
187     if (size <= 0) {
188         ImageAnimatorModelNG::SetImages(frameNode, std::vector<ImageProperties>());
189         return;
190     }
191     CHECK_NULL_VOID(imageInfos);
192     std::vector<ImageProperties> imageList;
193     for (int32_t i = 0; i < size; i++) {
194         ArkUIImageFrameInfo* image = imageInfos + i;
195         CHECK_NULL_VOID(image);
196         ImageProperties property;
197         auto pixelmap = PixelMap::GetFromDrawable(image->drawable);
198         if (pixelmap) {
199             property.pixelMap = pixelmap;
200         } else {
201             property.src = std::string(image->src);
202         }
203         property.width = CalcDimension(static_cast<double>(image->width), static_cast<DimensionUnit>(image->unit));
204         property.height = CalcDimension(static_cast<double>(image->height), static_cast<DimensionUnit>(image->unit));
205         property.top = CalcDimension(static_cast<double>(image->top), static_cast<DimensionUnit>(image->unit));
206         property.left = CalcDimension(static_cast<double>(image->left), static_cast<DimensionUnit>(image->unit));
207         property.duration = image->duration;
208         imageList.emplace_back(property);
209     }
210     ImageAnimatorModelNG::SetImages(frameNode, imageList);
211 }
212 
ResetDuration(ArkUINodeHandle node)213 void ResetDuration(ArkUINodeHandle node)
214 {
215     auto* frameNode = reinterpret_cast<FrameNode*>(node);
216     CHECK_NULL_VOID(frameNode);
217     ImageAnimatorModelNG::SetDuration(frameNode, DEFAULT_DURATION);
218 }
219 
GetIsReverse(ArkUINodeHandle node)220 ArkUI_Bool GetIsReverse(ArkUINodeHandle node)
221 {
222     auto* frameNode = reinterpret_cast<FrameNode*>(node);
223     CHECK_NULL_RETURN(frameNode, false);
224     return static_cast<ArkUI_Bool>(ImageAnimatorModelNG::IsReverse(frameNode));
225 }
226 
GetDuration(ArkUINodeHandle node)227 int32_t GetDuration(ArkUINodeHandle node)
228 {
229     auto* frameNode = reinterpret_cast<FrameNode*>(node);
230     CHECK_NULL_RETURN(frameNode, DEFAULT_DURATION);
231     return ImageAnimatorModelNG::GetDuration(frameNode);
232 }
233 
GetState(ArkUINodeHandle node)234 int32_t GetState(ArkUINodeHandle node)
235 {
236     auto* frameNode = reinterpret_cast<FrameNode*>(node);
237     CHECK_NULL_RETURN(frameNode, DEFAULT_STATE);
238     return ImageAnimatorModelNG::GetState(frameNode);
239 }
240 
GetIsFixedSize(ArkUINodeHandle node)241 ArkUI_Bool GetIsFixedSize(ArkUINodeHandle node)
242 {
243     auto* frameNode = reinterpret_cast<FrameNode*>(node);
244     CHECK_NULL_RETURN(frameNode, true);
245     return static_cast<ArkUI_Bool>(ImageAnimatorModelNG::IsFixedSize(frameNode));
246 }
247 
GetFillMode(ArkUINodeHandle node)248 int32_t GetFillMode(ArkUINodeHandle node)
249 {
250     auto* frameNode = reinterpret_cast<FrameNode*>(node);
251     CHECK_NULL_RETURN(frameNode, static_cast<int32_t>(DEFAULT_FILL_MODE));
252     return ImageAnimatorModelNG::GetFillMode(frameNode);
253 }
254 
GetIteration(ArkUINodeHandle node)255 int32_t GetIteration(ArkUINodeHandle node)
256 {
257     auto* frameNode = reinterpret_cast<FrameNode*>(node);
258     CHECK_NULL_RETURN(frameNode, DEFAULT_ITERATION);
259     return ImageAnimatorModelNG::GetIteration(frameNode);
260 }
261 
GetImagesSize(ArkUINodeHandle node)262 int32_t GetImagesSize(ArkUINodeHandle node)
263 {
264     auto* frameNode = reinterpret_cast<FrameNode*>(node);
265     CHECK_NULL_RETURN(frameNode, 0);
266     return ImageAnimatorModelNG::GetImagesSize(frameNode);
267 }
268 } // namespace ImageAnimatorModifier
269 
270 namespace NodeModifier {
GetImageAnimatorModifier()271 const ArkUIImageAnimatorModifier* GetImageAnimatorModifier()
272 {
273     static const ArkUIImageAnimatorModifier modifier = {
274         ImageAnimatorModifier::SetState,
275         ImageAnimatorModifier::ResetState,
276         ImageAnimatorModifier::SetDuration,
277         ImageAnimatorModifier::SetFixedSize,
278         ImageAnimatorModifier::ResetFixedSize,
279         ImageAnimatorModifier::SetFillMode,
280         ImageAnimatorModifier::ResetFillMode,
281         ImageAnimatorModifier::SetReverse,
282         ImageAnimatorModifier::ResetReverse,
283         ImageAnimatorModifier::SetImages,
284         ImageAnimatorModifier::ResetImages,
285         ImageAnimatorModifier::SetImageAnimatorIteration,
286         ImageAnimatorModifier::ResetImageAnimatorIteration,
287         ImageAnimatorModifier::SetImageAnimatorSrc,
288         ImageAnimatorModifier::ResetDuration,
289         ImageAnimatorModifier::GetIsReverse,
290         ImageAnimatorModifier::GetDuration,
291         ImageAnimatorModifier::GetState,
292         ImageAnimatorModifier::GetIsFixedSize,
293         ImageAnimatorModifier::GetFillMode,
294         ImageAnimatorModifier::GetIteration,
295         ImageAnimatorModifier::GetImagesSize
296     };
297 
298     return &modifier;
299 }
300 
GetCJUIImageAnimatorModifier()301 const CJUIImageAnimatorModifier* GetCJUIImageAnimatorModifier()
302 {
303     static const CJUIImageAnimatorModifier modifier = {
304         ImageAnimatorModifier::SetState,
305         ImageAnimatorModifier::ResetState,
306         ImageAnimatorModifier::SetDuration,
307         ImageAnimatorModifier::SetFixedSize,
308         ImageAnimatorModifier::ResetFixedSize,
309         ImageAnimatorModifier::SetFillMode,
310         ImageAnimatorModifier::ResetFillMode,
311         ImageAnimatorModifier::SetReverse,
312         ImageAnimatorModifier::ResetReverse,
313         ImageAnimatorModifier::SetImages,
314         ImageAnimatorModifier::ResetImages,
315         ImageAnimatorModifier::SetImageAnimatorIteration,
316         ImageAnimatorModifier::ResetImageAnimatorIteration,
317         ImageAnimatorModifier::SetImageAnimatorSrc,
318         ImageAnimatorModifier::ResetDuration,
319         ImageAnimatorModifier::GetIsReverse,
320         ImageAnimatorModifier::GetDuration,
321         ImageAnimatorModifier::GetState,
322         ImageAnimatorModifier::GetIsFixedSize,
323         ImageAnimatorModifier::GetFillMode,
324         ImageAnimatorModifier::GetIteration,
325         ImageAnimatorModifier::GetImagesSize
326     };
327 
328     return &modifier;
329 }
330 
SetImageAnimatorOnStart(ArkUINodeHandle node,void * extraParam)331 void SetImageAnimatorOnStart(ArkUINodeHandle node, void* extraParam)
332 {
333     auto* frameNode = reinterpret_cast<FrameNode*>(node);
334     CHECK_NULL_VOID(frameNode);
335     auto onEvent = [node, extraParam]() {
336         ArkUINodeEvent event;
337         event.kind = COMPONENT_ASYNC_EVENT;
338         event.extraParam = reinterpret_cast<intptr_t>(extraParam);
339         event.componentAsyncEvent.subKind = ON_IMAGE_ANIMATOR_ON_START;
340         SendArkUIAsyncEvent(&event);
341     };
342     ImageAnimatorModelNG::SetOnStart(frameNode, std::move(onEvent));
343 }
344 
SetImageAnimatorOnPause(ArkUINodeHandle node,void * extraParam)345 void SetImageAnimatorOnPause(ArkUINodeHandle node, void* extraParam)
346 {
347     auto* frameNode = reinterpret_cast<FrameNode*>(node);
348     CHECK_NULL_VOID(frameNode);
349     auto onEvent = [node, extraParam]() {
350         ArkUINodeEvent event;
351         event.kind = COMPONENT_ASYNC_EVENT;
352         event.extraParam = reinterpret_cast<intptr_t>(extraParam);
353         event.componentAsyncEvent.subKind = ON_IMAGE_ANIMATOR_ON_PAUSE;
354         SendArkUIAsyncEvent(&event);
355     };
356     ImageAnimatorModelNG::SetOnPause(frameNode, std::move(onEvent));
357 }
358 
SetImageAnimatorOnRepeat(ArkUINodeHandle node,void * extraParam)359 void SetImageAnimatorOnRepeat(ArkUINodeHandle node, void* extraParam)
360 {
361     auto* frameNode = reinterpret_cast<FrameNode*>(node);
362     CHECK_NULL_VOID(frameNode);
363     auto onEvent = [node, extraParam]() {
364         ArkUINodeEvent event;
365         event.kind = COMPONENT_ASYNC_EVENT;
366         event.extraParam = reinterpret_cast<intptr_t>(extraParam);
367         event.componentAsyncEvent.subKind = ON_IMAGE_ANIMATOR_ON_REPEAT;
368         SendArkUIAsyncEvent(&event);
369     };
370     ImageAnimatorModelNG::SetOnRepeat(frameNode, std::move(onEvent));
371 }
372 
SetImageAnimatorOnCancel(ArkUINodeHandle node,void * extraParam)373 void SetImageAnimatorOnCancel(ArkUINodeHandle node, void* extraParam)
374 {
375     auto* frameNode = reinterpret_cast<FrameNode*>(node);
376     CHECK_NULL_VOID(frameNode);
377     auto onEvent = [node, extraParam]() {
378         ArkUINodeEvent event;
379         event.kind = COMPONENT_ASYNC_EVENT;
380         event.extraParam = reinterpret_cast<intptr_t>(extraParam);
381         event.componentAsyncEvent.subKind = ON_IMAGE_ANIMATOR_ON_CANCEL;
382         SendArkUIAsyncEvent(&event);
383     };
384     ImageAnimatorModelNG::SetOnCancel(frameNode, std::move(onEvent));
385 }
386 
SetImageAnimatorOnFinish(ArkUINodeHandle node,void * extraParam)387 void SetImageAnimatorOnFinish(ArkUINodeHandle node, void* extraParam)
388 {
389     auto* frameNode = reinterpret_cast<FrameNode*>(node);
390     CHECK_NULL_VOID(frameNode);
391     auto onEvent = [node, extraParam]() {
392         ArkUINodeEvent event;
393         event.kind = COMPONENT_ASYNC_EVENT;
394         event.extraParam = reinterpret_cast<intptr_t>(extraParam);
395         event.componentAsyncEvent.subKind = ON_IMAGE_ANIMATOR_ON_FINISH;
396         SendArkUIAsyncEvent(&event);
397     };
398     ImageAnimatorModelNG::SetOnFinish(frameNode, std::move(onEvent));
399 }
400 
ResetImageAnimatorOnStart(ArkUINodeHandle node)401 void ResetImageAnimatorOnStart(ArkUINodeHandle node)
402 {
403     auto* frameNode = reinterpret_cast<FrameNode*>(node);
404     CHECK_NULL_VOID(frameNode);
405     ImageAnimatorModelNG::SetOnStart(frameNode, nullptr);
406 }
ResetImageAnimatorOnPause(ArkUINodeHandle node)407 void ResetImageAnimatorOnPause(ArkUINodeHandle node)
408 {
409     auto* frameNode = reinterpret_cast<FrameNode*>(node);
410     CHECK_NULL_VOID(frameNode);
411     ImageAnimatorModelNG::SetOnPause(frameNode, nullptr);
412 }
ResetImageAnimatorOnRepeat(ArkUINodeHandle node)413 void ResetImageAnimatorOnRepeat(ArkUINodeHandle node)
414 {
415     auto* frameNode = reinterpret_cast<FrameNode*>(node);
416     CHECK_NULL_VOID(frameNode);
417     ImageAnimatorModelNG::SetOnRepeat(frameNode, nullptr);
418 }
ResetImageAnimatorOnCancel(ArkUINodeHandle node)419 void ResetImageAnimatorOnCancel(ArkUINodeHandle node)
420 {
421     auto* frameNode = reinterpret_cast<FrameNode*>(node);
422     CHECK_NULL_VOID(frameNode);
423     ImageAnimatorModelNG::SetOnCancel(frameNode, nullptr);
424 }
ResetImageAnimatorOnFinish(ArkUINodeHandle node)425 void ResetImageAnimatorOnFinish(ArkUINodeHandle node)
426 {
427     auto* frameNode = reinterpret_cast<FrameNode*>(node);
428     CHECK_NULL_VOID(frameNode);
429     ImageAnimatorModelNG::SetOnFinish(frameNode, nullptr);
430 }
431 }
432 } // namespace OHOS::Ace::NG