1 /*
2  * Copyright (c) 2021-2022 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_TWEEN_OPTION_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_TWEEN_OPTION_H
18 
19 #include <list>
20 #include <map>
21 
22 #include "base/geometry/dimension.h"
23 #include "base/geometry/dimension_offset.h"
24 #include "base/geometry/transform_util.h"
25 #include "core/animation/animation.h"
26 #include "core/animation/animation_pub.h"
27 #include "core/animation/curve.h"
28 #include "core/animation/curves.h"
29 #include "core/animation/keyframe_animation.h"
30 #include "core/animation/property_animatable.h"
31 #include "core/animation/property_animation.h"
32 #include "core/components/common/properties/color.h"
33 #include "core/components/common/properties/decoration.h"
34 #include "core/components/common/properties/motion_path_option.h"
35 
36 namespace OHOS::Ace {
37 
38 class TweenOption final {
39 public:
SetCurve(const RefPtr<Curve> & curve)40     void SetCurve(const RefPtr<Curve>& curve)
41     {
42         if (!curve) {
43             LOGE("set curve failed. curve is null.");
44             return;
45         }
46         curve_ = curve;
47     }
48 
GetCurve()49     const RefPtr<Curve>& GetCurve() const
50     {
51         return curve_;
52     }
53 
SetDelay(int32_t delay)54     void SetDelay(int32_t delay)
55     {
56         delay_ = delay;
57     }
58 
GetDelay()59     int32_t GetDelay() const
60     {
61         return delay_;
62     }
63 
SetIteration(int32_t iteration)64     void SetIteration(int32_t iteration)
65     {
66         iteration_ = iteration;
67     }
68 
GetIteration()69     int32_t GetIteration() const
70     {
71         return iteration_;
72     }
73 
SetFillMode(FillMode fillMode)74     void SetFillMode(FillMode fillMode)
75     {
76         fillMode_ = fillMode;
77     }
78 
GetFillMode()79     FillMode GetFillMode() const
80     {
81         return fillMode_;
82     }
83 
SetTempo(float tempo)84     void SetTempo(float tempo)
85     {
86         if (tempo < 0.0f) {
87             return;
88         }
89         tempo_ = tempo;
90     }
91 
GetTempo()92     float GetTempo() const
93     {
94         return tempo_;
95     }
96 
SetDuration(int32_t duration)97     void SetDuration(int32_t duration)
98     {
99         duration_ = duration;
100         changeDuration_ = true;
101     }
102 
103     // Duration in millisecond.
GetDuration()104     int32_t GetDuration() const
105     {
106         return duration_;
107     }
108 
SetAnimationDirection(AnimationDirection direction)109     void SetAnimationDirection(AnimationDirection direction)
110     {
111         direction_ = direction;
112     }
113 
GetAnimationDirection()114     AnimationDirection GetAnimationDirection() const
115     {
116         return direction_;
117     }
118 
SetAnimatables(const PropAnimationMap & animatables)119     void SetAnimatables(const PropAnimationMap& animatables)
120     {
121         propAnimations_ = animatables;
122     }
123 
GetAnimatables()124     const PropAnimationMap& GetAnimatables() const
125     {
126         return propAnimations_;
127     }
128 
SetTransformOrigin(const Dimension & originX,const Dimension & originY)129     void SetTransformOrigin(const Dimension& originX, const Dimension& originY)
130     {
131         auto keyFrameAnimation = AceType::MakeRefPtr<KeyframeAnimation<DimensionOffset>>();
132         auto begin = AceType::MakeRefPtr<Keyframe<DimensionOffset>>(0.0f, DimensionOffset(originX, originY));
133         auto end = AceType::MakeRefPtr<Keyframe<DimensionOffset>>(1.0f, DimensionOffset(originX, originY));
134         keyFrameAnimation->AddKeyframe(begin);
135         keyFrameAnimation->AddKeyframe(end);
136         transformOriginAnimation_ = keyFrameAnimation;
137         SetTransformOriginChanged(true);
138     }
139 
GetTransformOriginX()140     Dimension GetTransformOriginX() const
141     {
142         if (transformOriginAnimation_) {
143             return transformOriginAnimation_->GetValue().GetX();
144         }
145 
146         return 0.5_pct;
147     }
148 
GetTransformOriginY()149     Dimension GetTransformOriginY() const
150     {
151         if (transformOriginAnimation_) {
152             return transformOriginAnimation_->GetValue().GetY();
153         }
154 
155         return 0.5_pct;
156     }
157 
GetTransformOriginAnimation()158     const RefPtr<Animation<DimensionOffset>>& GetTransformOriginAnimation() const
159     {
160         return transformOriginAnimation_;
161     }
162 
SetIsBackground(bool isBackground)163     void SetIsBackground(bool isBackground)
164     {
165         isBackground_ = isBackground;
166     }
167 
GetIsBackground()168     bool GetIsBackground() const
169     {
170         return isBackground_;
171     }
172 
GetMotionPathOption()173     const MotionPathOption& GetMotionPathOption() const
174     {
175         return motionPathOption_;
176     }
177 
SetMotionPathOption(const MotionPathOption & option)178     void SetMotionPathOption(const MotionPathOption& option)
179     {
180         motionPathOption_ = option;
181     }
182 
SetTranslateAnimations(AnimationType type,const RefPtr<Animation<DimensionOffset>> & transformOffsetAnimation)183     void SetTranslateAnimations(AnimationType type, const RefPtr<Animation<DimensionOffset>>& transformOffsetAnimation)
184     {
185         if (!transformOffsetAnimation) {
186             LOGE("input translateAnimation is null.");
187             return;
188         }
189         transformOffsetAnimations_[type] = transformOffsetAnimation;
190     }
191 
GetTranslateAnimations()192     const std::unordered_map<AnimationType, RefPtr<Animation<DimensionOffset>>>& GetTranslateAnimations() const
193     {
194         return transformOffsetAnimations_;
195     }
196 
SetTransformFloatAnimation(AnimationType type,const RefPtr<Animation<float>> & transformFloatAnimation)197     void SetTransformFloatAnimation(AnimationType type, const RefPtr<Animation<float>>& transformFloatAnimation)
198     {
199         if (!transformFloatAnimation) {
200             LOGE("input transformFloatAnimation is null.");
201             return;
202         }
203         transformFloatAnimations_[type] = transformFloatAnimation;
204     }
205 
GetMaxScaleXY()206     double GetMaxScaleXY()
207     {
208         return maxScaleXY_;
209     }
210 
SetMaxScaleXY(double maxScaleXY)211     void SetMaxScaleXY(double maxScaleXY)
212     {
213         maxScaleXY_ = maxScaleXY;
214     }
215 
GetTransformFloatAnimation()216     const std::unordered_map<AnimationType, RefPtr<Animation<float>>>& GetTransformFloatAnimation() const
217     {
218         return transformFloatAnimations_;
219     }
220 
SetOpacityAnimation(const RefPtr<Animation<float>> & opacityAnimation)221     void SetOpacityAnimation(const RefPtr<Animation<float>>& opacityAnimation)
222     {
223         if (!opacityAnimation) {
224             LOGE("input opacityAnimation is null.");
225             return;
226         }
227         opacityAnimation_ = opacityAnimation;
228     }
229 
GetOpacityAnimation()230     const RefPtr<Animation<float>>& GetOpacityAnimation() const
231     {
232         return opacityAnimation_;
233     }
234 
SetColorAnimation(const RefPtr<Animation<Color>> & colorAnimation)235     void SetColorAnimation(const RefPtr<Animation<Color>>& colorAnimation)
236     {
237         if (!colorAnimation) {
238             LOGE("input colorAnimation is null.");
239             return;
240         }
241         colorAnimation_ = colorAnimation;
242     }
243 
GetColorAnimation()244     RefPtr<Animation<Color>>& GetColorAnimation()
245     {
246         return colorAnimation_;
247     }
248 
SetPropertyAnimationFloat(PropertyAnimatableType property,const RefPtr<Animation<float>> & animation)249     void SetPropertyAnimationFloat(PropertyAnimatableType property, const RefPtr<Animation<float>>& animation)
250     {
251         if (!animation) {
252             LOGE("Set float property animation failed. animation is null. property: %{public}d", property);
253             return;
254         }
255         floatAnimationMap_[property] = animation;
256     }
257 
AddTransformAnimation(const RefPtr<Animation<TransformOperation>> & transformAnimation)258     void AddTransformAnimation(const RefPtr<Animation<TransformOperation>>& transformAnimation)
259     {
260         if (transformAnimation) {
261             transformAnimations_.push_back(transformAnimation);
262         }
263     }
264 
GetTransformAnimations()265     std::list<RefPtr<Animation<TransformOperation>>>& GetTransformAnimations()
266     {
267         return transformAnimations_;
268     }
269 
GetFloatPropertyAnimation()270     PropertyAnimationFloatMap& GetFloatPropertyAnimation()
271     {
272         return floatAnimationMap_;
273     }
274 
SetTransformOriginChanged(bool change)275     void SetTransformOriginChanged(bool change)
276     {
277         changeTransformOrigin_ = change;
278     }
279 
HasTransformOriginChanged()280     bool HasTransformOriginChanged() const
281     {
282         return changeTransformOrigin_;
283     }
284 
HasTransformOffsetChanged()285     bool HasTransformOffsetChanged() const
286     {
287         return !transformOffsetAnimations_.empty();
288     }
289 
HasTransformFloatChanged()290     bool HasTransformFloatChanged() const
291     {
292         return !transformFloatAnimations_.empty();
293     }
294 
HasTransformChanged()295     bool HasTransformChanged() const
296     {
297         return !transformAnimations_.empty();
298     }
299 
HasDurationChanged()300     bool HasDurationChanged() const
301     {
302         return changeDuration_;
303     }
304 
IsValid()305     bool IsValid() const
306     {
307         return (opacityAnimation_ || colorAnimation_ || !floatAnimationMap_.empty() ||
308                 !transformFloatAnimations_.empty() || !transformOffsetAnimations_.empty() ||
309                 !transformAnimations_.empty() || !propAnimations_.empty());
310     }
311 
ClearListeners()312     void ClearListeners()
313     {
314         if (opacityAnimation_) {
315             opacityAnimation_->ClearListeners();
316         }
317         if (colorAnimation_) {
318             colorAnimation_->ClearListeners();
319         }
320         ClearListeners(floatAnimationMap_);
321         for (auto&& [type, animation] : transformOffsetAnimations_) {
322             if (animation) {
323                 animation->ClearListeners();
324             }
325         }
326         for (auto&& [type, animation] : transformFloatAnimations_) {
327             if (animation) {
328                 animation->ClearListeners();
329             }
330         }
331 
332         for (auto&& animation : transformAnimations_) {
333             if (animation) {
334                 animation->ClearListeners();
335             }
336         }
337     }
338 
SetAllowRunningAsynchronously(bool allowRunningAsynchronously)339     void SetAllowRunningAsynchronously(bool allowRunningAsynchronously)
340     {
341         allowRunningAsynchronously_ = allowRunningAsynchronously;
342     }
343 
GetAllowRunningAsynchronously()344     bool GetAllowRunningAsynchronously()
345     {
346         return allowRunningAsynchronously_;
347     }
348 
349 private:
350     template<class T, class U>
ClearListeners(const std::map<T,RefPtr<Animation<U>>> & animations)351     void ClearListeners(const std::map<T, RefPtr<Animation<U>>>& animations)
352     {
353         for (auto&& [type, animation] : animations) {
354             if (animation) {
355                 animation->ClearListeners();
356             }
357         }
358     }
359 
360 private:
361     FillMode fillMode_ = FillMode::NONE;
362     AnimationDirection direction_ = AnimationDirection::NORMAL;
363     RefPtr<Curve> curve_; // use animation's curve as default.
364     RefPtr<Animation<float>> opacityAnimation_;
365     RefPtr<Animation<Color>> colorAnimation_;
366     RefPtr<Animation<DimensionOffset>> transformOriginAnimation_;
367     PropAnimationMap propAnimations_;
368     PropertyAnimationFloatMap floatAnimationMap_;
369     std::unordered_map<AnimationType, RefPtr<Animation<DimensionOffset>>> transformOffsetAnimations_;
370     std::unordered_map<AnimationType, RefPtr<Animation<float>>> transformFloatAnimations_;
371     std::list<RefPtr<Animation<TransformOperation>>> transformAnimations_;
372     int32_t duration_ = 0;
373     int32_t delay_ = 0;
374     int32_t iteration_ = 1;
375     bool isBackground_ = true;
376     bool changeTransformOrigin_ = false;
377     bool changeDuration_ = false;
378     double maxScaleXY_ = -1.0;
379     float tempo_ = 1.0f;
380     MotionPathOption motionPathOption_;
381     bool allowRunningAsynchronously_ = false;
382 };
383 
384 } // namespace OHOS::Ace
385 
386 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_TWEEN_OPTION_H
387