1 /*
2 * Copyright (c) 2022-2023 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/tabs/tab_bar_paint_method.h"
17
18 #include "core/components/tab_bar/tab_theme.h"
19 #include "core/components_ng/pattern/tabs/tab_bar_paint_property.h"
20 #include "core/components_ng/render/drawing_prop_convertor.h"
21
22 namespace OHOS::Ace::NG {
23 namespace {
24 constexpr int8_t LEFT_GRADIENT = 0;
25 constexpr int8_t RIGHT_GRADIENT = 1;
26 constexpr int8_t TOP_GRADIENT = 2;
27 constexpr int8_t BOTTOM_GRADIENT = 3;
28 constexpr int8_t POS_NUM = 4;
29 }
30
GetForegroundDrawFunction(PaintWrapper * paintWrapper)31 CanvasDrawFunction TabBarPaintMethod::GetForegroundDrawFunction(PaintWrapper* paintWrapper)
32 {
33 auto paintProperty = AceType::DynamicCast<TabBarPaintProperty>(paintWrapper->GetPaintProperty());
34 CHECK_NULL_RETURN(paintProperty, nullptr);
35 if (!paintProperty->GetFadingEdge().value_or(true)) {
36 return nullptr;
37 }
38
39 const auto& geometryNode = paintWrapper->GetGeometryNode();
40 CHECK_NULL_RETURN(geometryNode, nullptr);
41 MarginPropertyF padding;
42 if (geometryNode->GetPadding()) {
43 padding.left = geometryNode->GetPadding()->left;
44 padding.right = geometryNode->GetPadding()->right;
45 }
46
47 auto paintFunc = [gradientRegions = gradientRegions_, barRect = frameRect_, backgroundColor = backgroundColor_,
48 padding](RSCanvas& canvas) {
49 PaintGradient(canvas, barRect, backgroundColor, gradientRegions, padding);
50 };
51 return paintFunc;
52 }
53
PaintGradient(RSCanvas & canvas,const RectF & barRect,const Color & backgroundColor,const std::vector<bool> & gradientRegions,const MarginPropertyF & padding)54 void TabBarPaintMethod::PaintGradient(RSCanvas& canvas, const RectF& barRect, const Color& backgroundColor,
55 const std::vector<bool>& gradientRegions, const MarginPropertyF& padding)
56 {
57 auto pipelineContext = PipelineContext::GetCurrentContext();
58 CHECK_NULL_VOID(pipelineContext);
59 auto tabTheme = pipelineContext->GetTheme<TabTheme>();
60 CHECK_NULL_VOID(tabTheme);
61 float shadowMargin = static_cast<float>(tabTheme->GetTabBarShadowMargin().ConvertToPx());
62 float gradientWidth = static_cast<float>(tabTheme->GetTabBarGradientWidth().ConvertToPx());
63
64 auto leftPadding = padding.left.value_or(0.0f);
65 auto rightPadding = padding.right.value_or(0.0f);
66
67 for (int8_t position = 0; position < POS_NUM; position++) {
68 if (gradientRegions[position]) {
69 switch (position) {
70 case LEFT_GRADIENT:
71 PaintLeftGradient(canvas, barRect, backgroundColor, shadowMargin, gradientWidth, leftPadding);
72 break;
73 case RIGHT_GRADIENT:
74 PaintRightGradient(canvas, barRect, backgroundColor, shadowMargin, gradientWidth, rightPadding);
75 break;
76 case TOP_GRADIENT:
77 PaintTopGradient(canvas, barRect, backgroundColor, shadowMargin, gradientWidth);
78 break;
79 case BOTTOM_GRADIENT:
80 PaintBottomGradient(canvas, barRect, backgroundColor, shadowMargin, gradientWidth);
81 break;
82 default:
83 break;
84 }
85 }
86 }
87 }
88
PaintLeftGradient(RSCanvas & canvas,const RectF & barRect,const Color & backgroundColor,float shadowMargin,float gradientWidth,float padding)89 void TabBarPaintMethod::PaintLeftGradient(RSCanvas& canvas, const RectF& barRect, const Color& backgroundColor,
90 float shadowMargin, float gradientWidth, float padding)
91 {
92 RSRect gradientRect(0.0f, 0.0f, padding + shadowMargin + gradientWidth, barRect.Height());
93 RSPoint leftStartPoint;
94 leftStartPoint.SetX(shadowMargin + gradientWidth + padding);
95 leftStartPoint.SetY(0.0f);
96 RSPoint leftEndPoint;
97 leftEndPoint.SetX(0.0f);
98 leftEndPoint.SetY(0.0f);
99 PaintGradientRect(
100 canvas, gradientRect, backgroundColor, leftStartPoint, leftEndPoint, padding + shadowMargin, gradientWidth);
101 }
102
PaintRightGradient(RSCanvas & canvas,const RectF & barRect,const Color & backgroundColor,float shadowMargin,float gradientWidth,float padding)103 void TabBarPaintMethod::PaintRightGradient(RSCanvas& canvas, const RectF& barRect, const Color& backgroundColor,
104 float shadowMargin, float gradientWidth, float padding)
105 {
106 RSRect gradientRect(
107 barRect.Width() - shadowMargin - gradientWidth - padding, 0.0f, barRect.Width(), barRect.Height());
108 RSPoint rightStartPoint;
109 rightStartPoint.SetX(barRect.Width() - shadowMargin - gradientWidth - padding);
110 rightStartPoint.SetY(0.0f);
111 RSPoint rightEndPoint;
112 rightEndPoint.SetX(barRect.Width());
113 rightEndPoint.SetY(0.0f);
114 PaintGradientRect(
115 canvas, gradientRect, backgroundColor, rightStartPoint, rightEndPoint, shadowMargin + padding, gradientWidth);
116 }
117
PaintTopGradient(RSCanvas & canvas,const RectF & barRect,const Color & backgroundColor,float shadowMargin,float gradientWidth)118 void TabBarPaintMethod::PaintTopGradient(RSCanvas& canvas, const RectF& barRect, const Color& backgroundColor,
119 float shadowMargin, float gradientWidth)
120 {
121 RSRect gradientRect(0.0f, 0.0f, barRect.Width(), shadowMargin + gradientWidth);
122 RSPoint topStartPoint;
123 topStartPoint.SetX(0.0f);
124 topStartPoint.SetY(shadowMargin + gradientWidth);
125 RSPoint topEndPoint;
126 topEndPoint.SetX(0.0f);
127 topEndPoint.SetY(0.0f);
128 PaintGradientRect(canvas, gradientRect, backgroundColor, topStartPoint, topEndPoint, shadowMargin,
129 gradientWidth);
130 }
131
PaintBottomGradient(RSCanvas & canvas,const RectF & barRect,const Color & backgroundColor,float shadowMargin,float gradientWidth)132 void TabBarPaintMethod::PaintBottomGradient(RSCanvas& canvas, const RectF& barRect, const Color& backgroundColor,
133 float shadowMargin, float gradientWidth)
134 {
135 RSRect gradientRect(0.0f, barRect.Height() - shadowMargin - gradientWidth,
136 barRect.Width(), barRect.Height());
137 RSPoint bottomStartPoint;
138 bottomStartPoint.SetX(0.0f);
139 bottomStartPoint.SetY(barRect.Height() - shadowMargin - gradientWidth);
140 RSPoint bottomEndPoint;
141 bottomEndPoint.SetX(0.0f);
142 bottomEndPoint.SetY(barRect.Height());
143 PaintGradientRect(canvas, gradientRect, backgroundColor, bottomStartPoint, bottomEndPoint, shadowMargin,
144 gradientWidth);
145 }
146
PaintGradientRect(RSCanvas & canvas,const RSRect & gradientRect,const Color & backgroundColor,const RSPoint & startPoint,const RSPoint & endPoint,float shadowMargin,float gradientWidth)147 void TabBarPaintMethod::PaintGradientRect(RSCanvas& canvas, const RSRect& gradientRect, const Color& backgroundColor,
148 const RSPoint& startPoint, const RSPoint& endPoint, float shadowMargin, float gradientWidth)
149 {
150 RSBrush brush;
151 Color endColor = backgroundColor;
152 Color startColor = endColor.ChangeAlpha(0);
153 std::vector<float> gradientPos { 0.0f, gradientWidth / (shadowMargin + gradientWidth), 1.0f };
154 std::vector<RSColorQuad> gradientColors { startColor.GetValue(), endColor.GetValue(), endColor.GetValue() };
155 brush.SetShaderEffect(
156 RSShaderEffect::CreateLinearGradient(
157 startPoint, endPoint, gradientColors, gradientPos, RSTileMode::CLAMP));
158 canvas.DetachPen().AttachBrush(brush);
159 canvas.DrawRect(gradientRect);
160 canvas.DetachBrush();
161 }
162
GetContentModifier(PaintWrapper * paintWrapper)163 RefPtr<Modifier> TabBarPaintMethod::GetContentModifier(PaintWrapper* paintWrapper)
164 {
165 return tabBarModifier_;
166 }
167
UpdateContentModifier(PaintWrapper * paintWrapper)168 void TabBarPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper)
169 {
170 CHECK_NULL_VOID(tabBarModifier_);
171 auto pipeline = PipelineBase::GetCurrentContext();
172 CHECK_NULL_VOID(pipeline);
173
174 tabBarModifier_->SetIndicatorOffset(indicatorOffset_);
175 tabBarModifier_->SetIndicatorColor(LinearColor(indicatorStyle_.color));
176 tabBarModifier_->SetIndicatorHeight(indicatorStyle_.height.ConvertToPx());
177 tabBarModifier_->SetIndicatorWidth(indicatorStyle_.width.ConvertToPx());
178 tabBarModifier_->SetIndicatorBorderRadius(indicatorStyle_.borderRadius.ConvertToPx());
179 tabBarModifier_->SetIndicatorMarginTop(indicatorStyle_.marginTop.ConvertToPx());
180 tabBarModifier_->SetHasIndicator(hasIndicator_);
181 }
182 } // namespace OHOS::Ace::NG
183