1a3e0fd82Sopenharmony_ci/*
2a3e0fd82Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3a3e0fd82Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4a3e0fd82Sopenharmony_ci * you may not use this file except in compliance with the License.
5a3e0fd82Sopenharmony_ci * You may obtain a copy of the License at
6a3e0fd82Sopenharmony_ci *
7a3e0fd82Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8a3e0fd82Sopenharmony_ci *
9a3e0fd82Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10a3e0fd82Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11a3e0fd82Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a3e0fd82Sopenharmony_ci * See the License for the specific language governing permissions and
13a3e0fd82Sopenharmony_ci * limitations under the License.
14a3e0fd82Sopenharmony_ci */
15a3e0fd82Sopenharmony_ci
16a3e0fd82Sopenharmony_ci#include "layout/grid_layout.h"
17a3e0fd82Sopenharmony_ci
18a3e0fd82Sopenharmony_cinamespace OHOS {
19a3e0fd82Sopenharmony_civoid GridLayout::LayoutChildren(bool needInvalidate)
20a3e0fd82Sopenharmony_ci{
21a3e0fd82Sopenharmony_ci    if (childrenHead_ == nullptr) {
22a3e0fd82Sopenharmony_ci        return;
23a3e0fd82Sopenharmony_ci    }
24a3e0fd82Sopenharmony_ci    UIView* child = childrenHead_;
25a3e0fd82Sopenharmony_ci    if ((rows_ == 0) || (cols_ == 0)) {
26a3e0fd82Sopenharmony_ci        RemoveAll();
27a3e0fd82Sopenharmony_ci        return;
28a3e0fd82Sopenharmony_ci    }
29a3e0fd82Sopenharmony_ci    int16_t childrenNum = 0;
30a3e0fd82Sopenharmony_ci    while (child != nullptr) {
31a3e0fd82Sopenharmony_ci        childrenNum++;
32a3e0fd82Sopenharmony_ci        child = child->GetNextSibling();
33a3e0fd82Sopenharmony_ci    }
34a3e0fd82Sopenharmony_ci    if (rows_ * cols_ < childrenNum) {
35a3e0fd82Sopenharmony_ci        RemoveAll();
36a3e0fd82Sopenharmony_ci        return;
37a3e0fd82Sopenharmony_ci    }
38a3e0fd82Sopenharmony_ci
39a3e0fd82Sopenharmony_ci    if (direction_ == LAYOUT_HOR) {
40a3e0fd82Sopenharmony_ci        LayoutHorizontal();
41a3e0fd82Sopenharmony_ci    } else {
42a3e0fd82Sopenharmony_ci        LayoutVertical();
43a3e0fd82Sopenharmony_ci    }
44a3e0fd82Sopenharmony_ci    if (needInvalidate) {
45a3e0fd82Sopenharmony_ci        Invalidate();
46a3e0fd82Sopenharmony_ci    }
47a3e0fd82Sopenharmony_ci}
48a3e0fd82Sopenharmony_ci
49a3e0fd82Sopenharmony_civoid GridLayout::LayoutHorizontal()
50a3e0fd82Sopenharmony_ci{
51a3e0fd82Sopenharmony_ci    UIView* child = childrenHead_;
52a3e0fd82Sopenharmony_ci    int16_t left;
53a3e0fd82Sopenharmony_ci    int16_t right;
54a3e0fd82Sopenharmony_ci    int16_t top;
55a3e0fd82Sopenharmony_ci    int16_t bottom;
56a3e0fd82Sopenharmony_ci    int16_t layoutWidth = GetWidth() / cols_;
57a3e0fd82Sopenharmony_ci    int16_t layoutHeight = GetHeight() / rows_;
58a3e0fd82Sopenharmony_ci    int16_t posX;
59a3e0fd82Sopenharmony_ci    for (int16_t i = 0; i < rows_; i++) {
60a3e0fd82Sopenharmony_ci        int16_t posY = i * layoutHeight;
61a3e0fd82Sopenharmony_ci        for (int16_t j = 0; j < cols_; j++) {
62a3e0fd82Sopenharmony_ci            if (child == nullptr) {
63a3e0fd82Sopenharmony_ci                return;
64a3e0fd82Sopenharmony_ci            }
65a3e0fd82Sopenharmony_ci            posX = j * layoutWidth;
66a3e0fd82Sopenharmony_ci            child->ReMeasure();
67a3e0fd82Sopenharmony_ci            left = child->GetStyle(STYLE_MARGIN_LEFT);
68a3e0fd82Sopenharmony_ci            right = child->GetStyle(STYLE_MARGIN_RIGHT);
69a3e0fd82Sopenharmony_ci            top = child->GetStyle(STYLE_MARGIN_TOP);
70a3e0fd82Sopenharmony_ci            bottom = child->GetStyle(STYLE_MARGIN_BOTTOM);
71a3e0fd82Sopenharmony_ci            // 2: half
72a3e0fd82Sopenharmony_ci            int16_t actPosX = posX + (layoutWidth - child->GetRelativeRect().GetWidth() - left - right) / 2 + left;
73a3e0fd82Sopenharmony_ci            // 2: half
74a3e0fd82Sopenharmony_ci            int16_t actPosY = posY + (layoutHeight - child->GetRelativeRect().GetHeight() - top - bottom) / 2 + top;
75a3e0fd82Sopenharmony_ci            child->SetPosition(actPosX, actPosY);
76a3e0fd82Sopenharmony_ci            child->LayoutChildren();
77a3e0fd82Sopenharmony_ci            child->ResizeVisibleArea(posX, posY, layoutWidth, layoutHeight);
78a3e0fd82Sopenharmony_ci            child = child->GetNextSibling();
79a3e0fd82Sopenharmony_ci        }
80a3e0fd82Sopenharmony_ci    }
81a3e0fd82Sopenharmony_ci}
82a3e0fd82Sopenharmony_ci
83a3e0fd82Sopenharmony_civoid GridLayout::LayoutVertical()
84a3e0fd82Sopenharmony_ci{
85a3e0fd82Sopenharmony_ci    UIView* child = childrenHead_;
86a3e0fd82Sopenharmony_ci    int16_t left;
87a3e0fd82Sopenharmony_ci    int16_t right;
88a3e0fd82Sopenharmony_ci    int16_t top;
89a3e0fd82Sopenharmony_ci    int16_t bottom;
90a3e0fd82Sopenharmony_ci    int16_t layoutWidth = GetWidth() / cols_;
91a3e0fd82Sopenharmony_ci    int16_t layoutHeight = GetHeight() / rows_;
92a3e0fd82Sopenharmony_ci    int16_t posY;
93a3e0fd82Sopenharmony_ci    for (int16_t i = 0; i < cols_; i++) {
94a3e0fd82Sopenharmony_ci        int16_t posX = i * layoutWidth;
95a3e0fd82Sopenharmony_ci        for (int16_t j = 0; j < rows_; j++) {
96a3e0fd82Sopenharmony_ci            if (child == nullptr) {
97a3e0fd82Sopenharmony_ci                return;
98a3e0fd82Sopenharmony_ci            }
99a3e0fd82Sopenharmony_ci            posY = j * layoutHeight;
100a3e0fd82Sopenharmony_ci            child->ReMeasure();
101a3e0fd82Sopenharmony_ci            left = child->GetStyle(STYLE_MARGIN_LEFT);
102a3e0fd82Sopenharmony_ci            right = child->GetStyle(STYLE_MARGIN_RIGHT);
103a3e0fd82Sopenharmony_ci            top = child->GetStyle(STYLE_MARGIN_TOP);
104a3e0fd82Sopenharmony_ci            bottom = child->GetStyle(STYLE_MARGIN_BOTTOM);
105a3e0fd82Sopenharmony_ci            // 2: half
106a3e0fd82Sopenharmony_ci            int16_t actPosX = posX + (layoutWidth - child->GetRelativeRect().GetWidth() - left - right) / 2 + left;
107a3e0fd82Sopenharmony_ci            // 2: half
108a3e0fd82Sopenharmony_ci            int16_t actPosY = posY + (layoutHeight - child->GetRelativeRect().GetHeight() - top - bottom) / 2 + top;
109a3e0fd82Sopenharmony_ci            child->SetPosition(actPosX, actPosY);
110a3e0fd82Sopenharmony_ci            child->LayoutChildren();
111a3e0fd82Sopenharmony_ci            child->ResizeVisibleArea(posX, posY, layoutWidth, layoutHeight);
112a3e0fd82Sopenharmony_ci            child = child->GetNextSibling();
113a3e0fd82Sopenharmony_ci        }
114a3e0fd82Sopenharmony_ci    }
115a3e0fd82Sopenharmony_ci}
116a3e0fd82Sopenharmony_ci} // namespace OHOS
117