1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.constraintlayout.core.state.helpers;
18 
19 import androidx.constraintlayout.core.state.HelperReference;
20 import androidx.constraintlayout.core.state.State;
21 import androidx.constraintlayout.core.utils.GridCore;
22 import androidx.constraintlayout.core.widgets.HelperWidget;
23 
24 import org.jspecify.annotations.NonNull;
25 import org.jspecify.annotations.Nullable;
26 
27 /**
28  * A HelperReference of a Grid Helper that helps enable Grid in Compose
29  */
30 public class GridReference extends HelperReference {
31 
32     private static final String SPANS_RESPECT_WIDGET_ORDER_STRING = "spansrespectwidgetorder";
33     private static final String SUB_GRID_BY_COL_ROW_STRING = "subgridbycolrow";
34 
GridReference(@onNull State state, State.@NonNull Helper type)35     public GridReference(@NonNull State state, State.@NonNull Helper type) {
36         super(state, type);
37         if (type == State.Helper.ROW) {
38             this.mRowsSet = 1;
39         } else if (type == State.Helper.COLUMN) {
40             this.mColumnsSet = 1;
41         }
42     }
43 
44     /**
45      * The Grid Object
46      */
47     private GridCore mGrid;
48 
49     /**
50      * padding start
51      */
52     private int mPaddingStart = 0;
53 
54     /**
55      * padding end
56      */
57     private int mPaddingEnd = 0;
58 
59     /**
60      * padding top
61      */
62     private int mPaddingTop = 0;
63 
64     /**
65      * padding bottom
66      */
67     private int mPaddingBottom = 0;
68 
69     /**
70      * The orientation of the widgets arrangement horizontally or vertically
71      */
72     private int mOrientation;
73 
74     /**
75      * Number of rows of the Grid
76      */
77     private int mRowsSet;
78 
79     /**
80      * Number of columns of the Grid
81      */
82     private int mColumnsSet;
83 
84     /**
85      * The horizontal gaps between widgets
86      */
87     private float mHorizontalGaps;
88 
89     /**
90      * The vertical gaps between widgets
91      */
92     private float mVerticalGaps;
93 
94     /**
95      * The weight of each widget in a row
96      */
97     private String mRowWeights;
98 
99     /**
100      * The weight of each widget in a column
101      */
102     private String mColumnWeights;
103 
104     /**
105      * Specify the spanned areas of widgets
106      */
107     private String mSpans;
108 
109     /**
110      * Specify the positions to be skipped in the Grid
111      */
112     private String mSkips;
113 
114     /**
115      * An int value containing flag information.
116      */
117     private int mFlags;
118 
119     /**
120      * get padding left
121      * @return padding left
122      */
getPaddingStart()123     public int getPaddingStart() {
124         return mPaddingStart;
125     }
126 
127     /**
128      * set padding left
129      * @param paddingStart padding left to be set
130      */
setPaddingStart(int paddingStart)131     public void setPaddingStart(int paddingStart) {
132         mPaddingStart = paddingStart;
133     }
134 
135     /**
136      * get padding right
137      * @return padding right
138      */
getPaddingEnd()139     public int getPaddingEnd() {
140         return mPaddingEnd;
141     }
142 
143     /**
144      * set padding right
145      * @param paddingEnd padding right to be set
146      */
setPaddingEnd(int paddingEnd)147     public void setPaddingEnd(int paddingEnd) {
148         mPaddingEnd = paddingEnd;
149     }
150 
151     /**
152      * get padding top
153      * @return padding top
154      */
getPaddingTop()155     public int getPaddingTop() {
156         return mPaddingTop;
157     }
158 
159     /**
160      * set padding top
161      * @param paddingTop padding top to be set
162      */
setPaddingTop(int paddingTop)163     public void setPaddingTop(int paddingTop) {
164         mPaddingTop = paddingTop;
165     }
166 
167     /**
168      * get padding bottom
169      * @return padding bottom
170      */
getPaddingBottom()171     public int getPaddingBottom() {
172         return mPaddingBottom;
173     }
174 
175     /**
176      * set padding bottom
177      * @param paddingBottom padding bottom to be set
178      */
setPaddingBottom(int paddingBottom)179     public void setPaddingBottom(int paddingBottom) {
180         mPaddingBottom = paddingBottom;
181     }
182 
183     /**
184      * Get all the flags of a Grid
185      * @return an int value containing flag information
186      */
getFlags()187     public int getFlags() {
188         return mFlags;
189     }
190 
191     /**
192      * Set flags of a Grid
193      * @param flags an int value containing flag information
194      */
setFlags(int flags)195     public void setFlags(int flags) {
196         mFlags = flags;
197     }
198 
199     /**
200      * Set flags of a Grid
201      * @param flags a String containing all the flags
202      */
setFlags(@onNull String flags)203     public void setFlags(@NonNull String flags) {
204         if (flags.isEmpty()) {
205             return;
206         }
207 
208         String[] strArr = flags.split("\\|");
209         mFlags = 0;
210         for (String str: strArr) {
211             switch (str.toLowerCase()) {
212                 case SUB_GRID_BY_COL_ROW_STRING:
213                     mFlags |= 1;
214                     break;
215                 case SPANS_RESPECT_WIDGET_ORDER_STRING:
216                     mFlags |= 2;
217                     break;
218             }
219         }
220     }
221 
222     /**
223      * Get the number of rows
224      * @return the number of rows
225      */
getRowsSet()226     public int getRowsSet() {
227         return mRowsSet;
228     }
229 
230     /**
231      * Set the number of rows
232      * @param rowsSet the number of rows
233      */
setRowsSet(int rowsSet)234     public void setRowsSet(int rowsSet) {
235         if (super.getType() == State.Helper.COLUMN) {
236             return;
237         }
238         mRowsSet = rowsSet;
239     }
240 
241     /**
242      * Get the number of columns
243      * @return the number of columns
244      */
getColumnsSet()245     public int getColumnsSet() {
246         return mColumnsSet;
247     }
248 
249     /**
250      * Set the number of columns
251      * @param columnsSet the number of columns
252      */
setColumnsSet(int columnsSet)253     public void setColumnsSet(int columnsSet) {
254         if (super.getType() == State.Helper.ROW) {
255             return;
256         }
257         mColumnsSet = columnsSet;
258     }
259 
260     /**
261      * Get the horizontal gaps
262      * @return the horizontal gaps
263      */
getHorizontalGaps()264     public float getHorizontalGaps() {
265         return mHorizontalGaps;
266     }
267 
268     /**
269      * Set the horizontal gaps
270      * @param horizontalGaps the horizontal gaps
271      */
setHorizontalGaps(float horizontalGaps)272     public void setHorizontalGaps(float horizontalGaps) {
273         mHorizontalGaps = horizontalGaps;
274     }
275 
276     /**
277      * Get the vertical gaps
278      * @return the vertical gaps
279      */
getVerticalGaps()280     public float getVerticalGaps() {
281         return mVerticalGaps;
282     }
283 
284     /**
285      * Set the vertical gaps
286      * @param verticalGaps  the vertical gaps
287      */
setVerticalGaps(float verticalGaps)288     public void setVerticalGaps(float verticalGaps) {
289         mVerticalGaps = verticalGaps;
290     }
291 
292     /**
293      * Get the row weights
294      * @return the row weights
295      */
getRowWeights()296     public @Nullable String getRowWeights() {
297         return mRowWeights;
298     }
299 
300     /**
301      * Set the row weights
302      * @param rowWeights the row weights
303      */
setRowWeights(@onNull String rowWeights)304     public void setRowWeights(@NonNull String rowWeights) {
305         mRowWeights = rowWeights;
306     }
307 
308     /**
309      * Get the column weights
310      * @return the column weights
311      */
getColumnWeights()312     public @Nullable String getColumnWeights() {
313         return mColumnWeights;
314     }
315 
316     /**
317      * Set the column weights
318      * @param columnWeights the column weights
319      */
setColumnWeights(@onNull String columnWeights)320     public void setColumnWeights(@NonNull String columnWeights) {
321         mColumnWeights = columnWeights;
322     }
323 
324     /**
325      * Get the spans
326      * @return the spans
327      */
getSpans()328     public @Nullable String getSpans() {
329         return mSpans;
330     }
331 
332     /**
333      * Set the spans
334      * @param spans the spans
335      */
setSpans(@onNull String spans)336     public void setSpans(@NonNull String spans) {
337         mSpans = spans;
338     }
339 
340     /**
341      * Get the skips
342      * @return the skips
343      */
getSkips()344     public @Nullable String getSkips() {
345         return mSkips;
346     }
347 
348     /**
349      * Set the skips
350      * @param skips the skips
351      */
setSkips(@onNull String skips)352     public void setSkips(@NonNull String skips) {
353         mSkips = skips;
354     }
355 
356     /**
357      * Get the helper widget (Grid)
358      * @return the helper widget (Grid)
359      */
360     @Override
getHelperWidget()361     public @NonNull HelperWidget getHelperWidget() {
362         if (mGrid == null) {
363             mGrid = new GridCore();
364         }
365         return mGrid;
366     }
367 
368     /**
369      * Set the helper widget (Grid)
370      * @param widget the helper widget (Grid)
371      */
372     @Override
setHelperWidget(@ullable HelperWidget widget)373     public void setHelperWidget(@Nullable HelperWidget widget) {
374         if (widget instanceof GridCore) {
375             mGrid = (GridCore) widget;
376         } else {
377             mGrid = null;
378         }
379     }
380 
381     /**
382      * Get the Orientation
383      * @return the Orientation
384      */
getOrientation()385     public int getOrientation() {
386         return mOrientation;
387     }
388 
389     /**
390      * Set the Orientation
391      * @param orientation the Orientation
392      */
setOrientation(int orientation)393     public void setOrientation(int orientation) {
394         mOrientation = orientation;
395 
396     }
397 
398     /**
399      * Apply all the attributes to the helper widget (Grid)
400      */
401     @Override
apply()402     public void apply() {
403         getHelperWidget();
404 
405         mGrid.setOrientation(mOrientation);
406 
407         if (mRowsSet != 0) {
408             mGrid.setRows(mRowsSet);
409         }
410 
411         if (mColumnsSet != 0) {
412             mGrid.setColumns(mColumnsSet);
413         }
414 
415         if (mHorizontalGaps != 0) {
416             mGrid.setHorizontalGaps(mHorizontalGaps);
417         }
418 
419         if (mVerticalGaps != 0) {
420             mGrid.setVerticalGaps(mVerticalGaps);
421         }
422 
423         if (mRowWeights != null && !mRowWeights.isEmpty()) {
424             mGrid.setRowWeights(mRowWeights);
425         }
426 
427         if (mColumnWeights != null && !mColumnWeights.isEmpty()) {
428             mGrid.setColumnWeights(mColumnWeights);
429         }
430 
431         if (mSpans != null && !mSpans.isEmpty()) {
432             mGrid.setSpans(mSpans);
433         }
434 
435         if (mSkips != null && !mSkips.isEmpty()) {
436             mGrid.setSkips(mSkips);
437         }
438 
439         mGrid.setFlags(mFlags);
440 
441         mGrid.setPaddingStart(mPaddingStart);
442         mGrid.setPaddingEnd(mPaddingEnd);
443         mGrid.setPaddingTop(mPaddingTop);
444         mGrid.setPaddingBottom(mPaddingBottom);
445 
446         // General attributes of a widget
447         applyBase();
448     }
449 }