• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 #include "core/components_v2/grid_layout/grid_container_utils.h"
17 
18 #include "core/components/common/layout/grid_system_manager.h"
19 #include "core/components/container_modal/container_modal_constants.h"
20 #include "frameworks/bridge/common/utils/utils.h"
21 
22 namespace OHOS::Ace::V2 {
23 namespace {
24 constexpr int XS = 0;
25 constexpr int SM = 1;
26 constexpr int MD = 2;
27 constexpr int LG = 3;
28 constexpr int XL = 4;
29 constexpr int XXL = 5;
30 constexpr int BREAKPOINTSIZE = 5;
ParseBreakpoints(const BreakPoints & breakpoints)31 RefPtr<GridSizeInfo> ParseBreakpoints(const BreakPoints& breakpoints)
32 {
33     auto sizeInfo = AceType::MakeRefPtr<GridSizeInfo>();
34     sizeInfo->Reset();
35     for (const auto& breakpoint : breakpoints.breakpoints) {
36         sizeInfo->sizeInfo.push_back(Framework::StringToDimension(breakpoint));
37     }
38     return sizeInfo;
39 }
40 
ParseBreakpoints(const RefPtr<BreakPoints> & breakpoints)41 RefPtr<GridSizeInfo> ParseBreakpoints(const RefPtr<BreakPoints>& breakpoints)
42 {
43     if (!breakpoints) {
44         LOGI("user hasnt set breakpoint, use WindowSize and xs: 320vp, sm: 600vp, md: 840vp");
45         return AceType::MakeRefPtr<GridSizeInfo>();
46     }
47     return ParseBreakpoints(*breakpoints);
48 }
49 
50 } // namespace
51 
CalcBreakPoint(const RefPtr<GridSizeInfo> & threshold,double windowWidth)52 int GridContainerUtils::CalcBreakPoint(const RefPtr<GridSizeInfo> &threshold, double windowWidth)
53 {
54     int index = 0;
55     for (const auto &cur : threshold->sizeInfo) {
56         if (GreatNotEqual(cur.ConvertToPx(), windowWidth)) {
57             break;
58         }
59         index++;
60     }
61     return index;
62 }
63 
ProcessGridSizeType(const V2::BreakPoints & breakpoints,const Size & size,const WindowMode & mode,const RefPtr<PipelineBase> & pipeline)64 GridSizeType GridContainerUtils::ProcessGridSizeType(const V2::BreakPoints& breakpoints, const Size& size,
65     const WindowMode& mode, const RefPtr<PipelineBase>& pipeline)
66 {
67     auto threshold = ParseBreakpoints(breakpoints);
68     double windowWidth = 0.0;
69     if (breakpoints.reference == BreakPointsReference::WindowSize) {
70         if (!pipeline) {
71             TAG_LOGI(AceLogTag::ACE_GRIDROW, "pipeline is null");
72             return GridSizeType::UNDEFINED;
73         }
74         windowWidth = pipeline->GetDisplayWindowRectInfo().GetSize().Width();
75         if (mode == WindowMode::WINDOW_MODE_FLOATING &&
76             Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWENTY)) {
77             windowWidth =
78                 pipeline->CalcPageWidth(windowWidth - 2 * (CONTAINER_BORDER_WIDTH + CONTENT_PADDING).ConvertToPx());
79             int index = CalcBreakPoint(threshold, windowWidth);
80             return static_cast<GridSizeType>(index);
81         }
82         windowWidth = pipeline->CalcPageWidth(windowWidth);
83         std::vector<double> breakPoint(BREAKPOINTSIZE, -1.0);
84         std::transform(threshold->sizeInfo.begin(), threshold->sizeInfo.end(), breakPoint.begin(), [](Dimension x) {
85             return x.ConvertToVp();
86         });
87         auto custlayoutBreakpoints = WidthLayoutBreakPoint(breakPoint);
88         auto breakpoint = GetWidthBreakpoint(custlayoutBreakpoints, pipeline, breakpoints.userDefine);
89         return static_cast<GridSizeType>(breakpoint);
90     } else {
91         windowWidth = size.Width();
92     }
93     int index = CalcBreakPoint(threshold, windowWidth);
94     return static_cast<GridSizeType>(index);
95 }
96 
GetCalcWidthBreakpoint(const OHOS::Ace::WidthLayoutBreakPoint & finalBreakpoints,double density,double width)97 WidthBreakpoint GetCalcWidthBreakpoint(
98     const OHOS::Ace::WidthLayoutBreakPoint &finalBreakpoints, double density, double width)
99 {
100     WidthBreakpoint breakpoint;
101     if (finalBreakpoints.widthVPXS_ < 0 || GreatNotEqual(finalBreakpoints.widthVPXS_ * density, width)) {
102         breakpoint = WidthBreakpoint::WIDTH_XS;
103     } else if (finalBreakpoints.widthVPSM_ < 0 || GreatNotEqual(finalBreakpoints.widthVPSM_ * density, width)) {
104         breakpoint = WidthBreakpoint::WIDTH_SM;
105     } else if (finalBreakpoints.widthVPMD_ < 0 || GreatNotEqual(finalBreakpoints.widthVPMD_ * density, width)) {
106         breakpoint = WidthBreakpoint::WIDTH_MD;
107     } else if (finalBreakpoints.widthVPLG_ < 0 || GreatNotEqual(finalBreakpoints.widthVPLG_ * density, width)) {
108         breakpoint = WidthBreakpoint::WIDTH_LG;
109     } else if (finalBreakpoints.widthVPXL_ < 0 || GreatNotEqual(finalBreakpoints.widthVPXL_ * density, width)) {
110         breakpoint = WidthBreakpoint::WIDTH_XL;
111     } else {
112         breakpoint = WidthBreakpoint::WIDTH_XXL;
113     }
114     return breakpoint;
115 }
116 
GetWidthBreakpoint(const WidthLayoutBreakPoint & custlayoutBreakpoints,const RefPtr<PipelineBase> & pipeline,bool userDefine)117 WidthBreakpoint GridContainerUtils::GetWidthBreakpoint(
118     const WidthLayoutBreakPoint &custlayoutBreakpoints, const RefPtr<PipelineBase>& pipeline, bool userDefine)
119 {
120     auto finalBreakpoints = WidthLayoutBreakPoint(320.0, 600.0, 840.0, -1.0, -1.0);
121     auto configBreakpoints = SystemProperties::GetWidthLayoutBreakpoints();
122     if (userDefine) {  // cust has value
123         finalBreakpoints = custlayoutBreakpoints;
124     } else if (configBreakpoints != WidthLayoutBreakPoint()) {  // ccm has value
125         finalBreakpoints = configBreakpoints;
126     }
127     double density = pipeline->GetCurrentDensity();
128     return GetCalcWidthBreakpoint(finalBreakpoints, density, pipeline->GetPageWidth());
129 }
130 
ProcessGridSizeType(const RefPtr<BreakPoints> & breakpoints,const Size & size,const RefPtr<PipelineContext> & pipeline)131 GridSizeType GridContainerUtils::ProcessGridSizeType(
132     const RefPtr<BreakPoints>& breakpoints, const Size& size, const RefPtr<PipelineContext>& pipeline)
133 {
134     auto threshold = ParseBreakpoints(breakpoints);
135     double windowWidth = 0.0;
136     CHECK_NULL_RETURN(pipeline, GridSizeType::UNDEFINED);
137     if (breakpoints->reference == BreakPointsReference::WindowSize) {
138         windowWidth = GridSystemManager::GetInstance().GetScreenWidth();
139         auto windowManager = pipeline->GetWindowManager();
140         auto mode = windowManager->GetWindowMode();
141         if (mode == WindowMode::WINDOW_MODE_FLOATING
142             && Container::LessThanAPITargetVersion(PlatformVersion::VERSION_TWENTY)) {
143             windowWidth -= 2 * (CONTAINER_BORDER_WIDTH + CONTENT_PADDING).ConvertToPx();
144         }
145     } else {
146         windowWidth = size.Width();
147     }
148     int index = 0;
149     for (const auto& cur : threshold->sizeInfo) {
150         if (pipeline->NormalizeToPx(cur) > windowWidth) {
151             break;
152         }
153         index++;
154     }
155     return static_cast<GridSizeType>(index);
156 }
157 
ProcessGutter(GridSizeType sizeType,const Gutter & gutter)158 std::pair<Dimension, Dimension> GridContainerUtils::ProcessGutter(GridSizeType sizeType, const Gutter& gutter)
159 {
160     switch (sizeType) {
161         case GridSizeType::XS:
162             return std::pair<Dimension, Dimension>(gutter.xXs, gutter.yXs);
163         case GridSizeType::SM:
164             return std::pair<Dimension, Dimension>(gutter.xSm, gutter.ySm);
165         case GridSizeType::MD:
166             return std::pair<Dimension, Dimension>(gutter.xMd, gutter.yMd);
167         case GridSizeType::LG:
168             return std::pair<Dimension, Dimension>(gutter.xLg, gutter.yLg);
169         case GridSizeType::XL:
170             return std::pair<Dimension, Dimension>(gutter.xXl, gutter.yXl);
171         case GridSizeType::XXL:
172             return std::pair<Dimension, Dimension>(gutter.xXXl, gutter.yXXl);
173         default:
174             return std::pair<Dimension, Dimension>(gutter.xXs, gutter.yXs);
175     }
176 }
177 
ProcessGutter(GridSizeType sizeType,const RefPtr<Gutter> & gutter)178 std::pair<Dimension, Dimension> GridContainerUtils::ProcessGutter(GridSizeType sizeType, const RefPtr<Gutter>& gutter)
179 {
180     return ProcessGutter(sizeType, *gutter);
181 }
182 
ProcessColumn(GridSizeType sizeType,const GridContainerSize & columnNum)183 int32_t GridContainerUtils::ProcessColumn(GridSizeType sizeType, const GridContainerSize& columnNum)
184 {
185     switch (sizeType) {
186         case GridSizeType::XS:
187             return columnNum.xs;
188         case GridSizeType::SM:
189             return columnNum.sm;
190         case GridSizeType::MD:
191             return columnNum.md;
192         case GridSizeType::LG:
193             return columnNum.lg;
194         case GridSizeType::XL:
195             return columnNum.xl;
196         case GridSizeType::XXL:
197             return columnNum.xxl;
198         default:
199             return columnNum.xs;
200     }
201 }
202 
ProcessColumn(GridSizeType sizeType,const RefPtr<GridContainerSize> & columnNum)203 int32_t GridContainerUtils::ProcessColumn(GridSizeType sizeType, const RefPtr<GridContainerSize>& columnNum)
204 {
205     return ProcessColumn(sizeType, *columnNum);
206 }
207 
ProcessColumnWidth(const std::pair<double,double> & gutter,int32_t columnNum,double width)208 double GridContainerUtils::ProcessColumnWidth(const std::pair<double, double>& gutter, int32_t columnNum, double width)
209 {
210     auto xGutter = gutter.first;
211     if (columnNum != 0) {
212         return (width - (columnNum - 1) * xGutter) / columnNum;
213     }
214     return 0.0;
215 }
216 
InheritGridRowColumns(const RefPtr<V2::GridContainerSize> & gridContainerSize,int32_t * containerSizeArray,int32_t size)217 void GridContainerUtils::InheritGridRowColumns(const RefPtr<V2::GridContainerSize>& gridContainerSize,
218     int32_t *containerSizeArray, int32_t size)
219 {
220     for (auto i = 0; i < size; ++i) {
221         if (containerSizeArray[i] > 0) {
222             containerSizeArray[0] = containerSizeArray[i];
223             break;
224         }
225     }
226     if (containerSizeArray[0] <= 0) {
227         return;
228     }
229     for (auto i = 1; i < size; ++i) {
230         if (containerSizeArray[i] <= 0) {
231             containerSizeArray[i] = containerSizeArray[i - 1];
232         }
233     }
234     gridContainerSize->xs = containerSizeArray[XS];
235     gridContainerSize->sm = containerSizeArray[SM];
236     gridContainerSize->md = containerSizeArray[MD];
237     gridContainerSize->lg = containerSizeArray[LG];
238     gridContainerSize->xl = containerSizeArray[XL];
239     gridContainerSize->xxl = containerSizeArray[XXL];
240 }
241 } // namespace OHOS::Ace::V2
242