• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "core/components_ng/pattern/checkbox/checkbox_paint_method.h"
16 
17 #include <optional>
18 
19 #include "base/geometry/ng/offset_t.h"
20 #include "base/geometry/ng/rect_t.h"
21 #include "base/geometry/rect.h"
22 #include "base/geometry/rrect.h"
23 #include "base/utils/utils.h"
24 #include "core/components/checkable/checkable_theme.h"
25 #include "core/components/common/properties/alignment.h"
26 #include "core/components/common/properties/color.h"
27 #include "core/components/theme/theme_manager.h"
28 #include "core/components_ng/pattern/checkbox/checkbox_paint_property.h"
29 #include "core/components_ng/pattern/checkbox/checkbox_pattern.h"
30 #include "core/components_ng/render/drawing.h"
31 #include "core/components_ng/render/drawing_prop_convertor.h"
32 
33 namespace OHOS::Ace::NG {
34 namespace {
35 constexpr uint8_t ENABLED_ALPHA = 255;
36 constexpr uint8_t DISABLED_ALPHA = 102;
37 constexpr float CHECK_MARK_START_X_POSITION = 0.25f;
38 constexpr float CHECK_MARK_START_Y_POSITION = 0.49f;
39 constexpr float CHECK_MARK_MIDDLE_X_POSITION = 0.44f;
40 constexpr float CHECK_MARK_MIDDLE_Y_POSITION = 0.68f;
41 constexpr float CHECK_MARK_END_X_POSITION = 0.76f;
42 constexpr float CHECK_MARK_END_Y_POSITION = 0.33f;
43 } // namespace
44 
CheckBoxModifier(bool isSelect,const Color & boardColor,const Color & checkColor,const Color & borderColor,const Color & shadowColor)45 CheckBoxModifier::CheckBoxModifier(
46     bool isSelect, const Color& boardColor, const Color& checkColor, const Color& borderColor, const Color& shadowColor)
47 {
48     animatableBoardColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(boardColor));
49     animatableCheckColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(checkColor));
50     animatableBorderColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(borderColor));
51     animatableShadowColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(shadowColor));
52 
53     animateHoverColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(Color::TRANSPARENT));
54     isSelect_ = AceType::MakeRefPtr<PropertyBool>(isSelect);
55     isHover_ = AceType::MakeRefPtr<PropertyBool>(false);
56     offset_ = AceType::MakeRefPtr<PropertyOffsetF>(OffsetF());
57     size_ = AceType::MakeRefPtr<PropertySizeF>(SizeF());
58     enabled_ = AceType::MakeRefPtr<PropertyBool>(true);
59 
60     AttachProperty(animatableBoardColor_);
61     AttachProperty(animatableCheckColor_);
62     AttachProperty(animatableBorderColor_);
63     AttachProperty(animatableShadowColor_);
64     AttachProperty(animateHoverColor_);
65     AttachProperty(isSelect_);
66     AttachProperty(isHover_);
67     AttachProperty(offset_);
68     AttachProperty(size_);
69     AttachProperty(enabled_);
70 }
71 
InitializeParam()72 void CheckBoxModifier::InitializeParam()
73 {
74     auto pipeline = PipelineBase::GetCurrentContext();
75     CHECK_NULL_VOID(pipeline);
76     auto checkBoxTheme = pipeline->GetTheme<CheckboxTheme>();
77     CHECK_NULL_VOID(checkBoxTheme);
78     borderWidth_ = checkBoxTheme->GetBorderWidth().ConvertToPx();
79     borderRadius_ = checkBoxTheme->GetBorderRadius().ConvertToPx();
80     checkStroke_ = checkBoxTheme->GetCheckStroke().ConvertToPx();
81     pointColor_ = checkBoxTheme->GetPointColor();
82     activeColor_ = checkBoxTheme->GetActiveColor();
83     inactiveColor_ = checkBoxTheme->GetInactiveColor();
84     inactivePointColor_ = checkBoxTheme->GetInactivePointColor();
85     shadowColor_ = checkBoxTheme->GetShadowColor();
86     clickEffectColor_ = checkBoxTheme->GetClickEffectColor();
87     hoverColor_ = checkBoxTheme->GetHoverColor();
88     hoverRadius_ = checkBoxTheme->GetHoverRadius();
89     hotZoneHorizontalPadding_ = checkBoxTheme->GetHotZoneHorizontalPadding();
90     hotZoneVerticalPadding_ = checkBoxTheme->GetHotZoneVerticalPadding();
91     shadowWidth_ = checkBoxTheme->GetShadowWidth();
92     userActiveColor_ = activeColor_;
93     hoverDuration_ = checkBoxTheme->GetHoverDuration();
94     hoverToTouchDuration_ = checkBoxTheme->GetHoverToTouchDuration();
95     touchDuration_ = checkBoxTheme->GetTouchDuration();
96     colorAnimationDuration_ = checkBoxTheme->GetColorAnimationDuration();
97 }
98 
PaintCheckBox(RSCanvas & canvas,const OffsetF & paintOffset,const SizeF & contentSize) const99 void CheckBoxModifier::PaintCheckBox(RSCanvas& canvas, const OffsetF& paintOffset, const SizeF& contentSize) const
100 {
101     RSPen pen;
102     RSBrush brush;
103     pen.SetWidth(borderWidth_);
104     pen.SetAntiAlias(true);
105     DrawHoverBoard(canvas, contentSize, paintOffset);
106     RSPen shadowPen = RSPen(pen);
107     brush.SetColor(ToRSColor(animatableBoardColor_->Get()));
108     brush.SetAntiAlias(true);
109     if (!enabled_->Get()) {
110         brush.SetColor(
111             ToRSColor(animatableBoardColor_->Get().BlendOpacity(static_cast<float>(DISABLED_ALPHA) / ENABLED_ALPHA)));
112     }
113     DrawBackboard(canvas, paintOffset, brush, contentSize);
114     pen.SetColor(ToRSColor(animatableBorderColor_->Get()));
115     if (!enabled_->Get()) {
116         pen.SetColor(
117             ToRSColor(animatableBorderColor_->Get().BlendOpacity(static_cast<float>(DISABLED_ALPHA) / ENABLED_ALPHA)));
118     }
119     DrawBorder(canvas, paintOffset, pen, contentSize);
120     pen.SetColor(ToRSColor(animatableCheckColor_->Get()));
121     if (!enabled_->Get()) {
122         pen.SetColor(
123             ToRSColor(animatableCheckColor_->Get().BlendOpacity(static_cast<float>(DISABLED_ALPHA) / ENABLED_ALPHA)));
124     }
125     shadowPen.SetColor(ToRSColor(animatableShadowColor_->Get()));
126     DrawCheck(canvas, paintOffset, pen, shadowPen, contentSize);
127 }
128 
DrawHoverBoard(RSCanvas & canvas,const SizeF & size,const OffsetF & offset) const129 void CheckBoxModifier::DrawHoverBoard(RSCanvas& canvas, const SizeF& size, const OffsetF& offset) const
130 {
131     RSBrush brush;
132     brush.SetColor(ToRSColor(animateHoverColor_->Get()));
133     brush.SetAntiAlias(true);
134     float originX = offset.GetX() - hotZoneHorizontalPadding_.ConvertToPx();
135     float originY = offset.GetY() - hotZoneVerticalPadding_.ConvertToPx();
136     float endX = size.Width() + originX + 2 * hotZoneHorizontalPadding_.ConvertToPx();
137     float endY = size.Height() + originY + 2 * hotZoneVerticalPadding_.ConvertToPx();
138     auto rrect = RSRoundRect({ originX, originY, endX, endY }, hoverRadius_.ConvertToPx(), hoverRadius_.ConvertToPx());
139     canvas.AttachBrush(brush);
140     canvas.DrawRoundRect(rrect);
141 }
142 
DrawBorder(RSCanvas & canvas,const OffsetF & origin,RSPen & pen,const SizeF & paintSize) const143 void CheckBoxModifier::DrawBorder(RSCanvas& canvas, const OffsetF& origin, RSPen& pen, const SizeF& paintSize) const
144 {
145     float originX = origin.GetX() + borderWidth_ / 2.0;
146     float originY = origin.GetY() + borderWidth_ / 2.0;
147     float endX = originX + paintSize.Width() - borderWidth_;
148     float endY = originY + paintSize.Height() - borderWidth_;
149     auto rrect = RSRoundRect({ originX, originY, endX, endY }, borderRadius_, borderRadius_);
150     canvas.AttachPen(pen);
151     canvas.DrawRoundRect(rrect);
152 }
153 
DrawBackboard(RSCanvas & canvas,const OffsetF & origin,RSBrush & brush,const SizeF & paintSize) const154 void CheckBoxModifier::DrawBackboard(
155     RSCanvas& canvas, const OffsetF& origin, RSBrush& brush, const SizeF& paintSize) const
156 {
157     float originX = origin.GetX();
158     float originY = origin.GetY();
159     float endX = originX + paintSize.Width();
160     float endY = originY + paintSize.Height();
161     auto rrect = RSRoundRect({ originX, originY, endX, endY }, borderRadius_, borderRadius_);
162     canvas.AttachBrush(brush);
163     canvas.DrawRoundRect(rrect);
164 }
165 
DrawCheck(RSCanvas & canvas,const OffsetF & origin,RSPen & pen,RSPen & shadowPen,const SizeF & paintSize) const166 void CheckBoxModifier::DrawCheck(
167     RSCanvas& canvas, const OffsetF& origin, RSPen& pen, RSPen& shadowPen, const SizeF& paintSize) const
168 {
169     RSPath path;
170     float originX = origin.GetX();
171     float originY = origin.GetY();
172     const Offset start =
173         Offset(paintSize.Width() * CHECK_MARK_START_X_POSITION, paintSize.Height() * CHECK_MARK_START_Y_POSITION);
174     const Offset middle =
175         Offset(paintSize.Width() * CHECK_MARK_MIDDLE_X_POSITION, paintSize.Height() * CHECK_MARK_MIDDLE_Y_POSITION);
176     const Offset end =
177         Offset(paintSize.Width() * CHECK_MARK_END_X_POSITION, paintSize.Height() * CHECK_MARK_END_Y_POSITION);
178     path.MoveTo(originX + start.GetX(), originY + start.GetY());
179     path.LineTo(originX + middle.GetX(), originY + middle.GetY());
180     path.MoveTo(originX + middle.GetX(), originY + middle.GetY());
181     path.LineTo(originX + end.GetX(), originY + end.GetY());
182     shadowPen.SetCapStyle(RSPen::CapStyle::ROUND_CAP);
183     shadowPen.SetWidth(checkStroke_ + shadowWidth_.ConvertToPx() * 2);
184     pen.SetWidth(checkStroke_);
185     pen.SetCapStyle(RSPen::CapStyle::ROUND_CAP);
186     canvas.AttachPen(shadowPen);
187     canvas.DrawPath(path);
188     canvas.AttachPen(pen);
189     canvas.DrawPath(path);
190 }
191 
192 } // namespace OHOS::Ace::NG
193