• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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