• 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     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