1 /*
2  * Copyright (c) 2024 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 "bridge/cj_frontend/interfaces/cj_ffi/cj_grid_row_ffi.h"
17 
18 #include "cj_lambda.h"
19 #include "bridge/cj_frontend/interfaces/cj_ffi/cj_view_abstract_ffi.h"
20 #include "core/components_ng/base/view_abstract.h"
21 #include "core/components_ng/pattern/grid_row/grid_row_model_ng.h"
22 
23 using namespace OHOS::Ace;
24 
25 namespace {
26 constexpr size_t MAX_NUMBER_BREAKPOINT = 6;
27 
InheritGridRowOption(const RefPtr<V2::GridContainerSize> & gridContainerSize,std::optional<int32_t> (& containerSizeArray)[MAX_NUMBER_BREAKPOINT])28 void InheritGridRowOption(const RefPtr<V2::GridContainerSize>& gridContainerSize,
29     std::optional<int32_t> (&containerSizeArray)[MAX_NUMBER_BREAKPOINT])
30 {
31     if (!containerSizeArray[0].has_value()) {
32         containerSizeArray[0] = V2::DEFAULT_COLUMN_NUMBER;
33     }
34     for (size_t i = 1; i < MAX_NUMBER_BREAKPOINT; i++) {
35         if (!containerSizeArray[i].has_value()) {
36             containerSizeArray[i] = containerSizeArray[i - 1].value();
37         }
38     }
39     int32_t index = 0;
40     gridContainerSize->xs = containerSizeArray[index++].value();
41     gridContainerSize->sm = containerSizeArray[index++].value();
42     gridContainerSize->md = containerSizeArray[index++].value();
43     gridContainerSize->lg = containerSizeArray[index++].value();
44     gridContainerSize->xl = containerSizeArray[index++].value();
45     gridContainerSize->xxl = containerSizeArray[index].value();
46 }
47 
ParserColumns(int32_t columns)48 RefPtr<V2::GridContainerSize> ParserColumns(int32_t columns)
49 {
50     return columns > 0 ? AceType::MakeRefPtr<V2::GridContainerSize>(columns)
51                        : AceType::MakeRefPtr<V2::GridContainerSize>();
52 }
53 
ParserColumns(const GridRowColumnOption & columns)54 RefPtr<V2::GridContainerSize> ParserColumns(const GridRowColumnOption& columns)
55 {
56     auto gridContainerSize = AceType::MakeRefPtr<V2::GridContainerSize>(12);
57     std::optional<int32_t> containerSizeArray[MAX_NUMBER_BREAKPOINT];
58     int32_t index = 0;
59     containerSizeArray[index++] = columns.xs;
60     containerSizeArray[index++] = columns.sm;
61     containerSizeArray[index++] = columns.md;
62     containerSizeArray[index++] = columns.lg;
63     containerSizeArray[index++] = columns.xl;
64     containerSizeArray[index] = columns.xxl;
65     InheritGridRowOption(gridContainerSize, containerSizeArray);
66     return gridContainerSize;
67 }
68 
InheritGridRowGutterOption(const RefPtr<V2::Gutter> & gutter,std::optional<Dimension> (& gutterSizeArray)[MAX_NUMBER_BREAKPOINT],bool isHorizontal)69 void InheritGridRowGutterOption(const RefPtr<V2::Gutter>& gutter,
70     std::optional<Dimension> (&gutterSizeArray)[MAX_NUMBER_BREAKPOINT], bool isHorizontal)
71 {
72     if (!gutterSizeArray[0].has_value()) {
73         gutterSizeArray[0] = Dimension(0);
74     }
75     for (size_t i = 1; i < MAX_NUMBER_BREAKPOINT; i++) {
76         if (!gutterSizeArray[i].has_value()) {
77             gutterSizeArray[i] = gutterSizeArray[i - 1].value();
78         }
79     }
80     if (isHorizontal) {
81         int32_t indexHorizontal = 0;
82         gutter->xXs = gutterSizeArray[indexHorizontal++].value();
83         gutter->xSm = gutterSizeArray[indexHorizontal++].value();
84         gutter->xMd = gutterSizeArray[indexHorizontal++].value();
85         gutter->xLg = gutterSizeArray[indexHorizontal++].value();
86         gutter->xXl = gutterSizeArray[indexHorizontal++].value();
87         gutter->xXXl = gutterSizeArray[indexHorizontal].value();
88         return;
89     }
90     int32_t index = 0;
91     gutter->yXs = gutterSizeArray[index++].value();
92     gutter->ySm = gutterSizeArray[index++].value();
93     gutter->yMd = gutterSizeArray[index++].value();
94     gutter->yLg = gutterSizeArray[index++].value();
95     gutter->yXl = gutterSizeArray[index++].value();
96     gutter->yXXl = gutterSizeArray[index].value();
97 }
98 
ParseGutterObject(const AtCGridRowSizeOption & gutterObject,RefPtr<V2::Gutter> & gutter,bool isHorizontal)99 void ParseGutterObject(const AtCGridRowSizeOption& gutterObject, RefPtr<V2::Gutter>& gutter, bool isHorizontal)
100 {
101     std::optional<Dimension> gutterOptions[MAX_NUMBER_BREAKPOINT];
102     for (size_t i = 0; i < MAX_NUMBER_BREAKPOINT; ++i) {
103         gutterOptions[i] = Dimension(gutterObject.data[i].value, static_cast<DimensionUnit>(gutterObject.data[i].unit));
104     }
105     InheritGridRowGutterOption(gutter, gutterOptions, isHorizontal);
106 }
107 
ParserGutter(const AtCGridRowSizeOption & x,const AtCGridRowSizeOption & y)108 RefPtr<V2::Gutter> ParserGutter(const AtCGridRowSizeOption& x, const AtCGridRowSizeOption& y)
109 {
110     auto gutter = AceType::MakeRefPtr<V2::Gutter>();
111 
112     ParseGutterObject(x, gutter, true);
113     ParseGutterObject(y, gutter, false);
114     return gutter;
115 }
116 
ParserGutter(double x,int32_t xUnit,double y,int32_t yUnit)117 RefPtr<V2::Gutter> ParserGutter(double x, int32_t xUnit, double y, int32_t yUnit)
118 {
119     auto gutter = AceType::MakeRefPtr<V2::Gutter>();
120     gutter->SetXGutter(Dimension(x, static_cast<DimensionUnit>(xUnit)));
121     gutter->SetYGutter(Dimension(y, static_cast<DimensionUnit>(yUnit)));
122     return gutter;
123 }
124 
ParserGutter(const Dimension & gutterDim)125 RefPtr<V2::Gutter> ParserGutter(const Dimension& gutterDim)
126 {
127     auto gutter = AceType::MakeRefPtr<V2::Gutter>(gutterDim);
128     return gutter;
129 }
130 
ParserBreakpoints(VectorFloat64Handle valuesHandle,VectorInt32Handle unitsHandle,int32_t breakpointReference)131 RefPtr<V2::BreakPoints> ParserBreakpoints(
132     VectorFloat64Handle valuesHandle, VectorInt32Handle unitsHandle, int32_t breakpointReference)
133 {
134     auto breakpoint = AceType::MakeRefPtr<V2::BreakPoints>();
135     breakpoint->reference = static_cast<V2::BreakPointsReference>(breakpointReference);
136     breakpoint->breakpoints.clear();
137     const auto& valueVec = *reinterpret_cast<std::vector<double>*>(valuesHandle);
138     const auto& unitVec = *reinterpret_cast<std::vector<int32_t>*>(unitsHandle);
139     if (valueVec.size() > MAX_NUMBER_BREAKPOINT - 1) {
140         LOGI("The maximum number of breakpoints is %{public}zu", MAX_NUMBER_BREAKPOINT);
141         return breakpoint;
142     }
143     double width = -1.0;
144 
145     for (size_t i = 0; i < valueVec.size(); i++) {
146         if (GreatNotEqual(width, valueVec[i])) {
147             LOGI("Array data must be sorted in ascending order");
148             return breakpoint;
149         }
150         Dimension valueDimension(valueVec[i], static_cast<DimensionUnit>(unitVec[i]));
151         breakpoint->breakpoints.push_back(valueDimension.ToString());
152     }
153     return breakpoint;
154 }
155 
ParserDirection(int32_t direction)156 V2::GridRowDirection ParserDirection(int32_t direction)
157 {
158     return static_cast<V2::GridRowDirection>(direction);
159 }
160 } // namespace
161 
162 extern "C" {
FfiOHOSAceFrameworkGridRowCreate()163 void FfiOHOSAceFrameworkGridRowCreate()
164 {
165     GridRowModel::GetInstance()->Create();
166 }
167 
FfiOHOSAceFrameworkGridRowCreateWithFloat64Int32(GridRowCreateWithFloat64Int32 createOption)168 void FfiOHOSAceFrameworkGridRowCreateWithFloat64Int32(GridRowCreateWithFloat64Int32 createOption)
169 {
170     auto parsedColumns = ParserColumns(createOption.columns);
171     auto parsedGutter =
172         ParserGutter(Dimension(createOption.gutterValue, static_cast<DimensionUnit>(createOption.gutterUnit)));
173     auto parsedBreakpoints =
174         ParserBreakpoints(createOption.breakpointVals, createOption.breakpointUnits, createOption.breakpointReference);
175     auto parsedDirection = ParserDirection(createOption.direction);
176     GridRowModel::GetInstance()->Create(parsedColumns, parsedGutter, parsedBreakpoints, parsedDirection);
177 }
178 
FfiOHOSAceFrameworkGridRowCreateWithFloat64ColumnOption(GridRowCreateWithFloat64ColumnOption createOption)179 void FfiOHOSAceFrameworkGridRowCreateWithFloat64ColumnOption(GridRowCreateWithFloat64ColumnOption createOption)
180 {
181     auto parsedColumns = ParserColumns(createOption.columns);
182     auto parsedGutter =
183         ParserGutter(Dimension(createOption.gutterValue, static_cast<DimensionUnit>(createOption.gutterUnit)));
184     auto parsedBreakpoints =
185         ParserBreakpoints(createOption.breakpointVals, createOption.breakpointUnits, createOption.breakpointReference);
186     auto parsedDirection = ParserDirection(createOption.direction);
187 
188     GridRowModel::GetInstance()->Create(parsedColumns, parsedGutter, parsedBreakpoints, parsedDirection);
189 }
190 
FfiOHOSAceFrameworkGridRowCreateWithFloat64OptionColumnOption(GridRowCreateWithFloat64OptionColumnOption createOption)191 void FfiOHOSAceFrameworkGridRowCreateWithFloat64OptionColumnOption(
192     GridRowCreateWithFloat64OptionColumnOption createOption)
193 {
194     auto parsedColumns = ParserColumns(createOption.columns);
195     auto parsedGutter = ParserGutter(createOption.x, createOption.xUnit, createOption.y, createOption.yUnit);
196     auto parsedBreakpoints =
197         ParserBreakpoints(createOption.breakpointVals, createOption.breakpointUnits, createOption.breakpointReference);
198     auto parsedDirection = ParserDirection(createOption.direction);
199 
200     GridRowModel::GetInstance()->Create(parsedColumns, parsedGutter, parsedBreakpoints, parsedDirection);
201 }
202 
FfiOHOSAceFrameworkGridRowCreateWithSizeOptionColumnOption(GridRowCreateWithSizeOptionColumnOption createOption)203 void FfiOHOSAceFrameworkGridRowCreateWithSizeOptionColumnOption(GridRowCreateWithSizeOptionColumnOption createOption)
204 {
205     auto parsedColumns = ParserColumns(createOption.columns);
206     auto parsedGutter = ParserGutter(createOption.x, createOption.y);
207     auto parsedBreakpoints =
208         ParserBreakpoints(createOption.breakpointVals, createOption.breakpointUnits, createOption.breakpointReference);
209     auto parsedDirection = ParserDirection(createOption.direction);
210 
211     GridRowModel::GetInstance()->Create(parsedColumns, parsedGutter, parsedBreakpoints, parsedDirection);
212 }
213 
FfiOHOSAceFrameworkGridRowCreateWithFloat64OptionInt32(GridRowCreateWithFloat64OptionInt32 createOption)214 void FfiOHOSAceFrameworkGridRowCreateWithFloat64OptionInt32(GridRowCreateWithFloat64OptionInt32 createOption)
215 {
216     auto parsedColumns = ParserColumns(createOption.columns);
217     auto parsedGutter = ParserGutter(createOption.x, createOption.xUnit, createOption.y, createOption.yUnit);
218     auto parsedBreakpoints =
219         ParserBreakpoints(createOption.breakpointVals, createOption.breakpointUnits, createOption.breakpointReference);
220     auto parsedDirection = ParserDirection(createOption.direction);
221 
222     GridRowModel::GetInstance()->Create(parsedColumns, parsedGutter, parsedBreakpoints, parsedDirection);
223 }
224 
FfiOHOSAceFrameworkGridRowCreateWithSizeOptionInt32(GridRowCreateWithSizeOptionInt32 createOption)225 void FfiOHOSAceFrameworkGridRowCreateWithSizeOptionInt32(GridRowCreateWithSizeOptionInt32 createOption)
226 {
227     auto parsedColumns = ParserColumns(createOption.columns);
228     auto parsedGutter = ParserGutter(createOption.x, createOption.y);
229     auto parsedBreakpoints =
230         ParserBreakpoints(createOption.breakpointVals, createOption.breakpointUnits, createOption.breakpointReference);
231     auto parsedDirection = ParserDirection(createOption.direction);
232 
233     GridRowModel::GetInstance()->Create(parsedColumns, parsedGutter, parsedBreakpoints, parsedDirection);
234 }
235 
FfiOHOSAceFrameworkGridRowSetHeight(double height,int32_t heightUnit)236 void FfiOHOSAceFrameworkGridRowSetHeight(double height, int32_t heightUnit)
237 {
238     FfiOHOSAceFrameworkViewAbstractSetHeight(height, heightUnit);
239     GridRowModel::GetInstance()->SetHeight();
240 }
241 
FfiOHOSAceFrameworkGridRowBreakpointEvent(void (* callback)(const char *))242 void FfiOHOSAceFrameworkGridRowBreakpointEvent(void (*callback)(const char*))
243 {
244     auto onHover = CJLambda::Create(callback);
245     auto onBreakpointChange = [func = std::move(onHover)](const std::string& value) { func(value.c_str()); };
246     GridRowModel::GetInstance()->SetOnBreakPointChange(onBreakpointChange);
247 }
248 
FfiOHOSAceFrameworkGridRowAlignItem(int32_t alignItem)249 void FfiOHOSAceFrameworkGridRowAlignItem(int32_t alignItem)
250 {
251     if (alignItem == static_cast<int32_t>(FlexAlign::FLEX_START) ||
252         alignItem == static_cast<int32_t>(FlexAlign::FLEX_END) ||
253         alignItem == static_cast<int32_t>(FlexAlign::CENTER) || alignItem == static_cast<int32_t>(FlexAlign::STRETCH)) {
254         GridRowModel::GetInstance()->SetAlignItems(static_cast<FlexAlign>(alignItem));
255     } else if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
256         GridRowModel::GetInstance()->SetAlignItems(FlexAlign::FLEX_START);
257     }
258 }
259 }
260