• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_PICKER_PAINT_METHOD_UTILS_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_PICKER_PAINT_METHOD_UTILS_H
18 
19 #include "base/geometry/ng/size_t.h"
20 #include "base/memory/ace_type.h"
21 #include "base/memory/referenced.h"
22 #include "base/utils/macros.h"
23 #include "base/utils/utils.h"
24 #include "core/components_ng/render/divider_painter.h"
25 #include "core/components_ng/render/node_paint_method.h"
26 #include "core/components/common/properties/color.h"
27 #include "core/components/picker/picker_theme.h"
28 #include "core/components_ng/pattern/time_picker/timepicker_layout_property.h"
29 #include "core/components_ng/pattern/picker/datepicker_row_layout_property.h"
30 #include "core/components_ng/render/drawing_prop_convertor.h"
31 #include "core/pipeline_ng/pipeline_context.h"
32 
33 namespace OHOS::Ace::NG {
34 constexpr int32_t CONST_AVERAGE = 2;
35 constexpr int32_t BACKGROUND_HIGH = 12;
36 constexpr uint32_t SELECTED_ROW_BACKGROUND_COLOR = 0x33FFFFFF;
37 constexpr double  CONST_HALF_VALUE = 2.0;
38 constexpr int32_t CONST_DELTA_STEP = 1;
39 constexpr int32_t CONST_LINE_DIFF = 1;
40 
41 class PickerPaintMethodCircleUtils {
42 public:
PickerPaintMethodCircleUtils()43     PickerPaintMethodCircleUtils() {}
44 
~PickerPaintMethodCircleUtils()45     virtual ~PickerPaintMethodCircleUtils() {}
46 
47     template<class T>
GetContentDrawFunctionL(PaintWrapper * paintWrapper,const RefPtr<PipelineBase> & pipeline)48     CanvasDrawFunction GetContentDrawFunctionL(PaintWrapper* paintWrapper, const RefPtr<PipelineBase>& pipeline)
49     {
50         CHECK_NULL_RETURN(paintWrapper, nullptr);
51         CHECK_NULL_RETURN(pipeline, nullptr);
52         auto theme = pipeline->GetTheme<PickerTheme>();
53         CHECK_NULL_RETURN(theme, nullptr);
54         auto dividerSpacing = pipeline->NormalizeToPx(theme->GetDividerSpacing());
55         const auto& geometryNode = paintWrapper->GetGeometryNode();
56         CHECK_NULL_RETURN(geometryNode, nullptr);
57         auto frameRect = geometryNode->GetFrameRect();
58         auto renderContext = paintWrapper->GetRenderContext();
59         CHECK_NULL_RETURN(renderContext, nullptr);
60         auto pickerNode = renderContext->GetHost();
61         CHECK_NULL_RETURN(pickerNode, nullptr);
62         auto layoutProperty = pickerNode->GetLayoutProperty<T>();
63         CHECK_NULL_RETURN(layoutProperty, nullptr);
64 
65         Color paintcolor(SELECTED_ROW_BACKGROUND_COLOR);
66         if (theme->GetOptionDecoration(false)) {
67             paintcolor = theme->GetOptionDecoration(false)->GetBackgroundColor();
68         }
69 
70         return [layoutProperty, frameRect, dividerSpacing, paintcolor](RSCanvas& canvas) {
71             PaddingPropertyF padding = layoutProperty->CreatePaddingAndBorder();
72             RectF contentRect = { padding.left.value_or(0), padding.top.value_or(0),
73                 frameRect.Width() - padding.Width(), frameRect.Height() - padding.Height() };
74             if (GreatOrEqual(contentRect.Height(), dividerSpacing)) {
75                 double upperLine = (contentRect.Height() - dividerSpacing) / CONST_HALF_VALUE + contentRect.GetY();
76                 double downLine = (contentRect.Height() + dividerSpacing) / CONST_HALF_VALUE + contentRect.GetY();
77                 DrawCapsule(upperLine, downLine, contentRect.Width(), BACKGROUND_HIGH, paintcolor, canvas);
78             }
79         };
80     }
81 
82 protected:
checkRepeat(std::vector<int32_t> & vec,int32_t _x,int32_t _y,int32_t up)83     static void checkRepeat(std::vector<int32_t>& vec, int32_t _x, int32_t _y, int32_t up)
84     {
85         if (vec[_y - up] < _x) {
86             vec[_y - up] = _x;
87         }
88     }
89 
DrawCapsule(int32_t up,int32_t down,int32_t width,int32_t margins,const Color & paintcolor,RSCanvas & canvas)90     static void DrawCapsule(int32_t up, int32_t down, int32_t width, int32_t margins, const Color &paintcolor,
91         RSCanvas& canvas)
92     {
93         int32_t radius = (down - up) / CONST_AVERAGE;
94         int32_t leftXc = margins + radius;
95         int32_t rightXc = width - radius - margins;
96         int32_t yC = up + radius;
97 
98         int32_t x = 0;
99         int32_t y = radius;
100         int32_t delta = CONST_AVERAGE - CONST_AVERAGE * radius;
101         const double penWidth = 1.0;
102 
103         RSPen pen;
104         pen.SetColor(paintcolor.GetValue());
105         pen.SetWidth(penWidth);
106         canvas.AttachPen(pen);
107 
108         // draw the capsule algorithm
109         std::vector<int32_t> xOffset(down - up + CONST_LINE_DIFF);
110         std::fill(xOffset.begin(), xOffset.end(), 0);
111         while (x <= y) {
112             checkRepeat(xOffset, x, yC + y, up);
113             checkRepeat(xOffset, x, yC - y, up);
114             checkRepeat(xOffset, y, yC + x, up);
115             checkRepeat(xOffset, y, yC - x, up);
116 
117             if (delta > 0) {
118                 delta += CONST_AVERAGE * (x - y) + CONST_DELTA_STEP;
119                 y--;
120             } else {
121                 delta += CONST_AVERAGE * x + CONST_DELTA_STEP;
122             }
123             x++;
124         }
125         for (int y = up; y <= down; y++) {
126             canvas.DrawLine(RSPoint(leftXc - xOffset[y - up], y), RSPoint(rightXc + xOffset[y - up], y));
127         }
128         canvas.DetachPen();
129     }
130 };
131 }
132 #endif
133