• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWITCH_SWITCH_MODIFIER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWITCH_SWITCH_MODIFIER_H
18 
19 #include <algorithm>
20 #include <vector>
21 
22 #include "base/geometry/ng/offset_t.h"
23 #include "core/animation/spring_curve.h"
24 #include "core/common/container.h"
25 #include "core/components_ng/base/modifier.h"
26 #include "core/components_ng/pattern/radio/radio_modifier.h"
27 #include "core/components_ng/pattern/toggle/switch_paint_property.h"
28 #include "core/components_ng/property/property.h"
29 #include "core/components_ng/render/animation_utils.h"
30 #include "core/components_ng/render/canvas_image.h"
31 #include "core/components_ng/render/drawing_forward.h"
32 #include "core/components_ng/render/paint_wrapper.h"
33 namespace OHOS::Ace::NG {
34 class SwitchModifier : public ContentModifier {
35     DECLARE_ACE_TYPE(SwitchModifier, ContentModifier);
36 
37 public:
38     SwitchModifier(bool isSelect, const Color& boardColor, float dragOffsetX);
39     ~SwitchModifier() override = default;
40 
onDraw(DrawingContext & context)41     void onDraw(DrawingContext& context) override
42     {
43         RSCanvas& canvas = context.canvas;
44         PaintSwitch(canvas, offset_->Get(), size_->Get());
45     }
46 
UpdateAnimatableProperty()47     void UpdateAnimatableProperty()
48     {
49         switch (touchHoverType_) {
50             case TouchHoverAnimationType::HOVER:
51                 SetBoardColor(LinearColor(hoverColor_), hoverDuration_, Curves::FRICTION);
52                 break;
53             case TouchHoverAnimationType::PRESS_TO_HOVER:
54                 SetBoardColor(LinearColor(hoverColor_), hoverToTouchDuration_, Curves::SHARP);
55                 break;
56             case TouchHoverAnimationType::NONE:
57                 SetBoardColor(LinearColor(hoverColor_.BlendOpacity(0)), hoverDuration_, Curves::FRICTION);
58                 break;
59             case TouchHoverAnimationType::HOVER_TO_PRESS:
60                 SetBoardColor(LinearColor(clickEffectColor_), hoverToTouchDuration_, Curves::SHARP);
61                 break;
62             case TouchHoverAnimationType::PRESS:
63                 SetBoardColor(LinearColor(clickEffectColor_), hoverDuration_, Curves::FRICTION);
64                 break;
65             default:
66                 break;
67         }
68         // Animation is not displayed when created for the first time.
69         if (isFirstCreated_) {
70             animatableBoardColor_->Set(isSelect_->Get() ? LinearColor(userActiveColor_) : LinearColor(inactiveColor_));
71             pointOffset_->Set(isSelect_->Get() ? size_->Get().Width() - size_->Get().Height() : 0.0f);
72             isFirstCreated_ = false;
73         }
74         AnimationOption colorOption = AnimationOption();
75         colorOption.SetDuration(colorAnimationDuration_);
76         colorOption.SetCurve(Curves::FAST_OUT_SLOW_IN);
77         AnimationUtils::Animate(colorOption, [&]() {
78             animatableBoardColor_->Set(isSelect_->Get() ? LinearColor(userActiveColor_) : LinearColor(inactiveColor_));
79         });
80 
81         AnimationOption pointOption = AnimationOption();
82         pointOption.SetDuration(pointAnimationDuration_);
83         pointOption.SetCurve(Curves::FAST_OUT_SLOW_IN);
84         float newPointOffset = 0.0f;
85         if (!isDragEvent_) {
86             newPointOffset = isSelect_->Get() ? size_->Get().Width() - size_->Get().Height() : 0.0f;
87         } else {
88             newPointOffset = std::clamp(
89                 dragOffsetX_->Get() - offset_->Get().GetX(), 0.0f, size_->Get().Width() - size_->Get().Height());
90         }
91         AnimationUtils::Animate(pointOption, [&]() { pointOffset_->Set(newPointOffset); });
92     }
93 
SetBoardColor(LinearColor color,int32_t duratuion,const RefPtr<CubicCurve> & curve)94     void SetBoardColor(LinearColor color, int32_t duratuion, const RefPtr<CubicCurve>& curve)
95     {
96         if (animateTouchHoverColor_) {
97             AnimationOption option = AnimationOption();
98             option.SetDuration(duratuion);
99             option.SetCurve(curve);
100             AnimationUtils::Animate(option, [&]() { animateTouchHoverColor_->Set(color); });
101         }
102     }
103 
104     void InitializeParam();
105     void PaintSwitch(RSCanvas& canvas, const OffsetF& contentOffset, const SizeF& contentSize);
106     void DrawTouchAndHoverBoard(RSCanvas& canvas, const OffsetF& offset) const;
107     float GetSwitchWidth(const SizeF& contentSize) const;
108 
SetUserActiveColor(const Color & color)109     void SetUserActiveColor(const Color& color)
110     {
111         userActiveColor_ = color;
112         animatableBoardColor_->Set(isSelect_->Get() ? LinearColor(userActiveColor_) : LinearColor(inactiveColor_));
113     }
114 
SetPointColor(const Color & color)115     void SetPointColor(const Color& color)
116     {
117         animatePointColor_->Set(LinearColor(color));
118     }
119 
SetEnabled(bool enabled)120     void SetEnabled(bool enabled)
121     {
122         if (enabled_) {
123             enabled_->Set(enabled);
124         }
125     }
126 
SetIsHover(bool isHover)127     void SetIsHover(bool isHover)
128     {
129         if (isHover_) {
130             isHover_->Set(isHover);
131         }
132     }
133 
SetIsSelect(bool isSelect)134     void SetIsSelect(bool isSelect)
135     {
136         if (isSelect_) {
137             isSelect_->Set(isSelect);
138         }
139     }
140 
SetHotZoneOffset(OffsetF & hotZoneOffset)141     void SetHotZoneOffset(OffsetF& hotZoneOffset)
142     {
143         hotZoneOffset_ = hotZoneOffset;
144     }
145 
SetHotZoneSize(SizeF & hotZoneSize)146     void SetHotZoneSize(SizeF& hotZoneSize)
147     {
148         hotZoneSize_ = hotZoneSize;
149     }
150 
SetOffset(OffsetF & offset)151     void SetOffset(OffsetF& offset)
152     {
153         if (offset_) {
154             offset_->Set(offset);
155         }
156     }
157 
SetSize(SizeF & size)158     void SetSize(SizeF& size)
159     {
160         if (size_) {
161             size_->Set(size);
162         }
163     }
164 
SetDragOffsetX(float dragOffsetX)165     void SetDragOffsetX(float dragOffsetX)
166     {
167         if (dragOffsetX_) {
168             dragOffsetX_->Set(dragOffsetX);
169         }
170     }
171 
SetPointOffset(float pointOffset)172     void SetPointOffset(float pointOffset)
173     {
174         if (pointOffset_) {
175             pointOffset_->Set(pointOffset);
176         }
177     }
178 
SetTouchHoverAnimationType(const TouchHoverAnimationType touchHoverType)179     void SetTouchHoverAnimationType(const TouchHoverAnimationType touchHoverType)
180     {
181         touchHoverType_ = touchHoverType;
182     }
183 
SetIsDragEvent(bool isDragEvent)184     void SetIsDragEvent(bool isDragEvent)
185     {
186         isDragEvent_ = isDragEvent;
187     }
188 
189 private:
190     float actualWidth_ = 0.0f;
191     float actualHeight_ = 0.0f;
192     float pointRadius_ = 0.0f;
193     const Dimension radiusGap_ = 2.0_vp;
194     Color clickEffectColor_;
195     Color hoverColor_;
196     Color activeColor_;
197     Color inactiveColor_;
198     Color userActiveColor_;
199     Dimension hoverRadius_ = 8.0_vp;
200     float hoverDuration_ = 0.0f;
201     float hoverToTouchDuration_ = 0.0f;
202     float touchDuration_ = 0.0f;
203     float colorAnimationDuration_ = 0.0f;
204     float pointAnimationDuration_ = 0.0f;
205     bool isDragEvent_ = false;
206     bool isFirstCreated_ = true;
207 
208     OffsetF hotZoneOffset_;
209     SizeF hotZoneSize_;
210     TouchHoverAnimationType touchHoverType_ = TouchHoverAnimationType::NONE;
211 
212     RefPtr<AnimatablePropertyColor> animatableBoardColor_;
213     RefPtr<AnimatablePropertyColor> animateTouchHoverColor_;
214     RefPtr<AnimatablePropertyColor> animatePointColor_;
215     RefPtr<AnimatablePropertyFloat> pointOffset_;
216     RefPtr<PropertyFloat> dragOffsetX_;
217     RefPtr<PropertyBool> isSelect_;
218     RefPtr<PropertyBool> isHover_;
219     RefPtr<AnimatablePropertyOffsetF> offset_;
220     RefPtr<AnimatablePropertySizeF> size_;
221     RefPtr<PropertyBool> enabled_;
222 
223     ACE_DISALLOW_COPY_AND_MOVE(SwitchModifier);
224 };
225 } // namespace OHOS::Ace::NG
226 
227 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWITCH_SWITCH_MODIFIER_H
228