1 /*
2  * Copyright (c) 2021 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 #include "base/geometry/animatable_matrix4.h"
17 
18 #include "core/event/ace_event_helper.h"
19 
20 namespace OHOS::Ace {
21 
operator =(const Matrix4 & newMatrix4)22 AnimatableMatrix4& AnimatableMatrix4::operator=(const Matrix4& newMatrix4)
23 {
24     ResetAnimatableMatrix();
25     Matrix4& matrix4 = *this;
26     matrix4 = newMatrix4;
27     return *this;
28 }
29 
operator =(const AnimatableMatrix4 & newMatrix4)30 AnimatableMatrix4& AnimatableMatrix4::operator=(const AnimatableMatrix4& newMatrix4)
31 {
32     SetAnimationOption(newMatrix4.GetAnimationOption());
33     auto pipelineContext = context_.Upgrade();
34     if (!animationCallback_ || !pipelineContext) {
35         Matrix4& matrix4 = *this;
36         matrix4 = newMatrix4;
37         return *this;
38     }
39     AnimationOption explicitAnim = pipelineContext->GetExplicitAnimationOption();
40     if (explicitAnim.IsValid()) {
41         SetAnimationOption(explicitAnim);
42         AnimateTo(newMatrix4);
43     } else if (animationOption_.IsValid()) {
44         AnimateTo(newMatrix4);
45     } else {
46         ResetController();
47         Matrix4& matrix4 = *this;
48         matrix4 = newMatrix4;
49     }
50     isFirstAssign_ = false;
51     return *this;
52 }
53 
MoveTo(const Matrix4 & target)54 void AnimatableMatrix4::MoveTo(const Matrix4& target)
55 {
56     Matrix4& matrix4 = *this;
57     matrix4 = target;
58     isFirstAssign_ = false;
59 }
60 
AnimateTo(const Matrix4 & endValue)61 void AnimatableMatrix4::AnimateTo(const Matrix4& endValue)
62 {
63     if (isFirstAssign_) {
64         isFirstAssign_ = false;
65         Matrix4& matrix4 = *this;
66         matrix4 = endValue;
67         return;
68     }
69 
70     if (*this == endValue && !evaluator_) {
71         return;
72     }
73     ResetController();
74     if (!animationController_) {
75         animationController_ = CREATE_ANIMATOR(context_);
76     }
77 
78     TransformOperation operationInit;
79     TransformOperation operationEnd;
80     operationInit.type_ = TransformOperationType::MATRIX;
81     operationEnd.type_ = TransformOperationType::MATRIX;
82     operationInit.matrix4_ = static_cast<Matrix4>(*this);
83     operationEnd.matrix4_ = endValue;
84     RefPtr<CurveAnimation<TransformOperation>> animation = AceType::MakeRefPtr<CurveAnimation<TransformOperation>>(
85         operationInit, operationEnd, animationOption_.GetCurve());
86     if (evaluator_) {
87         animation->SetEvaluator(evaluator_);
88     }
89     animation->AddListener(std::bind(&AnimatableMatrix4::OnAnimationCallback, this, std::placeholders::_1));
90     animationController_->AddInterpolator(animation);
91     auto onFinishEvent = animationOption_.GetOnFinishEvent();
92     if (onFinishEvent) {
93         animationController_->AddStopListener([onFinishEvent, weakContext = context_] {
94             auto context = weakContext.Upgrade();
95             if (context) {
96                 context->PostAsyncEvent(onFinishEvent, "ArkUIAnimatableMatrix4FinishEvent");
97             }
98         });
99     }
100     if (stopCallback_) {
101         animationController_->AddStopListener(stopCallback_);
102     }
103     animationController_->SetDuration(animationOption_.GetDuration());
104     animationController_->SetStartDelay(animationOption_.GetDelay());
105     animationController_->SetIteration(animationOption_.GetIteration());
106     animationController_->SetTempo(animationOption_.GetTempo());
107     animationController_->SetAnimationDirection(animationOption_.GetAnimationDirection());
108     animationController_->SetFillMode(FillMode::FORWARDS);
109     animationController_->SetAllowRunningAsynchronously(animationOption_.GetAllowRunningAsynchronously());
110     animationController_->Play();
111 }
112 
ResetController()113 void AnimatableMatrix4::ResetController()
114 {
115     if (animationController_) {
116         if (!animationController_->IsStopped()) {
117             animationController_->Stop();
118         }
119         animationController_->ClearInterpolators();
120         animationController_->ClearAllListeners();
121         animationController_.Reset();
122     }
123 }
124 
OnAnimationCallback(const TransformOperation & value)125 void AnimatableMatrix4::OnAnimationCallback(const TransformOperation& value)
126 {
127     Matrix4& matrix4 = *this;
128     matrix4 = value.matrix4_;
129     if (animationCallback_) {
130         animationCallback_();
131     }
132 }
133 
ResetAnimatableMatrix()134 void AnimatableMatrix4::ResetAnimatableMatrix()
135 {
136     isFirstAssign_ = true;
137     animationOption_ = AnimationOption();
138     animationController_ = nullptr;
139     context_ = nullptr;
140     animationCallback_ = nullptr;
141 }
142 
143 } // namespace OHOS::Ace
144