• 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 
16 #include "core/components_ng/pattern/toggle/switch_paint_method.h"
17 
18 #include "base/geometry/ng/offset_t.h"
19 #include "base/memory/referenced.h"
20 #include "base/utils/utils.h"
21 #include "core/components/checkable/checkable_theme.h"
22 #include "core/components/common/properties/color.h"
23 #include "core/components_ng/pattern/toggle/switch_layout_algorithm.h"
24 #include "core/components_ng/pattern/toggle/switch_modifier.h"
25 #include "core/components_ng/pattern/toggle/switch_paint_property.h"
26 #include "core/components_ng/render/drawing.h"
27 #include "core/components_ng/render/drawing_prop_convertor.h"
28 #include "core/components_ng/render/paint_property.h"
29 #include "core/pipeline/pipeline_base.h"
30 
31 namespace OHOS::Ace::NG {
32 
33 namespace {
34 constexpr uint8_t ENABLED_ALPHA = 255;
35 constexpr uint8_t DISABLED_ALPHA = 102;
36 } // namespace
37 
SwitchModifier(bool isSelect,const Color & boardColor,float mainDelta)38 SwitchModifier::SwitchModifier(bool isSelect, const Color& boardColor, float mainDelta)
39 {
40     animatableBoardColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(boardColor));
41     animateHoverColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(Color::TRANSPARENT));
42     mainDelta_ = AceType::MakeRefPtr<PropertyFloat>(mainDelta);
43     isSelect_ = AceType::MakeRefPtr<PropertyBool>(isSelect);
44     isHover_ = AceType::MakeRefPtr<PropertyBool>(false);
45     offset_ = AceType::MakeRefPtr<PropertyOffsetF>(OffsetF());
46     size_ = AceType::MakeRefPtr<PropertySizeF>(SizeF());
47     enabled_ = AceType::MakeRefPtr<PropertyBool>(true);
48 
49     AttachProperty(animatableBoardColor_);
50     AttachProperty(animateHoverColor_);
51     AttachProperty(mainDelta_);
52     AttachProperty(isSelect_);
53     AttachProperty(isHover_);
54     AttachProperty(offset_);
55     AttachProperty(size_);
56     AttachProperty(enabled_);
57 }
58 
InitializeParam()59 void SwitchModifier::InitializeParam()
60 {
61     auto pipeline = PipelineBase::GetCurrentContext();
62     CHECK_NULL_VOID(pipeline);
63     auto switchTheme = pipeline->GetTheme<SwitchTheme>();
64     CHECK_NULL_VOID(switchTheme);
65     activeColor_ = switchTheme->GetActiveColor();
66     inactiveColor_ = switchTheme->GetInactiveColor();
67     pointColor_ = switchTheme->GetPointColor();
68     clickEffectColor_ = switchTheme->GetClickEffectColor();
69     hoverColor_ = switchTheme->GetHoverColor();
70     hoverRadius_ = switchTheme->GetHoverRadius();
71     userActiveColor_ = activeColor_;
72     userPointColor_ = pointColor_;
73     hoverDuration_ = switchTheme->GetHoverDuration();
74     hoverToTouchDuration_ = switchTheme->GetHoverToTouchDuration();
75     touchDuration_ = switchTheme->GetTouchDuration();
76     colorAnimationDuration_ = switchTheme->GetColorAnimationDuration();
77 }
78 
PaintSwitch(RSCanvas & canvas,const OffsetF & contentOffset,const SizeF & contentSize)79 void SwitchModifier::PaintSwitch(RSCanvas& canvas, const OffsetF& contentOffset, const SizeF& contentSize)
80 {
81     auto pipelineContext = PipelineBase::GetCurrentContext();
82     CHECK_NULL_VOID(pipelineContext);
83     auto switchTheme = pipelineContext->GetTheme<SwitchTheme>();
84     CHECK_NULL_VOID(switchTheme);
85 
86     auto width = contentSize.Width();
87     auto height = contentSize.Height();
88     auto radius = height / 2;
89     auto actualGap = radiusGap_.ConvertToPx() * height /
90                      (switchTheme->GetHeight() - switchTheme->GetHotZoneVerticalPadding() * 2).ConvertToPx();
91     auto xOffset = contentOffset.GetX();
92     auto yOffset = contentOffset.GetY();
93     pointRadius_ = radius - actualGap;
94     clickEffectColor_ = switchTheme->GetClickEffectColor();
95     hoverColor_ = switchTheme->GetHoverColor();
96     hoverRadius_ = switchTheme->GetHoverRadius();
97     auto defaultWidth = switchTheme->GetDefaultWidth().ConvertToPx();
98     auto defaultHeight = switchTheme->GetDefaultHeight().ConvertToPx();
99     auto defaultWidthGap =
100         defaultWidth - (switchTheme->GetWidth() - switchTheme->GetHotZoneHorizontalPadding() * 2).ConvertToPx();
101     auto defaultHeightGap =
102         defaultHeight - (switchTheme->GetHeight() - switchTheme->GetHotZoneVerticalPadding() * 2).ConvertToPx();
103     actualWidth_ = width + defaultWidthGap;
104     actualHeight_ = height + defaultHeightGap;
105     hoverRadius_ =
106         hoverRadius_ * height / (switchTheme->GetHeight() - switchTheme->GetHotZoneVerticalPadding() * 2).ConvertToPx();
107 
108     OffsetF hoverBoardOffset;
109     hoverBoardOffset.SetX(xOffset - (actualWidth_ - width) / 2.0);
110     hoverBoardOffset.SetY(yOffset - (actualHeight_ - height) / 2.0);
111     DrawHoverBoard(canvas, hoverBoardOffset);
112     RSRect rect;
113     rect.SetLeft(xOffset);
114     rect.SetTop(yOffset);
115     rect.SetRight(xOffset + width);
116     rect.SetBottom(yOffset + height);
117     RSRoundRect roundRect(rect, radius, radius);
118 
119     RSBrush brush;
120     if (!enabled_->Get()) {
121         brush.SetColor(
122             ToRSColor(animatableBoardColor_->Get().BlendOpacity(static_cast<float>(DISABLED_ALPHA) / ENABLED_ALPHA)));
123     } else {
124         brush.SetColor(ToRSColor(animatableBoardColor_->Get()));
125     }
126     brush.SetBlendMode(RSBlendMode::SRC_OVER);
127     brush.SetAntiAlias(true);
128     canvas.AttachBrush(brush);
129     canvas.DrawRoundRect(roundRect);
130 
131     brush.SetColor(ToRSColor(userPointColor_));
132     brush.SetAntiAlias(true);
133     canvas.AttachBrush(brush);
134 
135     RSPoint point;
136     point.SetX(xOffset + actualGap + pointRadius_ + mainDelta_->Get());
137     point.SetY(yOffset + radius);
138     canvas.DrawCircle(point, pointRadius_);
139 }
140 
DrawHoverBoard(RSCanvas & canvas,const OffsetF & offset) const141 void SwitchModifier::DrawHoverBoard(RSCanvas& canvas, const OffsetF& offset) const
142 {
143     RSBrush brush;
144     brush.SetColor(ToRSColor(animateHoverColor_->Get()));
145     brush.SetAntiAlias(true);
146     auto rightBottomX = offset.GetX() + actualWidth_;
147     auto rightBottomY = offset.GetY() + actualHeight_;
148     auto rrect = RSRoundRect({ offset.GetX(), offset.GetY(), rightBottomX, rightBottomY }, hoverRadius_.ConvertToPx(),
149         hoverRadius_.ConvertToPx());
150     canvas.AttachBrush(brush);
151     canvas.DrawRoundRect(rrect);
152 }
153 
GetSwitchWidth(const SizeF & contentSize) const154 float SwitchModifier::GetSwitchWidth(const SizeF& contentSize) const
155 {
156     const float switchGap = 2.0f;
157     auto pipelineContext = PipelineBase::GetCurrentContext();
158     CHECK_NULL_RETURN(pipelineContext, false);
159     auto switchTheme = pipelineContext->GetTheme<SwitchTheme>();
160     auto actualGap = switchGap * contentSize.Height() /
161                      (switchTheme->GetHeight() - switchTheme->GetHotZoneVerticalPadding() * 2).ConvertToPx();
162     auto switchWidth = contentSize.Width() - contentSize.Height() + actualGap;
163     return switchWidth;
164 }
165 
166 } // namespace OHOS::Ace::NG