1 /*
2  * Copyright (c) 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_COMPONENTS_NG_PROPERTIES_TRANSITION_PROPERTY_H
17 #define FOUNDATION_ACE_FRAMEWORKS_COMPONENTS_NG_PROPERTIES_TRANSITION_PROPERTY_H
18 
19 #include <iomanip>
20 #include <ios>
21 #include <optional>
22 #include <sstream>
23 #include <string>
24 
25 #include "base/geometry/calc_dimension.h"
26 #include "core/animation/animation_pub.h"
27 #include "core/components/common/properties/animation_option.h"
28 #include "core/components_ng/property/property.h"
29 
30 
31 namespace OHOS::Ace::NG {
32 
33 struct TranslateOptions {
34     CalcDimension x;
35     CalcDimension y;
36     CalcDimension z;
37     TranslateOptions() = default;
TranslateOptionsTranslateOptions38     TranslateOptions(const CalcDimension& x, const CalcDimension& y, const CalcDimension& z) : x(x), y(y), z(z) {}
39     // for inner construct, default unit is PX
TranslateOptionsTranslateOptions40     TranslateOptions(float x, float y, float z) : x(x), y(y), z(z) {}
41     bool operator==(const TranslateOptions& other) const
42     {
43         return x == other.x && y == other.y && z == other.z;
44     }
ToStringTranslateOptions45     std::string ToString() const
46     {
47         return "translate:[" + x.ToString() + ", " + y.ToString() + ", " + z.ToString() + "]";
48     }
49 };
50 struct ScaleOptions {
51     float xScale = 1.0f;
52     float yScale = 1.0f;
53     float zScale = 1.0f;
54     CalcDimension centerX;
55     CalcDimension centerY;
ScaleOptionsScaleOptions56     ScaleOptions(float xScale, float yScale, float zScale, const CalcDimension& centerX, const CalcDimension& centerY)
57         : xScale(xScale), yScale(yScale), zScale(zScale), centerX(centerX), centerY(centerY)
58     {}
59     ScaleOptions() = default;
60     bool operator==(const ScaleOptions& other) const
61     {
62         return NearEqual(xScale, other.xScale) && NearEqual(yScale, other.yScale) && NearEqual(zScale, other.zScale) &&
63                NearEqual(centerX, other.centerX) && NearEqual(centerY, other.centerY);
64     }
ToStringScaleOptions65     std::string ToString() const
66     {
67         return "scale:[" + std::to_string(xScale) + "," + std::to_string(yScale) + "," + std::to_string(zScale) + "," +
68                centerX.ToString() + "," + centerY.ToString() + "]";
69     }
70 };
71 struct RotateOptions {
72     float xDirection = 0.0f;
73     float yDirection = 0.0f;
74     float zDirection = 0.0f;
75     // angle in degree unit
76     float angle = 0.0f;
77     CalcDimension centerX;
78     CalcDimension centerY;
79     CalcDimension centerZ;
80     // camera distance value
81     float perspective = 0.0f;
82 
83     RotateOptions(float xDirection, float yDirection, float zDirection, float angle, const CalcDimension& centerX,
84         const CalcDimension& centerY, const CalcDimension& centerZ = CalcDimension(0.0f, DimensionUnit::VP),
85         const float perspective = 0.0f) : xDirection(xDirection), yDirection(yDirection), zDirection(zDirection),
86         angle(angle), centerX(centerX), centerY(centerY), centerZ(centerZ), perspective(perspective) {}
87     RotateOptions() = default;
88     bool operator==(const RotateOptions& other) const
89     {
90         return NearEqual(angle, other.angle) && NearEqual(xDirection, other.xDirection) &&
91                NearEqual(yDirection, other.yDirection) && NearEqual(zDirection, other.zDirection) &&
92                NearEqual(centerX, other.centerX) && NearEqual(centerY, other.centerY) &&
93                NearEqual(centerZ, other.centerZ) && NearEqual(perspective, other.perspective);
94     }
ToStringRotateOptions95     std::string ToString() const
96     {
97         return "rotate:[" + std::to_string(xDirection) + "," + std::to_string(yDirection) + "," +
98                std::to_string(zDirection) + "," + centerX.ToString() + "," + centerY.ToString() +
99                "," + centerZ.ToString() + ", angle:" + std::to_string(angle) + ", perspective:" +
100                std::to_string(perspective) + "]";
101     }
102 };
103 struct TransitionOptions {
104     TransitionType Type = TransitionType::ALL;
105     ACE_DEFINE_PROPERTY_GROUP_ITEM(Opacity, float);
106     ACE_DEFINE_PROPERTY_GROUP_ITEM(Translate, TranslateOptions);
107     ACE_DEFINE_PROPERTY_GROUP_ITEM(Scale, ScaleOptions);
108     ACE_DEFINE_PROPERTY_GROUP_ITEM(Rotate, RotateOptions);
GetDefaultTransitionTransitionOptions109     static TransitionOptions GetDefaultTransition(TransitionType type)
110     {
111         TransitionOptions options;
112         options.Type = type;
113         options.UpdateOpacity(0.0f);
114         return options;
115     }
116     bool operator==(const TransitionOptions& other) const
117     {
118         return NearEqual(Type, other.Type) && NearEqual(propOpacity, other.propOpacity) &&
119                NearEqual(propTranslate, other.propTranslate) && NearEqual(propScale, other.propScale) &&
120                NearEqual(propRotate, other.propRotate);
121     }
ToStringTransitionOptions122     std::string ToString() const
123     {
124         std::stringstream ss;
125         ss << "type:"
126            << (Type == TransitionType::ALL ? "all" : (Type == TransitionType::APPEARING ? "appear" : "disappear"))
127            << ", opacity:" << (HasOpacity() ? std::to_string(GetOpacityValue()) : "none") << ", "
128            << (HasTranslate() ? GetTranslate()->ToString() : "translate: none") << ", "
129            << (HasScale() ? GetScale()->ToString() : "scale: none") << ", "
130            << (HasRotate() ? GetRotate()->ToString() : "rotate: none");
131         return ss.str();
132     }
133 };
134 
135 enum class ChainedTransitionEffectType {
136     IDENTITY = 0,
137     OPACITY,
138     SLIDE_SWITCH,
139     MOVE,
140     TRANSLATE,
141     ROTATE,
142     SCALE,
143     ASYMMETRIC,
144 };
145 
146 enum class TransitionEdge {
147     TOP = 0,
148     BOTTOM,
149     START,
150     END,
151 };
152 
153 class ChainedTransitionEffect : public AceType {
154     DECLARE_ACE_TYPE(ChainedTransitionEffect, AceType);
155 
156 public:
ChainedTransitionEffect(ChainedTransitionEffectType type)157     explicit ChainedTransitionEffect(ChainedTransitionEffectType type) : type_(type) {}
158 
GetType()159     ChainedTransitionEffectType GetType() const
160     {
161         return type_;
162     }
GetNext()163     const RefPtr<ChainedTransitionEffect>& GetNext() const
164     {
165         return next_;
166     }
GetAnimationOption()167     const std::shared_ptr<AnimationOption>& GetAnimationOption() const
168     {
169         return animationOption_;
170     }
SetNext(const RefPtr<ChainedTransitionEffect> & next)171     void SetNext(const RefPtr<ChainedTransitionEffect>& next)
172     {
173         next_ = next;
174     }
SetAnimationOption(const std::shared_ptr<AnimationOption> & option)175     void SetAnimationOption(const std::shared_ptr<AnimationOption>& option)
176     {
177         animationOption_ = option;
178     }
179     virtual std::string ToString() = 0;
180 
181 protected:
AnimationOptionToString()182     std::string AnimationOptionToString() const
183     {
184         if (animationOption_) {
185             return "{duration:" + std::to_string(animationOption_->GetDuration()) +
186                    ", delay:" + std::to_string(animationOption_->GetDelay()) + ", curve:" +
187                    (animationOption_->GetCurve() ? animationOption_->GetCurve()->ToString() : std::string("null")) +
188                    "}";
189         }
190         return "null";
191     }
192     ChainedTransitionEffectType type_;
193     std::shared_ptr<AnimationOption> animationOption_;
194     RefPtr<ChainedTransitionEffect> next_;
195 };
196 
197 class OneCenterTransitionOptionType : public AceType {
198     DECLARE_ACE_TYPE(OneCenterTransitionOptionType, AceType);
199 
200 public:
201     OneCenterTransitionOptionType() = default;
202     ~OneCenterTransitionOptionType() = default;
GetCenterX()203     Dimension& GetCenterX()
204     {
205         return centerX_;
206     }
GetCenterY()207     Dimension& GetCenterY()
208     {
209         return centerY_;
210     }
GetCenterZ()211     Dimension& GetCenterZ()
212     {
213         return centerZ_;
214     }
GetTransitionEffect()215     RefPtr<NG::ChainedTransitionEffect> GetTransitionEffect()
216     {
217         return effect_;
218     }
SetCenterX(const Dimension & centerX)219     void SetCenterX(const Dimension& centerX)
220     {
221         centerX_ = centerX;
222     }
SetCenterY(const Dimension & centerY)223     void SetCenterY(const Dimension& centerY)
224     {
225         centerY_ = centerY;
226     }
SetCenterZ(const Dimension & centerZ)227     void SetCenterZ(const Dimension& centerZ)
228     {
229         centerZ_ = centerZ;
230     }
SetTransitionEffect(const RefPtr<NG::ChainedTransitionEffect> & effect)231     void SetTransitionEffect(const RefPtr<NG::ChainedTransitionEffect>& effect)
232     {
233         effect_ = effect;
234     }
235     bool operator==(const OneCenterTransitionOptionType& other) const
236     {
237         return false;
238     }
239     OneCenterTransitionOptionType& operator=(OneCenterTransitionOptionType& other)
240     {
241         centerX_ = other.GetCenterX();
242         centerY_ = other.GetCenterY();
243         centerZ_ = other.GetCenterZ();
244         effect_ = other.GetTransitionEffect();
245         return *this;
246     }
247 
248 private:
249     Dimension centerX_;
250     Dimension centerY_;
251     Dimension centerZ_;
252     RefPtr<NG::ChainedTransitionEffect> effect_;
253 };
254 
255 class ChainedTranslateEffect final : public ChainedTransitionEffect {
256     DECLARE_ACE_TYPE(ChainedTranslateEffect, ChainedTransitionEffect);
257 
258 public:
ChainedTranslateEffect(const TranslateOptions & option)259     explicit ChainedTranslateEffect(const TranslateOptions& option)
260         : ChainedTransitionEffect(ChainedTransitionEffectType::TRANSLATE), effect_(option)
261     {}
262 
GetEffect()263     const TranslateOptions& GetEffect() const
264     {
265         return effect_;
266     }
SetTranslateEffect(const TranslateOptions & effect)267     void SetTranslateEffect(const TranslateOptions& effect)
268     {
269         effect_ = effect;
270     }
ToString()271     std::string ToString() override
272     {
273         std::string ans = "{type: translate";
274         ans += ", effect: " + effect_.ToString();
275         ans += ", animation: " + AnimationOptionToString();
276         ans += ", successor: " + (next_ ? next_->ToString() : std::string("null")) + "}";
277         return ans;
278     }
279 
280 private:
281     TranslateOptions effect_;
282 };
283 
284 class ChainedRotateEffect final : public ChainedTransitionEffect {
285     DECLARE_ACE_TYPE(ChainedRotateEffect, ChainedTransitionEffect);
286 
287 public:
ChainedRotateEffect(const RotateOptions & option)288     explicit ChainedRotateEffect(const RotateOptions& option)
289         : ChainedTransitionEffect(ChainedTransitionEffectType::ROTATE), effect_(option)
290     {}
291 
GetEffect()292     const RotateOptions& GetEffect() const
293     {
294         return effect_;
295     }
296 
SetRotateEffect(const RotateOptions & effect)297     void SetRotateEffect(const RotateOptions& effect)
298     {
299         effect_ = effect;
300     }
301 
ToString()302     std::string ToString() override
303     {
304         std::string ans = "{type: rotate";
305         ans += ", effect: " + effect_.ToString();
306         ans += ", animation: " + AnimationOptionToString();
307         ans += ", successor: " + (next_ ? next_->ToString() : std::string("null")) + "}";
308         return ans;
309     }
310 
311 private:
312     RotateOptions effect_;
313 };
314 
315 class ChainedScaleEffect final : public ChainedTransitionEffect {
316     DECLARE_ACE_TYPE(ChainedScaleEffect, ChainedTransitionEffect);
317 
318 public:
ChainedScaleEffect(const ScaleOptions & option)319     explicit ChainedScaleEffect(const ScaleOptions& option)
320         : ChainedTransitionEffect(ChainedTransitionEffectType::SCALE), effect_(option)
321     {}
322 
GetEffect()323     const ScaleOptions& GetEffect() const
324     {
325         return effect_;
326     }
SetScaleEffect(const ScaleOptions & effect)327     void SetScaleEffect(const ScaleOptions& effect)
328     {
329         effect_ = effect;
330     }
ToString()331     std::string ToString() override
332     {
333         std::string ans = "{type: scale";
334         ans += ", effect: " + effect_.ToString();
335         ans += ", animation: " + AnimationOptionToString();
336         ans += ", successor: " + (next_ ? next_->ToString() : std::string("null")) + "}";
337         return ans;
338     }
339 
340 private:
341     ScaleOptions effect_;
342 };
343 
344 class ChainedOpacityEffect final : public ChainedTransitionEffect {
345     DECLARE_ACE_TYPE(ChainedOpacityEffect, ChainedTransitionEffect);
346 
347 public:
ChainedOpacityEffect(float opacity)348     explicit ChainedOpacityEffect(float opacity)
349         : ChainedTransitionEffect(ChainedTransitionEffectType::OPACITY), opacity_(opacity)
350     {}
351 
GetEffect()352     const float& GetEffect() const
353     {
354         return opacity_;
355     }
356 
SetOpacity(float opacity)357     void SetOpacity(float opacity)
358     {
359         opacity_ = opacity;
360     }
361 
ToString()362     std::string ToString() override
363     {
364         std::string ans = "{type: opacity";
365         ans += ", effect: " + std::to_string(opacity_);
366         ans += ", animation: " + AnimationOptionToString();
367         ans += ", successor: " + (next_ ? next_->ToString() : std::string("null")) + "}";
368         return ans;
369     }
370 
371 private:
372     float opacity_;
373 };
374 
375 class ChainedMoveEffect final : public ChainedTransitionEffect {
376     DECLARE_ACE_TYPE(ChainedMoveEffect, ChainedTransitionEffect);
377 
378 public:
ChainedMoveEffect(TransitionEdge edge)379     explicit ChainedMoveEffect(TransitionEdge edge)
380         : ChainedTransitionEffect(ChainedTransitionEffectType::MOVE), edge_(edge)
381     {}
382 
GetEffect()383     const TransitionEdge& GetEffect() const
384     {
385         return edge_;
386     }
ToString()387     std::string ToString() override
388     {
389         const static std::string edgeName[] = { "top", "bottom", "start", "end" };
390         std::string ans = "{type: move";
391         ans += ", effect: " + edgeName[static_cast<int>(edge_)];
392         ans += ", animation: " + AnimationOptionToString();
393         ans += ", successor: " + (next_ ? next_->ToString() : std::string("null")) + "}";
394         return ans;
395     }
396 
397 private:
398     TransitionEdge edge_;
399 };
400 
401 class ChainedSlideSwitchEffect final : public ChainedTransitionEffect {
402     DECLARE_ACE_TYPE(ChainedSlideSwitchEffect, ChainedTransitionEffect);
403 
404 public:
ChainedSlideSwitchEffect()405     explicit ChainedSlideSwitchEffect() : ChainedTransitionEffect(ChainedTransitionEffectType::SLIDE_SWITCH) {}
ToString()406     std::string ToString() override
407     {
408         std::string ans = "{type: slideSwitch";
409         ans += ", animation: " + AnimationOptionToString();
410         ans += ", successor: " + (next_ ? next_->ToString() : std::string("null")) + "}";
411         return ans;
412     }
413 };
414 
415 class ChainedIdentityEffect final : public ChainedTransitionEffect {
416     DECLARE_ACE_TYPE(ChainedIdentityEffect, ChainedTransitionEffect);
417 
418 public:
ChainedIdentityEffect()419     explicit ChainedIdentityEffect() : ChainedTransitionEffect(ChainedTransitionEffectType::IDENTITY) {}
ToString()420     std::string ToString() override
421     {
422         std::string ans = "{type: identity";
423         ans += ", animation: " + AnimationOptionToString();
424         ans += ", successor: " + (next_ ? next_->ToString() : std::string("null")) + "}";
425         return ans;
426     }
427 };
428 
429 class ChainedAsymmetricEffect final : public ChainedTransitionEffect {
430     DECLARE_ACE_TYPE(ChainedAsymmetricEffect, ChainedTransitionEffect);
431 
432 public:
ChainedAsymmetricEffect(const RefPtr<ChainedTransitionEffect> & appear,const RefPtr<ChainedTransitionEffect> & disappear)433     explicit ChainedAsymmetricEffect(
434         const RefPtr<ChainedTransitionEffect>& appear, const RefPtr<ChainedTransitionEffect>& disappear)
435         : ChainedTransitionEffect(ChainedTransitionEffectType::ASYMMETRIC), appearEffect_(appear),
436           disappearEffect_(disappear)
437     {}
438 
GetAppearEffect()439     const RefPtr<ChainedTransitionEffect>& GetAppearEffect() const
440     {
441         return appearEffect_;
442     }
GetDisappearEffect()443     const RefPtr<ChainedTransitionEffect>& GetDisappearEffect() const
444     {
445         return disappearEffect_;
446     }
ToString()447     std::string ToString() override
448     {
449         std::string ans = "{type: asymmetric";
450         ans += ", effect: {appear: " + (appearEffect_ ? appearEffect_->ToString() : "null") +
451                ", disappear: " + (disappearEffect_ ? disappearEffect_->ToString() : "null") + "}";
452         ans += ", animation: " + AnimationOptionToString();
453         ans += ", successor: " + (next_ ? next_->ToString() : std::string("null")) + "}";
454         return ans;
455     }
456 
457 private:
458     RefPtr<ChainedTransitionEffect> appearEffect_;
459     RefPtr<ChainedTransitionEffect> disappearEffect_;
460 };
461 } // namespace OHOS::Ace::NG
462 #endif // FOUNDATION_ACE_FRAMEWORKS_COMPONENTS_NG_PROPERTIES_TRANSITION_PROPERTY_H
463