1/*
2 * Copyright (c) 2023 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 "animation_curve.h"
17
18#include "devicestatus_define.h"
19
20#undef LOG_TAG
21#define LOG_TAG "AnimationCurve"
22
23constexpr int32_t CUBIC_PARAM_LIMIT { 4 };
24constexpr int32_t SPRING_PARAM_LIMIT { 4 };
25constexpr int32_t INTERPOLATING_SPRING_PARAM_LIMIT { 4 };
26constexpr int32_t RESPONSE_SPRING_PARAM_LIMIT { 3 };
27constexpr int32_t STEPS_PARAM_LIMIT { 2 };
28
29constexpr int32_t ARG_0 { 0 };
30constexpr int32_t ARG_1 { 1 };
31constexpr int32_t ARG_2 { 2 };
32constexpr int32_t ARG_3 { 3 };
33
34namespace OHOS {
35namespace Msdp {
36namespace DeviceStatus {
37namespace {
38static const RosenCurveType EASE_CURVE = Rosen::RSAnimationTimingCurve::EASE;
39} // namespace
40
41std::unordered_map<std::string, RosenCurveType> AnimationCurve::specialCurveMap_ = {
42    { "ease", Rosen::RSAnimationTimingCurve::EASE },
43    { "ease-in", Rosen::RSAnimationTimingCurve::EASE_IN },
44    { "ease-out", Rosen::RSAnimationTimingCurve::EASE_OUT },
45    { "ease-in-out", Rosen::RSAnimationTimingCurve::EASE_IN_OUT },
46    { "linear", Rosen::RSAnimationTimingCurve::LINEAR }
47};
48
49std::unordered_map<std::string, AnimationCurve::CurveCreator> AnimationCurve::curveMap_ = {
50    { "cubic-bezier", [](const std::vector<float> &curve) {
51        return AnimationCurve::CreateCubicCurve(curve);
52    } },
53    { "spring", [](const std::vector<float> &curve) {
54        return AnimationCurve::CreateSpringCurve(curve);
55    } },
56    { "interpolating-spring", [](const std::vector<float> &curve) {
57        return AnimationCurve::CreateInterpolatingSpring(curve);
58    } },
59    { "responsive-spring-motion", [](const std::vector<float> &curve) {
60        return AnimationCurve::CreateResponseSpring(curve);
61    } },
62    { "steps", [](const std::vector<float> &curve) {
63        return AnimationCurve::CreateStepsCurve(curve);
64    } }
65};
66
67RosenCurveType AnimationCurve::CreateCurve(const std::string &curveName, const std::vector<float> &curve)
68{
69    if (specialCurveMap_.find(curveName) != specialCurveMap_.end()) {
70        return specialCurveMap_[curveName];
71    }
72    if (curveMap_.find(curveName) == curveMap_.end() || curveMap_[curveName] == nullptr) {
73        FI_HILOGE("Unknow curve type, use EASE");
74        return EASE_CURVE;
75    }
76    return curveMap_[curveName](curve);
77}
78
79RosenCurveType AnimationCurve::CreateCubicCurve(const std::vector<float> &curve)
80{
81    if (curve.size() != CUBIC_PARAM_LIMIT) {
82        FI_HILOGE("Invalid parameter, use EASE");
83        return EASE_CURVE;
84    }
85    return RosenCurveType::CreateCubicCurve(curve[ARG_0], curve[ARG_1], curve[ARG_2], curve[ARG_3]);
86}
87
88RosenCurveType AnimationCurve::CreateSpringCurve(const std::vector<float> &curve)
89{
90    if (curve.size() != SPRING_PARAM_LIMIT) {
91        FI_HILOGE("Invalid parameter, use EASE");
92        return EASE_CURVE;
93    }
94    return RosenCurveType::CreateSpringCurve(curve[ARG_0], curve[ARG_1], curve[ARG_2], curve[ARG_3]);
95}
96
97RosenCurveType AnimationCurve::CreateInterpolatingSpring(const std::vector<float> &curve)
98{
99    if (curve.size() != INTERPOLATING_SPRING_PARAM_LIMIT) {
100        FI_HILOGE("Invalid parameter, use EASE");
101        return EASE_CURVE;
102    }
103    return RosenCurveType::CreateInterpolatingSpring(curve[ARG_0], curve[ARG_1], curve[ARG_2], curve[ARG_3]);
104}
105
106RosenCurveType AnimationCurve::CreateResponseSpring(const std::vector<float> &curve)
107{
108    if (curve.size() != RESPONSE_SPRING_PARAM_LIMIT) {
109        FI_HILOGE("Invalid parameter, use EASE");
110        return EASE_CURVE;
111    }
112    return RosenCurveType::CreateSpring(curve[ARG_0], curve[ARG_1], curve[ARG_2]);
113}
114
115RosenCurveType AnimationCurve::CreateStepsCurve(const std::vector<float> &curve)
116{
117    if (curve.size() != STEPS_PARAM_LIMIT) {
118        FI_HILOGE("Invalid parameter, use EASE");
119        return EASE_CURVE;
120    }
121    auto steps = static_cast<int32_t>(curve[ARG_0]);
122    auto stepPosition = static_cast<OHOS::Rosen::StepsCurvePosition>(static_cast<int32_t>(curve[ARG_1]));
123    return RosenCurveType::CreateStepsCurve(steps, stepPosition);
124}
125
126} // namespace DeviceStatus
127} // namespace Msdp
128} // namespace OHOS
129