123b3eb3cSopenharmony_ci/*
223b3eb3cSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
323b3eb3cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
423b3eb3cSopenharmony_ci * you may not use this file except in compliance with the License.
523b3eb3cSopenharmony_ci * You may obtain a copy of the License at
623b3eb3cSopenharmony_ci *
723b3eb3cSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
823b3eb3cSopenharmony_ci *
923b3eb3cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1023b3eb3cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1123b3eb3cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1223b3eb3cSopenharmony_ci * See the License for the specific language governing permissions and
1323b3eb3cSopenharmony_ci * limitations under the License.
1423b3eb3cSopenharmony_ci */
1523b3eb3cSopenharmony_ci
1623b3eb3cSopenharmony_ci#include "base/geometry/animatable_dimension.h"
1723b3eb3cSopenharmony_ci#include "core/event/ace_event_helper.h"
1823b3eb3cSopenharmony_ci
1923b3eb3cSopenharmony_cinamespace OHOS::Ace {
2023b3eb3cSopenharmony_ciAnimatableDimension& AnimatableDimension::operator=(const Dimension& newDimension)
2123b3eb3cSopenharmony_ci{
2223b3eb3cSopenharmony_ci    ResetAnimatableDimension();
2323b3eb3cSopenharmony_ci    Dimension& dimension = *this;
2423b3eb3cSopenharmony_ci    dimension = newDimension;
2523b3eb3cSopenharmony_ci    return *this;
2623b3eb3cSopenharmony_ci}
2723b3eb3cSopenharmony_ci
2823b3eb3cSopenharmony_ciAnimatableDimension& AnimatableDimension::operator=(const CalcDimension& newDimension)
2923b3eb3cSopenharmony_ci{
3023b3eb3cSopenharmony_ci    ResetAnimatableDimension();
3123b3eb3cSopenharmony_ci    CalcDimension& dimension = *this;
3223b3eb3cSopenharmony_ci    dimension = newDimension;
3323b3eb3cSopenharmony_ci    return *this;
3423b3eb3cSopenharmony_ci}
3523b3eb3cSopenharmony_ci
3623b3eb3cSopenharmony_ciAnimatableDimension& AnimatableDimension::operator=(const AnimatableDimension& newDimension)
3723b3eb3cSopenharmony_ci{
3823b3eb3cSopenharmony_ci    SetUnit(newDimension.Unit());
3923b3eb3cSopenharmony_ci    SetAnimationOption(newDimension.GetAnimationOption());
4023b3eb3cSopenharmony_ci    auto pipelineContext = context_.Upgrade();
4123b3eb3cSopenharmony_ci    if (!animationCallback_ || !pipelineContext) {
4223b3eb3cSopenharmony_ci        if (newDimension.Unit() == DimensionUnit::CALC) {
4323b3eb3cSopenharmony_ci            SetCalcValue(newDimension.CalcValue());
4423b3eb3cSopenharmony_ci        } else {
4523b3eb3cSopenharmony_ci            SetValue(newDimension.Value());
4623b3eb3cSopenharmony_ci        }
4723b3eb3cSopenharmony_ci        return *this;
4823b3eb3cSopenharmony_ci    }
4923b3eb3cSopenharmony_ci    AnimationOption explicitAnim = pipelineContext->GetExplicitAnimationOption();
5023b3eb3cSopenharmony_ci    if (explicitAnim.IsValid()) {
5123b3eb3cSopenharmony_ci        SetAnimationOption(explicitAnim);
5223b3eb3cSopenharmony_ci        AnimateTo(newDimension.Value());
5323b3eb3cSopenharmony_ci    } else if (animationOption_.IsValid()) {
5423b3eb3cSopenharmony_ci        AnimateTo(newDimension.Value());
5523b3eb3cSopenharmony_ci    } else {
5623b3eb3cSopenharmony_ci        ResetController();
5723b3eb3cSopenharmony_ci        if (newDimension.Unit() == DimensionUnit::CALC) {
5823b3eb3cSopenharmony_ci            SetCalcValue(newDimension.CalcValue());
5923b3eb3cSopenharmony_ci        } else {
6023b3eb3cSopenharmony_ci            SetValue(newDimension.Value());
6123b3eb3cSopenharmony_ci        }
6223b3eb3cSopenharmony_ci    }
6323b3eb3cSopenharmony_ci    isFirstAssign_ = false;
6423b3eb3cSopenharmony_ci    return *this;
6523b3eb3cSopenharmony_ci}
6623b3eb3cSopenharmony_ci
6723b3eb3cSopenharmony_civoid AnimatableDimension::AnimateTo(double endValue)
6823b3eb3cSopenharmony_ci{
6923b3eb3cSopenharmony_ci    if (isFirstAssign_) {
7023b3eb3cSopenharmony_ci        isFirstAssign_ = false;
7123b3eb3cSopenharmony_ci        SetValue(endValue);
7223b3eb3cSopenharmony_ci        return;
7323b3eb3cSopenharmony_ci    }
7423b3eb3cSopenharmony_ci    if (NearEqual(Value(), endValue) && !evaluator_) {
7523b3eb3cSopenharmony_ci        return;
7623b3eb3cSopenharmony_ci    }
7723b3eb3cSopenharmony_ci    ResetController();
7823b3eb3cSopenharmony_ci    if (!animationController_) {
7923b3eb3cSopenharmony_ci        animationController_ = CREATE_ANIMATOR(context_);
8023b3eb3cSopenharmony_ci    }
8123b3eb3cSopenharmony_ci    RefPtr<CurveAnimation<double>> animation =
8223b3eb3cSopenharmony_ci        AceType::MakeRefPtr<CurveAnimation<double>>(Value(), endValue, animationOption_.GetCurve());
8323b3eb3cSopenharmony_ci    if (evaluator_) {
8423b3eb3cSopenharmony_ci        animation->SetEvaluator(evaluator_);
8523b3eb3cSopenharmony_ci    }
8623b3eb3cSopenharmony_ci    animation->AddListener(std::bind(&AnimatableDimension::OnAnimationCallback, this, std::placeholders::_1));
8723b3eb3cSopenharmony_ci
8823b3eb3cSopenharmony_ci    animationController_->AddInterpolator(animation);
8923b3eb3cSopenharmony_ci    auto onFinishEvent = animationOption_.GetOnFinishEvent();
9023b3eb3cSopenharmony_ci    if (onFinishEvent) {
9123b3eb3cSopenharmony_ci        animationController_->AddStopListener([onFinishEvent, weakContext = context_] {
9223b3eb3cSopenharmony_ci            auto context = weakContext.Upgrade();
9323b3eb3cSopenharmony_ci            if (context) {
9423b3eb3cSopenharmony_ci                context->PostAsyncEvent(onFinishEvent, "ArkUIAnimatableDimensionFinishEvent");
9523b3eb3cSopenharmony_ci            }
9623b3eb3cSopenharmony_ci        });
9723b3eb3cSopenharmony_ci    }
9823b3eb3cSopenharmony_ci    if (stopCallback_) {
9923b3eb3cSopenharmony_ci        animationController_->AddStopListener(stopCallback_);
10023b3eb3cSopenharmony_ci    }
10123b3eb3cSopenharmony_ci    animationController_->SetDuration(animationOption_.GetDuration());
10223b3eb3cSopenharmony_ci    animationController_->SetStartDelay(animationOption_.GetDelay());
10323b3eb3cSopenharmony_ci    animationController_->SetIteration(animationOption_.GetIteration());
10423b3eb3cSopenharmony_ci    animationController_->SetTempo(animationOption_.GetTempo());
10523b3eb3cSopenharmony_ci    animationController_->SetAnimationDirection(animationOption_.GetAnimationDirection());
10623b3eb3cSopenharmony_ci    animationController_->SetFillMode(FillMode::FORWARDS);
10723b3eb3cSopenharmony_ci    animationController_->SetAllowRunningAsynchronously(animationOption_.GetAllowRunningAsynchronously());
10823b3eb3cSopenharmony_ci    animationController_->Play();
10923b3eb3cSopenharmony_ci}
11023b3eb3cSopenharmony_ci
11123b3eb3cSopenharmony_civoid AnimatableDimension::ResetController()
11223b3eb3cSopenharmony_ci{
11323b3eb3cSopenharmony_ci    if (animationController_) {
11423b3eb3cSopenharmony_ci        if (!animationController_->IsStopped()) {
11523b3eb3cSopenharmony_ci            animationController_->Stop();
11623b3eb3cSopenharmony_ci        }
11723b3eb3cSopenharmony_ci        animationController_->ClearInterpolators();
11823b3eb3cSopenharmony_ci        animationController_->ClearAllListeners();
11923b3eb3cSopenharmony_ci        animationController_.Reset();
12023b3eb3cSopenharmony_ci    }
12123b3eb3cSopenharmony_ci}
12223b3eb3cSopenharmony_ci
12323b3eb3cSopenharmony_civoid AnimatableDimension::OnAnimationCallback(double value)
12423b3eb3cSopenharmony_ci{
12523b3eb3cSopenharmony_ci    SetValue(value);
12623b3eb3cSopenharmony_ci    if (animationCallback_) {
12723b3eb3cSopenharmony_ci        animationCallback_();
12823b3eb3cSopenharmony_ci    }
12923b3eb3cSopenharmony_ci}
13023b3eb3cSopenharmony_ci
13123b3eb3cSopenharmony_civoid AnimatableDimension::MoveTo(double target)
13223b3eb3cSopenharmony_ci{
13323b3eb3cSopenharmony_ci    SetValue(target);
13423b3eb3cSopenharmony_ci    isFirstAssign_ = false;
13523b3eb3cSopenharmony_ci}
13623b3eb3cSopenharmony_ci
13723b3eb3cSopenharmony_civoid AnimatableDimension::ResetAnimatableDimension()
13823b3eb3cSopenharmony_ci{
13923b3eb3cSopenharmony_ci    isFirstAssign_ = true;
14023b3eb3cSopenharmony_ci    animationOption_ = AnimationOption();
14123b3eb3cSopenharmony_ci    animationController_ = nullptr;
14223b3eb3cSopenharmony_ci    context_ = nullptr;
14323b3eb3cSopenharmony_ci    animationCallback_ = nullptr;
14423b3eb3cSopenharmony_ci}
14523b3eb3cSopenharmony_ci} // namespace OHOS::Ace
146