1 /*
2  * Copyright (c) 2022 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_PATTERN_PROGRESS_PROGRESS_PAINT_METHOD_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_PROGRESS_PROGRESS_PAINT_METHOD_H
18 
19 #include <optional>
20 
21 #include "base/geometry/dimension.h"
22 #include "base/geometry/ng/offset_t.h"
23 #include "base/geometry/ng/size_t.h"
24 #include "base/utils/utils.h"
25 #include "core/common/container.h"
26 #include "core/components/common/properties/color.h"
27 #include "core/components/progress/progress_theme.h"
28 #include "core/components_ng/pattern/progress/progress_date.h"
29 #include "core/components_ng/pattern/progress/progress_modifier.h"
30 #include "core/components_ng/pattern/progress/progress_paint_property.h"
31 #include "core/components_ng/render/drawing.h"
32 #include "core/components_ng/render/drawing_prop_convertor.h"
33 #include "core/components_ng/render/node_paint_method.h"
34 
35 namespace OHOS::Ace::NG {
36 constexpr float DEFAULT_BORDER_WIDTH = 1.0f;
37 
38 class ACE_EXPORT ProgressPaintMethod : public NodePaintMethod {
DECLARE_ACE_TYPE(ProgressPaintMethod,NodePaintMethod)39     DECLARE_ACE_TYPE(ProgressPaintMethod, NodePaintMethod)
40 public:
41     explicit ProgressPaintMethod(
42         ProgressType progressType, float strokeWidth, const RefPtr<ProgressModifier>& progressModifier)
43         : strokeWidth_(strokeWidth), progressType_(progressType), progressModifier_(progressModifier)
44     {
45         progressModifier_->SetProgressType(progressType_);
46     }
47     ~ProgressPaintMethod() override = default;
48 
GetContentModifier(PaintWrapper * paintWrapper)49     RefPtr<Modifier> GetContentModifier(PaintWrapper* paintWrapper) override
50     {
51         CHECK_NULL_RETURN(progressModifier_, nullptr);
52         return progressModifier_;
53     }
54 
UpdateContentModifier(PaintWrapper * paintWrapper)55     void UpdateContentModifier(PaintWrapper* paintWrapper) override
56     {
57         CHECK_NULL_VOID(progressModifier_);
58         GetThemeData();
59         auto paintProperty = DynamicCast<ProgressPaintProperty>(paintWrapper->GetPaintProperty());
60         CHECK_NULL_VOID(paintProperty);
61         auto isSensitive = paintProperty->GetIsSensitive().value_or(false);
62         color_ = paintProperty->GetColor().value_or(color_);
63         bgColor_ = paintProperty->GetBackgroundColor().value_or(bgColor_);
64         borderColor_ = paintProperty->GetBorderColor().value_or(borderColor_);
65         maxValue_ = paintProperty->GetMaxValue().value_or(maxValue_);
66         value_ = paintProperty->GetValue().value_or(value_);
67         scaleCount_ = paintProperty->GetScaleCount().value_or(scaleCount_);
68         scaleWidth_ = paintProperty->GetScaleWidth().value_or(Dimension(scaleWidth_)).ConvertToPx();
69         capsuleBorderWidth_ = paintProperty->GetBorderWidth().value_or(capsuleBorderWidth_);
70         sweepEffect_ = paintProperty->GetEnableScanEffect().value_or(false);
71         ringSweepEffect_ = paintProperty->GetEnableRingScanEffect().value_or(false);
72         linearSweepEffect_ = paintProperty->GetEnableLinearScanEffect().value_or(false);
73         bool paintShadow = paintProperty->GetPaintShadow().value_or(false);
74         ProgressStatus progressStatus = paintProperty->GetProgressStatus().value_or(ProgressStatus::PROGRESSING);
75         progressModifier_->SetSmoothEffect(paintProperty->GetEnableSmoothEffect().value_or(true));
76         progressModifier_->SetContentOffset(paintWrapper->GetContentOffset());
77         progressModifier_->SetContentSize(paintWrapper->GetContentSize());
78         CalculateStrokeWidth(paintWrapper->GetContentSize());
79         progressModifier_->SetSweepEffect(sweepEffect_);
80         progressModifier_->SetRingSweepEffect(ringSweepEffect_);
81         progressModifier_->SetLinearSweepEffect(linearSweepEffect_);
82         progressModifier_->SetStrokeWidth(strokeWidth_);
83         progressModifier_->SetBorderWidth(capsuleBorderWidth_.ConvertToPx());
84         progressModifier_->SetColor(LinearColor(color_));
85         progressModifier_->SetBackgroundColor(LinearColor(bgColor_));
86         progressModifier_->SetBorderColor(LinearColor(borderColor_));
87         progressModifier_->SetProgressType(progressType_);
88         progressModifier_->SetProgressStatus(progressStatus);
89         progressModifier_->SetScaleWidth(scaleWidth_);
90         progressModifier_->SetScaleCount(scaleCount_);
91         auto ringProgressColor = GenerateRingProgressColor(paintWrapper);
92         progressModifier_->SetRingProgressColor(ringProgressColor);
93         progressModifier_->SetPaintShadow(paintShadow);
94         isItalic_ = paintProperty->GetItalicFontStyle() != Ace::FontStyle::NORMAL;
95         progressModifier_->SetIsItalic(isItalic_);
96         progressModifier_->SetMaxValue(maxValue_);
97         progressModifier_->SetValue(isSensitive ? 0.0 : value_);
98         auto strokeRadius = static_cast<float>(
99             paintProperty->GetStrokeRadiusValue(Dimension(strokeWidth_ / 2.0f, DimensionUnit::VP)).ConvertToPx());
100         strokeRadius = std::min(strokeWidth_ / 2, strokeRadius);
101         progressModifier_->SetStrokeRadius(strokeRadius);
102     }
103 
104     void GetThemeData();
105     void CalculateStrokeWidth(const SizeF& contentSize);
106 
107 private:
108     Gradient GenerateRingProgressColor(PaintWrapper* paintWrapper);
109 
110     Color color_ = Color::BLUE;
111     Color bgColor_ = Color::GRAY;
112     Color borderColor_ = Color::GRAY;
113     float strokeWidth_ = 0.0f;
114     float scaleWidth_ = 0.0f;
115     int32_t scaleCount_ = 0;
116     float maxValue_ = 100.0f;
117     float value_ = 0.0f;
118     Dimension capsuleBorderWidth_ = Dimension(DEFAULT_BORDER_WIDTH, DimensionUnit::VP);
119     Color ringProgressEndSideColor_ = Color::BLUE;
120     Color ringProgressBeginSideColor_ = Color::BLUE;
121 
122     ProgressType progressType_ = ProgressType::LINEAR;
123     RefPtr<ProgressModifier> progressModifier_;
124     bool sweepEffect_ = false;
125     bool ringSweepEffect_ = false;
126     bool linearSweepEffect_ = false;
127     bool isItalic_ = false;
128 
129     ACE_DISALLOW_COPY_AND_MOVE(ProgressPaintMethod);
130 };
131 
132 } // namespace OHOS::Ace::NG
133 
134 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_PROGRESS_PROGRESS_PAINT_METHOD_H
135