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 #include "core/components/side_bar/side_bar_animation_controller.h"
17 
18 #include "core/components/side_bar/render_side_bar_container.h"
19 
20 namespace OHOS::Ace {
21 
22 namespace {
23 
24 constexpr int32_t SLIDE_TRANSLATE_DURATION = 400;
25 constexpr double RATIO_NEGATIVE = -1.0;
26 constexpr double RATIO_ZERO = 0;
27 
UpdateSideBarPosition(const WeakPtr<SideBarAnimationController> & weak,double value)28 void UpdateSideBarPosition(const WeakPtr<SideBarAnimationController>& weak, double value)
29 {
30     auto animationController = weak.Upgrade();
31     if (!animationController) {
32         return;
33     }
34 
35     auto sidebar = animationController->GetRenderSideBarContainer().Upgrade();
36     if (!sidebar) {
37         return;
38     }
39 
40     auto renderSideBarContainer = AceType::DynamicCast<RenderSideBarContainer>(sidebar);
41     if (!renderSideBarContainer) {
42         return;
43     }
44     auto curValue = value * renderSideBarContainer->GetSidebarWidth();
45     renderSideBarContainer->UpdateElementPosition(curValue);
46 }
47 
48 }
49 
SideBarAnimation(const WeakPtr<PipelineContext> & context,double start,double end,int delay,int duration,const RefPtr<Curve> & curve,AnimationCallback && callback)50 SideBarAnimation::SideBarAnimation(const WeakPtr<PipelineContext>& context, double start,
51                                    double end, int delay,
52                                    int duration, const RefPtr<Curve>& curve,
53                                    AnimationCallback&& callback)
54     : start_(start), end_(end), delay_(delay), duration_(duration)
55 {
56     curve_ = curve;
57     callback_ = callback;
58     context_ = context;
59     animation_ = AceType::MakeRefPtr<CurveAnimation<double>>(start_, end_, curve_);
60     animation_->AddListener(Animation<double>::ValueCallback(callback_));
61     controller_ = CREATE_ANIMATOR(context_);
62     controller_->SetDuration(duration_);
63     controller_->SetStartDelay(delay_);
64 }
65 
Play()66 void SideBarAnimation::Play()
67 {
68     if (!controller_ || !animation_) {
69         return;
70     }
71     controller_->ClearInterpolators();
72     controller_->AddInterpolator(animation_);
73     controller_->Play();
74 }
75 
Stop()76 void SideBarAnimation::Stop()
77 {
78     if (controller_) {
79         controller_->Finish();
80     }
81 }
82 
StopAnimation()83 void SideBarAnimationController::StopAnimation()
84 {
85     StopRightToLeftAnimation();
86     StopLeftToRightAnimation();
87 }
88 
PlaySideBarContainerToAnimation(SideStatus status)89 void SideBarAnimationController::PlaySideBarContainerToAnimation(SideStatus status)
90 {
91     if (!isAnimationCreated_) {
92         CreateAnimation();
93     }
94 
95     StopRightToLeftAnimation();
96     if (rightToLeftAnimation_) {
97         rightToLeftAnimation_->ClearStopListenerCallback();
98     }
99 
100     StopLeftToRightAnimation();
101     if (leftToRightAnimation_) {
102         leftToRightAnimation_->ClearStopListenerCallback();
103     }
104     bool isSideBarStart = sidebarpositon_ == SideBarPosition::START;
105     if (status == SideStatus::HIDDEN) {
106         if (isSideBarStart) {
107             if (rightToLeftAnimation_ && stopCallback_) {
108                 rightToLeftAnimation_->AddStopListenerCallback(stopCallback_);
109                 PlayRightToLeftAnimation();
110             }
111         } else {
112             if (leftToRightAnimation_ && stopCallback_) {
113                 leftToRightAnimation_->AddStopListenerCallback(stopCallback_);
114                 PlayLeftToRightAnimation();
115             }
116         }
117     } else {
118         if (isSideBarStart) {
119             if (leftToRightAnimation_ && stopCallback_) {
120                 leftToRightAnimation_->AddStopListenerCallback(stopCallback_);
121                 PlayLeftToRightAnimation();
122             }
123         } else {
124             if (rightToLeftAnimation_ && stopCallback_) {
125                 rightToLeftAnimation_->AddStopListenerCallback(stopCallback_);
126                 PlayRightToLeftAnimation();
127             }
128         }
129     }
130 }
131 
CreateAnimation()132 void SideBarAnimationController::CreateAnimation()
133 {
134     auto weak = AceType::WeakClaim(this);
135 
136     leftToRightAnimation_ = AceType::MakeRefPtr<SideBarAnimation>(context_, RATIO_NEGATIVE,
137         RATIO_ZERO, 0, SLIDE_TRANSLATE_DURATION, Curves::FRICTION, [weak](double value) {
138             UpdateSideBarPosition(weak, value);
139         });
140 
141     rightToLeftAnimation_ = AceType::MakeRefPtr<SideBarAnimation>(context_, RATIO_ZERO,
142         RATIO_NEGATIVE, 0, SLIDE_TRANSLATE_DURATION, Curves::FRICTION, [weak](double value) {
143             UpdateSideBarPosition(weak, value);
144         });
145 
146     isAnimationCreated_ = true;
147 }
148 
PlayRightToLeftAnimation()149 void SideBarAnimationController::PlayRightToLeftAnimation()
150 {
151     if (rightToLeftAnimation_) {
152         rightToLeftAnimation_->Play();
153     }
154 }
155 
StopRightToLeftAnimation()156 void SideBarAnimationController::StopRightToLeftAnimation()
157 {
158     if (rightToLeftAnimation_) {
159         rightToLeftAnimation_->Stop();
160     }
161 }
162 
PlayLeftToRightAnimation()163 void SideBarAnimationController::PlayLeftToRightAnimation()
164 {
165     if (leftToRightAnimation_) {
166         leftToRightAnimation_->Play();
167     }
168 }
169 
StopLeftToRightAnimation()170 void SideBarAnimationController::StopLeftToRightAnimation()
171 {
172     if (leftToRightAnimation_) {
173         leftToRightAnimation_->Stop();
174     }
175 }
176 
177 } // namespace OHOS::Ace
178