1 /*
2 * Copyright (c) 2022-2025 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 "core/components_ng/pattern/progress/progress_paint_method.h"
17
18 namespace OHOS::Ace::NG {
GetThemeData(int32_t themeScopeId)19 void ProgressPaintMethod::GetThemeData(int32_t themeScopeId)
20 {
21 auto pipeline = PipelineBase::GetCurrentContext();
22 CHECK_NULL_VOID(pipeline);
23 auto progressTheme = pipeline->GetTheme<ProgressTheme>(themeScopeId);
24 CHECK_NULL_VOID(progressTheme);
25 color_ = progressTheme->GetTrackSelectedColor();
26 if (progressType_ == ProgressType::CAPSULE) {
27 color_ = progressTheme->GetCapsuleSelectColor();
28 bgColor_ = progressTheme->GetCapsuleBgColor();
29 } else if (progressType_ == ProgressType::RING) {
30 bgColor_ = progressTheme->GetRingProgressBgColor();
31 } else if (progressType_ == ProgressType::SCALE) {
32 color_ = progressTheme->GetScaleTrackSelectedColor();
33 bgColor_ = progressTheme->GetTrackBgColor();
34 } else {
35 bgColor_ = progressTheme->GetTrackBgColor();
36 }
37 scaleWidth_ = progressTheme->GetScaleWidth().ConvertToPx();
38 scaleCount_ = progressTheme->GetScaleNumber();
39 borderColor_ = progressTheme->GetBorderColor();
40 capsuleBorderWidth_ = progressTheme->GetBorderWidth();
41 ringProgressEndSideColor_ = progressTheme->GetRingProgressEndSideColor();
42 ringProgressBeginSideColor_ = progressTheme->GetRingProgressBeginSideColor();
43 capsuleBgFocusedColor_ = progressTheme->GetCapsuleBgFocusedColor();
44 capsuleSelectFocusedColor_ = progressTheme->GetCapsuleSelectFocusedColor();
45 capsuleInprogressBorderColor_ = progressTheme->GetCapsuleInprogressBorderColor();
46 capsuleInprogressBorderWidth_ = progressTheme->GetCapsuleInprogressBorderWidth();
47 capsuleInprogressBgColor_ = progressTheme->GetCapsuleInprogressBgColor();
48 defaultBorderColor_ = progressTheme->GetBorderColor();
49 defaultBorderWidth_ = progressTheme->GetBorderWidth();
50 }
51
CalculateStrokeWidth(const SizeF & contentSize)52 void ProgressPaintMethod::CalculateStrokeWidth(const SizeF& contentSize)
53 {
54 auto length = std::min(contentSize.Width(), contentSize.Height());
55 constexpr float HALF = 0.5;
56 switch (progressType_) {
57 case ProgressType::LINEAR:
58 strokeWidth_ = std::min(strokeWidth_, length);
59 break;
60 case ProgressType::RING:
61 case ProgressType::SCALE:
62 if (strokeWidth_ >= length * HALF) {
63 strokeWidth_ = length * HALF * HALF;
64 }
65 break;
66 case ProgressType::MOON:
67 case ProgressType::CAPSULE:
68 default:
69 break;
70 }
71 }
72
GenerateRingProgressColor(PaintWrapper * paintWrapper)73 Gradient ProgressPaintMethod::GenerateRingProgressColor(PaintWrapper* paintWrapper)
74 {
75 auto paintProperty = DynamicCast<ProgressPaintProperty>(paintWrapper->GetPaintProperty());
76 if (paintProperty->HasGradientColor()) {
77 return paintProperty->GetGradientColorValue();
78 }
79
80 Gradient gradient;
81 GradientColor gradientColorEnd;
82 GradientColor gradientColorStart;
83 if (paintProperty->HasColor()) {
84 Color color = paintProperty->GetColorValue();
85 gradientColorEnd.SetLinearColor(LinearColor(color));
86 gradientColorStart.SetLinearColor(LinearColor(color));
87 } else {
88 gradientColorEnd.SetLinearColor(LinearColor(ringProgressEndSideColor_));
89 gradientColorStart.SetLinearColor(LinearColor(ringProgressBeginSideColor_));
90 }
91 gradientColorEnd.SetDimension(Dimension(0.0));
92 gradient.AddColor(gradientColorEnd);
93 gradientColorStart.SetDimension(Dimension(1.0));
94 gradient.AddColor(gradientColorStart);
95 return gradient;
96 }
97
UpdateCapsuleProgress(PaintWrapper * paintWrapper)98 void ProgressPaintMethod::UpdateCapsuleProgress(PaintWrapper* paintWrapper)
99 {
100 if (progressType_ != ProgressType::CAPSULE) {
101 return;
102 }
103 CHECK_NULL_VOID(paintWrapper);
104 auto paintProperty = DynamicCast<ProgressPaintProperty>(paintWrapper->GetPaintProperty());
105 CHECK_NULL_VOID(paintProperty);
106
107 bool isFocused = progressModifier_->IsFocused();
108 bool isInprogress = LessNotEqual(0.0f, value_) && LessNotEqual(value_, maxValue_);
109
110 if (!paintProperty->HasBackgroundColor()) {
111 bgColor_ = capsuleInprogressBgColor_;
112 bgColor_ = isFocused ? capsuleBgFocusedColor_ : bgColor_;
113 }
114 bgColor_ = progressModifier_->CalculateHoverPressColor(bgColor_);
115 progressModifier_->SetBackgroundColor(LinearColor(bgColor_));
116
117 if (!paintProperty->HasColor() && isFocused) {
118 color_ = capsuleSelectFocusedColor_;
119 }
120 color_ = progressModifier_->CalculateHoverPressColor(color_);
121 progressModifier_->SetColor(LinearColor(color_));
122
123 if (paintProperty->GetBorderColorValue(defaultBorderColor_) == defaultBorderColor_) {
124 borderColor_ = capsuleInprogressBorderColor_;
125 }
126 borderColor_ = progressModifier_->CalculateHoverPressColor(borderColor_);
127 progressModifier_->SetBorderColor(LinearColor(borderColor_));
128
129 if (paintProperty->GetBorderWidthValue(defaultBorderWidth_) == defaultBorderWidth_ && isInprogress) {
130 progressModifier_->SetBorderWidth(capsuleInprogressBorderWidth_.ConvertToPx());
131 }
132 }
133
SetCapsuleBorderRadius(PaintWrapper * paintWrapper)134 void ProgressPaintMethod::SetCapsuleBorderRadius(PaintWrapper* paintWrapper)
135 {
136 if (progressType_ != ProgressType::CAPSULE) {
137 return;
138 }
139 CHECK_NULL_VOID(progressModifier_);
140 auto paintProperty = DynamicCast<ProgressPaintProperty>(paintWrapper->GetPaintProperty());
141 CHECK_NULL_VOID(paintProperty);
142 const SizeF& contentSize = paintWrapper->GetContentSize();
143 constexpr float HALF = 2.0f;
144 float contentMinHalf = std::min(contentSize.Height(), contentSize.Width()) / HALF;
145 auto borderRadius = static_cast<float>(
146 paintProperty->GetBorderRadiusValue(Dimension(contentMinHalf, DimensionUnit::PX)).ConvertToPx());
147 progressModifier_->SetCapsuleBorderRadius(std::min(contentMinHalf, borderRadius));
148 }
149
GetThemeScopeId(PaintWrapper * paintWrapper) const150 int32_t ProgressPaintMethod::GetThemeScopeId(PaintWrapper* paintWrapper) const
151 {
152 const int32_t defaultValue = 0;
153 CHECK_NULL_RETURN(paintWrapper, defaultValue);
154 auto renderContext = paintWrapper->GetRenderContext();
155 CHECK_NULL_RETURN(renderContext, defaultValue);
156 auto host = renderContext->GetHost();
157 CHECK_NULL_RETURN(host, defaultValue);
158 return host->GetThemeScopeId();
159 }
160 } // namespace OHOS::Ace::NG
161