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