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