1/*
2 * Copyright (c) 2020-2021 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 "layout/grid_layout.h"
17
18namespace OHOS {
19void GridLayout::LayoutChildren(bool needInvalidate)
20{
21    if (childrenHead_ == nullptr) {
22        return;
23    }
24    UIView* child = childrenHead_;
25    if ((rows_ == 0) || (cols_ == 0)) {
26        RemoveAll();
27        return;
28    }
29    int16_t childrenNum = 0;
30    while (child != nullptr) {
31        childrenNum++;
32        child = child->GetNextSibling();
33    }
34    if (rows_ * cols_ < childrenNum) {
35        RemoveAll();
36        return;
37    }
38
39    if (direction_ == LAYOUT_HOR) {
40        LayoutHorizontal();
41    } else {
42        LayoutVertical();
43    }
44    if (needInvalidate) {
45        Invalidate();
46    }
47}
48
49void GridLayout::LayoutHorizontal()
50{
51    UIView* child = childrenHead_;
52    int16_t left;
53    int16_t right;
54    int16_t top;
55    int16_t bottom;
56    int16_t layoutWidth = GetWidth() / cols_;
57    int16_t layoutHeight = GetHeight() / rows_;
58    int16_t posX;
59    for (int16_t i = 0; i < rows_; i++) {
60        int16_t posY = i * layoutHeight;
61        for (int16_t j = 0; j < cols_; j++) {
62            if (child == nullptr) {
63                return;
64            }
65            posX = j * layoutWidth;
66            child->ReMeasure();
67            left = child->GetStyle(STYLE_MARGIN_LEFT);
68            right = child->GetStyle(STYLE_MARGIN_RIGHT);
69            top = child->GetStyle(STYLE_MARGIN_TOP);
70            bottom = child->GetStyle(STYLE_MARGIN_BOTTOM);
71            // 2: half
72            int16_t actPosX = posX + (layoutWidth - child->GetRelativeRect().GetWidth() - left - right) / 2 + left;
73            // 2: half
74            int16_t actPosY = posY + (layoutHeight - child->GetRelativeRect().GetHeight() - top - bottom) / 2 + top;
75            child->SetPosition(actPosX, actPosY);
76            child->LayoutChildren();
77            child->ResizeVisibleArea(posX, posY, layoutWidth, layoutHeight);
78            child = child->GetNextSibling();
79        }
80    }
81}
82
83void GridLayout::LayoutVertical()
84{
85    UIView* child = childrenHead_;
86    int16_t left;
87    int16_t right;
88    int16_t top;
89    int16_t bottom;
90    int16_t layoutWidth = GetWidth() / cols_;
91    int16_t layoutHeight = GetHeight() / rows_;
92    int16_t posY;
93    for (int16_t i = 0; i < cols_; i++) {
94        int16_t posX = i * layoutWidth;
95        for (int16_t j = 0; j < rows_; j++) {
96            if (child == nullptr) {
97                return;
98            }
99            posY = j * layoutHeight;
100            child->ReMeasure();
101            left = child->GetStyle(STYLE_MARGIN_LEFT);
102            right = child->GetStyle(STYLE_MARGIN_RIGHT);
103            top = child->GetStyle(STYLE_MARGIN_TOP);
104            bottom = child->GetStyle(STYLE_MARGIN_BOTTOM);
105            // 2: half
106            int16_t actPosX = posX + (layoutWidth - child->GetRelativeRect().GetWidth() - left - right) / 2 + left;
107            // 2: half
108            int16_t actPosY = posY + (layoutHeight - child->GetRelativeRect().GetHeight() - top - bottom) / 2 + top;
109            child->SetPosition(actPosX, actPosY);
110            child->LayoutChildren();
111            child->ResizeVisibleArea(posX, posY, layoutWidth, layoutHeight);
112            child = child->GetNextSibling();
113        }
114    }
115}
116} // namespace OHOS
117