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_RADIO_RADIO_MODIFIER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_RADIO_RADIO_MODIFIER_H
18 
19 #include <vector>
20 
21 #include "base/geometry/ng/offset_t.h"
22 #include "base/memory/ace_type.h"
23 #include "core/common/container.h"
24 #include "core/components_ng/base/modifier.h"
25 #include "core/components_ng/render/drawing_forward.h"
26 
27 namespace OHOS::Ace::NG {
28 enum class UIStatus {
29     SELECTED = 0,
30     UNSELECTED,
31     FOCUS,
32     ON_TO_OFF,
33     OFF_TO_ON,
34     PART,
35     PART_TO_OFF,
36     OFF_TO_PART,
37     PART_TO_ON,
38     ON_TO_PART,
39 };
40 
41 enum class TouchHoverAnimationType {
42     NONE = 0,
43     HOVER,
44     PRESS,
45     HOVER_TO_PRESS,
46     PRESS_TO_HOVER,
47 };
48 
49 class RadioModifier : public ContentModifier {
50     DECLARE_ACE_TYPE(RadioModifier, ContentModifier);
51 
52 public:
53     RadioModifier();
54     ~RadioModifier() override = default;
55 
onDraw(DrawingContext & context)56     void onDraw(DrawingContext& context) override
57     {
58         if (useContentModifier_->Get()) {
59             return;
60         }
61         RSCanvas& canvas = context.canvas;
62         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
63             PaintIndicator(canvas, isCheck_->Get(), size_->Get(), offset_->Get());
64         } else {
65             PaintRadio(canvas, isCheck_->Get(), size_->Get(), offset_->Get());
66         }
67     }
68 
69     void UpdateAnimatableProperty();
70     void UpdateTotalScaleOnAnimatable(
71         bool isCheck, const AnimationOption& delayOption, const AnimationOption& halfDurationOption);
72     void UpdateIsOnAnimatableProperty(bool isCheck);
73     void UpdateIndicatorAnimation(bool isCheck);
74     void SetBoardColor(LinearColor color, int32_t duratuion, const RefPtr<CubicCurve>& curve);
75     void InitializeParam();
76     void PaintRadio(RSCanvas& canvas, bool checked, const SizeF& contentSize, const OffsetF& contentOffset) const;
77     void PaintIndicator(RSCanvas& canvas, bool checked, const SizeF& contentSize, const OffsetF& contentOffset) const;
78     void PaintUnselectedIndicator(RSCanvas& canvas, float outCircleRadius, float centerX, float centerY) const;
79     void DrawTouchAndHoverBoard(RSCanvas& canvas, const SizeF& contentSize, const OffsetF& contentOffset) const;
80 
SetPointColor(const Color & pointColor)81     void SetPointColor(const Color& pointColor)
82     {
83         pointColor_->Set(LinearColor(pointColor));
84     }
85 
SetactiveColor(const Color & activeColor)86     void SetactiveColor(const Color& activeColor)
87     {
88         activeColor_->Set(LinearColor(activeColor));
89     }
90 
SetinactiveColor(const Color & inactiveColor)91     void SetinactiveColor(const Color& inactiveColor)
92     {
93         inactiveColor_->Set(LinearColor(inactiveColor));
94     }
SetHotZoneOffset(const OffsetF & hotZoneOffset)95     void SetHotZoneOffset(const OffsetF& hotZoneOffset)
96     {
97         hotZoneOffset_ = hotZoneOffset;
98     }
99 
SetHotZoneSize(const SizeF & hotZoneSize)100     void SetHotZoneSize(const SizeF& hotZoneSize)
101     {
102         hotZoneSize_ = hotZoneSize;
103     }
104 
SetEnabled(bool enabled)105     void SetEnabled(bool enabled)
106     {
107         if (enabled_) {
108             enabled_->Set(enabled);
109         }
110     }
111 
SetIsCheck(bool isCheck)112     void SetIsCheck(bool isCheck)
113     {
114         if (isCheck_) {
115             isCheck_->Set(isCheck);
116         }
117     }
118 
GetIsCheck()119     bool GetIsCheck()
120     {
121         if (isCheck_) {
122             return isCheck_->Get();
123         }
124         return false;
125     }
126 
SetIsOnAnimationFlag(bool isOnAnimationFlag)127     void SetIsOnAnimationFlag(bool isOnAnimationFlag)
128     {
129         if (isOnAnimationFlag_) {
130             isOnAnimationFlag_->Set(isOnAnimationFlag);
131         }
132     }
133 
SetTotalScale(const float totalScale)134     void SetTotalScale(const float totalScale)
135     {
136         if (totalScale_) {
137             totalScale_->Set(totalScale);
138         }
139     }
140 
InitOpacityScale(bool isCheck)141     void InitOpacityScale(bool isCheck)
142     {
143         if (opacityScale_) {
144             opacityScale_->Set(isCheck ? 1.0f : 0);
145         }
146         if (borderOpacityScale_) {
147             borderOpacityScale_->Set(isCheck ? 0 : 1.0f);
148         }
149     }
150 
SetPointScale(const float pointScale)151     void SetPointScale(const float pointScale)
152     {
153         if (pointScale_) {
154             pointScale_->Set(pointScale);
155         }
156     }
157 
SetRingPointScale(const float ringPointScale)158     void SetRingPointScale(const float ringPointScale)
159     {
160         if (ringPointScale_) {
161             ringPointScale_->Set(ringPointScale);
162         }
163     }
164 
SetOffset(OffsetF & offset)165     void SetOffset(OffsetF& offset)
166     {
167         if (offset_) {
168             offset_->Set(offset);
169         }
170     }
171 
SetSize(SizeF & size)172     void SetSize(SizeF& size)
173     {
174         if (size_) {
175             size_->Set(size);
176         }
177     }
178 
SetUIStatus(const UIStatus & uiStatus)179     void SetUIStatus(const UIStatus& uiStatus)
180     {
181         if (uiStatus_) {
182             uiStatus_->Set(static_cast<int32_t>(uiStatus));
183         }
184     }
185 
SetTouchHoverAnimationType(const TouchHoverAnimationType touchHoverType)186     void SetTouchHoverAnimationType(const TouchHoverAnimationType touchHoverType)
187     {
188         touchHoverType_ = touchHoverType;
189     }
190 
SetShowHoverEffect(bool showHoverEffect)191     void SetShowHoverEffect(bool showHoverEffect)
192     {
193         showHoverEffect_ = showHoverEffect;
194     }
195 
SetUseContentModifier(bool useContentModifier)196     void SetUseContentModifier(bool useContentModifier)
197     {
198         if (useContentModifier_) {
199             useContentModifier_->Set(useContentModifier);
200         }
201     }
202 
203 private:
204     float shadowWidth_ = 1.5f;
205     float borderWidth_ = 1.5f;
206     Color inactivePointColor_;
207     Color shadowColor_;
208     Color clickEffectColor_;
209     Color hoverColor_;
210     Dimension hotZoneHorizontalPadding_;
211     Dimension defaultPadding_;
212     float hoverDuration_ = 0.0f;
213     float hoverToTouchDuration_ = 0.0f;
214     float touchDuration_ = 0.0f;
215     bool showHoverEffect_ = true;
216     OffsetF hotZoneOffset_;
217     SizeF hotZoneSize_;
218     RefPtr<PropertyBool> isOnAnimationFlag_;
219     RefPtr<PropertyBool> enabled_;
220     RefPtr<PropertyBool> isCheck_;
221     RefPtr<PropertyInt> uiStatus_;
222     RefPtr<PropertyBool> useContentModifier_;
223 
224     RefPtr<AnimatablePropertyColor> pointColor_;
225     RefPtr<AnimatablePropertyColor> activeColor_;
226     RefPtr<AnimatablePropertyColor> inactiveColor_;
227     RefPtr<AnimatablePropertyOffsetF> offset_;
228     RefPtr<AnimatablePropertySizeF> size_;
229     RefPtr<RadioModifier> radioModifier_;
230     RefPtr<AnimatablePropertyFloat> totalScale_;
231     RefPtr<AnimatablePropertyFloat> opacityScale_;
232     RefPtr<AnimatablePropertyFloat> borderOpacityScale_;
233     RefPtr<AnimatablePropertyFloat> pointScale_;
234     RefPtr<AnimatablePropertyFloat> ringPointScale_;
235     RefPtr<AnimatablePropertyColor> animateTouchHoverColor_;
236     TouchHoverAnimationType touchHoverType_ = TouchHoverAnimationType::NONE;
237 
238     ACE_DISALLOW_COPY_AND_MOVE(RadioModifier);
239 };
240 } // namespace OHOS::Ace::NG
241 
242 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_RADIO_RADIO_MODIFIER_H
243