1 /*
2  * Copyright (c) 2022 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 "grid_property.h"
17 
18 #include <cstddef>
19 
20 #include "core/components/common/layout/grid_container_info.h"
21 #include "core/components_ng/base/inspector_filter.h"
22 #include "core/components_ng/pattern/grid_container/grid_container_layout_property.h"
23 
24 namespace OHOS::Ace::NG {
25 
GetWidth()26 Dimension GridProperty::GetWidth()
27 {
28     CHECK_NULL_RETURN(gridInfo_, Dimension());
29     // gridInfo_ must exist, because layout algorithm invoke UpdateContainer first
30     return Dimension(gridInfo_->GetWidth());
31 }
32 
GetOffset()33 Dimension GridProperty::GetOffset()
34 {
35     CHECK_NULL_RETURN(gridInfo_, Dimension());
36     // gridInfo_ must exist, because layout algorithm invoke UpdateContainer() first
37     auto offset = gridInfo_->GetOffset();
38     if (offset == UNDEFINED_DIMENSION) {
39         return UNDEFINED_DIMENSION;
40     }
41     auto marginOffset = Dimension(gridInfo_->GetParent()->GetMarginLeft().ConvertToPx());
42     return offset + marginOffset;
43 }
44 
UpdateContainer(const RefPtr<Property> & container,const RefPtr<AceType> & host)45 bool GridProperty::UpdateContainer(const RefPtr<Property>& container, const RefPtr<AceType>& host)
46 {
47     auto currentContainer = DynamicCast<GridContainerLayoutProperty>(container);
48     auto gridContainer = currentContainer->GetReserveObj();
49     GridColumnInfo::Builder builder;
50     auto containerInfo = AceType::MakeRefPtr<GridContainerInfo>(gridContainer->GetContainerInfoValue());
51     builder.SetParent(containerInfo);
52     for (const auto& item : typedPropertySet_) {
53         builder.SetSizeColumn(item.type_, item.span_);
54         builder.SetOffset(item.offset_, item.type_);
55     }
56     gridInfo_ = builder.Build();
57     container_ = container;
58 
59     currentContainer->RegistGridChild(DynamicCast<FrameNode>(host));
60     return true;
61 }
62 
UpdateSpan(int32_t span,GridSizeType type)63 bool GridProperty::UpdateSpan(int32_t span, GridSizeType type)
64 {
65     if (span < 0) {
66         LOGE("Span value is illegal.");
67         return false;
68     }
69     if (!container_) {
70         SetSpan(type, span);
71         return true;
72     }
73 
74     auto container = DynamicCast<GridContainerLayoutProperty>(container_);
75     GridSizeType currentType = container->GetContainerInfo()->GetSizeType(); // working type, not UNDEFINED
76     auto currentProp = GetTypedProperty(type);                               // working property
77 
78     return (currentProp->type_ == type || currentType == type) && SetSpan(type, span);
79 }
80 
UpdateOffset(int32_t offset,GridSizeType type)81 bool GridProperty::UpdateOffset(int32_t offset, GridSizeType type)
82 {
83     if (!container_) {
84         SetOffset(type, offset);
85         return true;
86     }
87     auto container = DynamicCast<GridContainerLayoutProperty>(container_);
88     GridSizeType currentType = container->GetContainerInfo()->GetSizeType(); // working type, not UNDEFINED
89     auto currentProp = GetTypedProperty(type);                               // working property
90 
91     return (currentProp->type_ == type || currentType == type) && SetOffset(type, offset);
92 }
93 
SetSpan(GridSizeType type,int32_t span)94 bool GridProperty::SetSpan(GridSizeType type, int32_t span)
95 {
96     auto item = std::find_if(typedPropertySet_.begin(), typedPropertySet_.end(),
97         [type](const GridTypedProperty& p) { return p.type_ == type; });
98     if (item == typedPropertySet_.end()) {
99         typedPropertySet_.emplace_back(type, span, DEFAULT_GRID_OFFSET);
100         return true;
101     }
102     if (item->span_ == span) {
103         return false;
104     }
105     item->span_ = span;
106     return true;
107 }
108 
SetOffset(GridSizeType type,int32_t offset)109 bool GridProperty::SetOffset(GridSizeType type, int32_t offset)
110 {
111     auto item = std::find_if(typedPropertySet_.begin(), typedPropertySet_.end(),
112         [type](const GridTypedProperty& p) { return p.type_ == type; });
113     if (item == typedPropertySet_.end()) {
114         typedPropertySet_.emplace_back(type, DEFAULT_GRID_SPAN, offset);
115         return true;
116     }
117     if (item->offset_ == offset) {
118         return false;
119     }
120     item->offset_ = offset;
121     return true;
122 }
123 
GetContainerPosition()124 OffsetF GridProperty::GetContainerPosition()
125 {
126     if (container_) {
127         auto container = DynamicCast<GridContainerLayoutProperty>(container_);
128         auto framenode = container->GetHost();
129         CHECK_NULL_RETURN(framenode, OffsetF());
130         return framenode->GetOffsetRelativeToWindow();
131     }
132     return OffsetF();
133 }
134 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const135 void GridProperty::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
136 {
137     const char* GRID_SIZE_TYPE[] = { "default", "sx", "sm", "md", "lg" };
138     /* no fixed attr below, just return */
139     if (filter.IsFastFilter()) {
140         return;
141     }
142     if (!gridInfo_) {
143         auto item = std::find_if(typedPropertySet_.begin(), typedPropertySet_.end(),
144             [](const GridTypedProperty& p) { return p.type_ == GridSizeType::UNDEFINED; });
145         if (item == typedPropertySet_.end()) {
146             json->PutExtAttr("gridSpan", 1, filter);
147             json->PutExtAttr("gridOffset", 0, filter);
148         } else {
149             json->PutExtAttr("gridSpan", item->span_, filter);
150             json->PutExtAttr("gridOffset", item->offset_, filter);
151         }
152 
153         auto useSizeType = JsonUtil::Create(true);
154         for (const auto& item : typedPropertySet_) {
155             auto jsonValue = JsonUtil::Create(true);
156             jsonValue->Put("span", item.span_);
157             jsonValue->Put("offset", item.offset_);
158             useSizeType->Put(GRID_SIZE_TYPE[static_cast<int32_t>(item.type_)], jsonValue);
159         }
160         json->PutExtAttr("useSizeType", useSizeType, filter);
161         return;
162     }
163 
164     auto gridOffset = gridInfo_->GetOffset(GridSizeType::UNDEFINED);
165     json->PutExtAttr("gridSpan", static_cast<int32_t>(gridInfo_->GetColumns()), filter);
166     json->PutExtAttr("gridOffset", gridOffset == -1 ? 0 : gridOffset, filter);
167 
168     auto useSizeType = JsonUtil::Create(true);
169     auto index = static_cast<int32_t>(GridSizeType::XS);
170     for (; index < static_cast<int32_t>(GridSizeType::XL); index++) {
171         auto jsonValue = JsonUtil::Create(true);
172         auto type = static_cast<GridSizeType>(index);
173         jsonValue->Put("span", static_cast<int32_t>(gridInfo_->GetColumns(type)));
174         jsonValue->Put("offset", gridInfo_->GetOffset(type));
175         useSizeType->Put(GRID_SIZE_TYPE[index], jsonValue);
176     }
177     json->PutExtAttr("useSizeType", useSizeType, filter);
178 }
179 
180 } // namespace OHOS::Ace::NG
181