• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #include "core/components_ng/pattern/arc_scroll/inner/arc_scroll_bar_overlay_modifier.h"
16 #include "base/geometry/ng/offset_t.h"
17 #include "base/utils/utils.h"
18 #include "core/components_ng/base/modifier.h"
19 #include "core/components_ng/render/drawing.h"
20 #include "core/components_ng/render/drawing_prop_convertor.h"
21 #include "core/pipeline/pipeline_base.h"
22 
23 namespace OHOS::Ace::NG {
24 namespace {
25 constexpr double FULL_ALPHA = 255.0;
26 constexpr int32_t BAR_GROW_DURATION = 150;       // 150ms, scroll bar width expands from 4dp to 8dp
27 constexpr int32_t BAR_SHRINK_DURATION = 250;     // 250ms, scroll bar width shrinks from 8dp to 4dp
28 } // namespace
29 
ArcScrollBarOverlayModifier(const OffsetF & barOffset,const SizeF & barSize)30 ArcScrollBarOverlayModifier::ArcScrollBarOverlayModifier(
31     const OffsetF& barOffset, const SizeF& barSize) : ScrollBarOverlayModifier(barOffset, barSize)
32 {
33     strokeWidth_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0);
34     AttachProperty(strokeWidth_);
35     curveRadius_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0);
36     AttachProperty(curveRadius_);
37     curveCenter_ = AceType::MakeRefPtr<AnimatablePropertyOffsetF>(OffsetF());
38     AttachProperty(curveCenter_);
39     startAngle_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0);
40     AttachProperty(startAngle_);
41     sweepAngle_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0);
42     AttachProperty(sweepAngle_);
43     backgroundStartAngle_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0);
44     AttachProperty(backgroundStartAngle_);
45     backgroundSweepAngle_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0);
46     AttachProperty(backgroundSweepAngle_);
47     backgroundStrokeWidth_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0);
48     AttachProperty(backgroundStrokeWidth_);
49     backgroundCurveRadius_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0);
50     AttachProperty(backgroundCurveRadius_);
51     backgroundBarColor_ = AceType::MakeRefPtr<PropertyColor>(Color());
52     AttachProperty(backgroundBarColor_);
53 }
54 
StartArcBarAnimation(HoverAnimationType hoverAnimationType,OpacityAnimationType opacityAnimationType,bool needAdaptAnimation,const ArcRound & arcBarRect,const ArcRound & backgroundArcBarRect)55 void ArcScrollBarOverlayModifier::StartArcBarAnimation(HoverAnimationType hoverAnimationType,
56     OpacityAnimationType opacityAnimationType, bool needAdaptAnimation, const ArcRound& arcBarRect,
57     const ArcRound& backgroundArcBarRect)
58 {
59     if (hoverAnimationType == HoverAnimationType::NONE && !needAdaptAnimation) {
60         SetArcRect(arcBarRect);
61         SetBackgroundArcRect(backgroundArcBarRect);
62     } else {
63         StartHoverAnimation(arcBarRect, backgroundArcBarRect, hoverAnimationType);
64     }
65     if (opacityAnimationType != OpacityAnimationType::NONE && GetScrollable()) {
66         StartOpacityAnimation(opacityAnimationType);
67     }
68 }
69 
SetBackgroundArcRect(const ArcRound & backgroundArcBarRect)70 void ArcScrollBarOverlayModifier::SetBackgroundArcRect(const ArcRound& backgroundArcBarRect)
71 {
72     backgroundStrokeWidth_->Set(backgroundArcBarRect.GetWidth());
73     backgroundCurveRadius_->Set(backgroundArcBarRect.GetRadius());
74     backgroundStartAngle_->Set(backgroundArcBarRect.GetStartAngle());
75     backgroundSweepAngle_->Set(backgroundArcBarRect.GetSweepAngle());
76 }
77 
SetArcRect(const ArcRound & arcBarRect)78 void ArcScrollBarOverlayModifier::SetArcRect(const ArcRound& arcBarRect)
79 {
80     strokeWidth_->Set(arcBarRect.GetWidth());
81     curveRadius_->Set(arcBarRect.GetRadius());
82     SetCurveCenter(arcBarRect.GetCenterPoint());
83     startAngle_->Set(arcBarRect.GetStartAngle());
84     sweepAngle_->Set(arcBarRect.GetSweepAngle());
85 }
86 
SetBackgroundBarColor(Color backgroundBarColor)87 void ArcScrollBarOverlayModifier::SetBackgroundBarColor(Color backgroundBarColor)
88 {
89     CHECK_NULL_VOID(backgroundBarColor_);
90     backgroundBarColor_->Set(backgroundBarColor);
91 }
92 
SetCurveCenter(Point curveCenter)93 void ArcScrollBarOverlayModifier::SetCurveCenter(Point curveCenter)
94 {
95     CHECK_NULL_VOID(curveCenter_);
96     float x = curveCenter.GetX();
97     float y = curveCenter.GetY();
98     OffsetF temp(x, y);
99     curveCenter_->Set(temp);
100 }
101 
StartHoverAnimation(const ArcRound & arcBarRect,const ArcRound & backgroundArcBarRect,HoverAnimationType hoverAnimationType)102 void ArcScrollBarOverlayModifier::StartHoverAnimation(const ArcRound& arcBarRect,
103     const ArcRound& backgroundArcBarRect, HoverAnimationType hoverAnimationType)
104 {
105     if (hoverAnimationType == HoverAnimationType::NONE) {
106         SetArcRect(arcBarRect);
107         SetBackgroundArcRect(backgroundArcBarRect);
108         return;
109     }
110     if (hoverAnimationType != GetHoverAnimatingType()) {
111         StopHoverAnimation();
112     }
113 
114     AnimationOption option;
115     option.SetCurve(Curves::SHARP);
116     if (hoverAnimationType == HoverAnimationType::GROW) {
117         option.SetDuration(BAR_GROW_DURATION);
118     } else if (hoverAnimationType == HoverAnimationType::SHRINK) {
119         option.SetDuration(BAR_SHRINK_DURATION);
120     }
121 
122     SetHoverAnimatingType(hoverAnimationType);
123     hoverAnimation_ = AnimationUtils::StartAnimation(
124         option,
125         [&]() {
126             SetArcRect(arcBarRect);
127             SetBackgroundArcRect(backgroundArcBarRect);
128         },
129         [weak = WeakClaim(this)]() {
130             auto modifier = weak.Upgrade();
131             CHECK_NULL_VOID(modifier);
132             modifier->SetHoverAnimatingType(HoverAnimationType::NONE);
133         });
134 }
135 
onDraw(DrawingContext & drawingContext)136 void ArcScrollBarOverlayModifier::onDraw(DrawingContext& drawingContext)
137 {
138     CHECK_NULL_VOID(strokeWidth_);
139     CHECK_NULL_VOID(curveCenter_);
140     CHECK_NULL_VOID(startAngle_);
141     CHECK_NULL_VOID(sweepAngle_);
142     CHECK_NULL_VOID(curveRadius_);
143 
144     CHECK_NULL_VOID(backgroundStartAngle_);
145     CHECK_NULL_VOID(backgroundSweepAngle_);
146     CHECK_NULL_VOID(backgroundStrokeWidth_);
147     CHECK_NULL_VOID(backgroundCurveRadius_);
148     CHECK_NULL_VOID(backgroundBarColor_);
149     DrawBackgroundArc(drawingContext);
150     DrawArc(drawingContext);
151 }
152 
DrawArc(DrawingContext & context)153 void ArcScrollBarOverlayModifier::DrawArc(DrawingContext& context)
154 {
155     auto pipeline = PipelineBase::GetCurrentContext();
156     CHECK_NULL_VOID(pipeline);
157     auto strokeWidth = strokeWidth_->Get();
158     auto& canvas = context.canvas;
159     RSPen pen;
160     pen.SetAntiAlias(true);
161     pen.SetWidth(strokeWidth);
162     pen.SetCapStyle(ToRSCapStyle(LineCap::ROUND));
163     auto barOpacity = GetOpacity() / FULL_ALPHA;
164     pen.SetColor(ToRSColor(GetBarColor()->Get().BlendOpacity(barOpacity)));
165     canvas.AttachPen(pen);
166     auto center = curveCenter_->Get();
167     auto radius = curveRadius_->Get();
168     auto startAngle = startAngle_->Get();
169     auto sweepAngle = sweepAngle_->Get();
170     canvas.DrawArc(
171         { center.GetX() - radius, center.GetY() - radius, center.GetX() + radius, center.GetY() + radius },
172         startAngle, sweepAngle);
173     canvas.DetachPen();
174 }
175 
DrawBackgroundArc(DrawingContext & context)176 void ArcScrollBarOverlayModifier::DrawBackgroundArc(DrawingContext& context)
177 {
178     CHECK_NULL_VOID(backgroundBarColor_);
179     auto pipeline = PipelineBase::GetCurrentContext();
180     CHECK_NULL_VOID(pipeline);
181     auto& canvas = context.canvas;
182     auto strokeWidth = backgroundStrokeWidth_->Get();
183     RSPen pen;
184     pen.SetAntiAlias(true);
185     pen.SetWidth(strokeWidth);
186     pen.SetCapStyle(ToRSCapStyle(LineCap::ROUND));
187     auto barOpacity = GetOpacity() / FULL_ALPHA;
188     pen.SetColor(ToRSColor(backgroundBarColor_->Get().BlendOpacity(barOpacity)));
189 
190     canvas.AttachPen(pen);
191     auto center = curveCenter_->Get();
192     auto radius = backgroundCurveRadius_->Get();
193     auto startAngle = backgroundStartAngle_->Get();
194     auto sweepAngle = backgroundSweepAngle_->Get();
195 
196     canvas.DrawArc(
197         { center.GetX() - radius, center.GetY() - radius, center.GetX() + radius, center.GetY() + radius },
198         startAngle, sweepAngle);
199     canvas.DetachPen();
200 }
201 } // namespace OHOS::Ace::NG