1 /*
2  * Copyright (c) 2024 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 META_SRC_STAGGERED_ANIMATION_STATE_H
17 #define META_SRC_STAGGERED_ANIMATION_STATE_H
18 
19 #include <algorithm>
20 #include <functional>
21 
22 #include <meta/api/property/property_event_handler.h>
23 #include <meta/base/namespace.h>
24 #include <meta/ext/object_container.h>
25 #include <meta/interface/animation/intf_animation.h>
26 
27 #include "animation_state.h"
28 
META_BEGIN_NAMESPACE()29 META_BEGIN_NAMESPACE()
30 
31 namespace Internal {
32 
33 /**
34  * @brief The Base state class for animation containers.
35  */
36 class StaggeredAnimationState : public AnimationState {
37     using Super = AnimationState;
38 
39 public:
40     struct AnimationSegment {
41         IAnimation::Ptr animation_;                   // Animation in the segment
42         IAnimationController::WeakPtr controller_;    // The view animation was originally associated with (if any)
43         float startProgress_ {};                      // Progress [0..1] of the animation at start of the segment
44         float endProgress_ {};                        // Percentage [0..1] of the animation length in this segment
45         PropertyChangedEventHandler durationChanged_; // Handler for animation duration change
46         PropertyChangedEventHandler validChanged_;    // Handler for animation validity change
47     };
48 
49     using SegmentVector = BASE_NS::vector<AnimationSegment>;
50 
51 public:
52     META_NO_COPY_MOVE(StaggeredAnimationState)
53     StaggeredAnimationState() = default;
54     ~StaggeredAnimationState() = default;
55 
56     IContainer& GetContainerInterface() noexcept
57     {
58         CORE_ASSERT(container_);
59         return *container_;
60     }
61     const IContainer& GetContainerInterface() const noexcept
62     {
63         CORE_ASSERT(container_);
64         return *container_;
65     }
66 
67     IEvent::Ptr OnChildrenChanged() const noexcept
68     {
69         return onChildrenChanged_;
70     }
71     bool IsValid() const;
72 
73     virtual void ChildrenChanged();
74 
75 protected: // AnimationState
76     bool Initialize(AnimationStateParams&& params) override;
77     void Uninitialize() override;
78     void UpdateTotalDuration() override;
79 
80 private:
81     void ChildAdded(const ChildChangedInfo& info);
82     void ChildRemoved(const ChildChangedInfo& info);
83     void ChildMoved(const ChildMovedInfo& info);
84     void RemoveChild(typename SegmentVector::iterator& item);
85 
86 protected:
87     SegmentVector& GetChildren() noexcept
88     {
89         return children_;
90     }
91     const SegmentVector& GetChildren() const noexcept
92     {
93         return children_;
94     }
95 
96     virtual IContainer::Ptr CreateContainer() const = 0;
97 
98 protected:
99     TimeSpan baseDuration_ { TimeSpan::Zero() };
100 
101 private:
102     IEvent::Ptr onChildrenChanged_;
103     IOnChanged::InterfaceTypePtr childrenChanged_;
104 
105     IContainer::Ptr container_;
106     IAnimationController::WeakPtr controller_;
107     SegmentVector children_;
108 };
109 
110 /**
111  * @brief State class for parallel animations
112  */
113 class ParallelAnimationState : public StaggeredAnimationState {
114     using Super = StaggeredAnimationState;
115 
116 public:
117     AnyReturnValue Evaluate();
118 
119 protected:
120     IContainer::Ptr CreateContainer() const override;
121     void ChildrenChanged() override;
122     TimeSpan GetAnimationBaseDuration() const override;
123 };
124 
125 /**
126  * @brief State class for sequential animations
127  */
128 class SequentialAnimationState : public StaggeredAnimationState {
129     using Super = StaggeredAnimationState;
130 
131 public:
132     AnyReturnValue Evaluate();
133 
134 protected:
135     IContainer::Ptr CreateContainer() const override;
136     void ChildrenChanged() override;
137     TimeSpan GetAnimationBaseDuration() const override;
138 
139     struct ActiveAnimation {
140         const AnimationSegment* segment {};
141         int64_t index {};
142         explicit operator bool() const noexcept
143         {
144             return segment != nullptr;
145         }
146     };
147 
148     ActiveAnimation GetActiveAnimation(float progress, bool reverse) const;
149 };
150 
151 } // namespace Internal
152 
153 META_END_NAMESPACE()
154 
155 #endif // META_SRC_STAGGERED_ANIMATION_STATE_H
156