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