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 "core/components_ng/pattern/flex/flex_model_ng.h"
17
18 #include "base/log/log_wrapper.h"
19 #include "base/utils/macros.h"
20 #include "core/components/common/layout/constants.h"
21 #include "core/components_ng/base/frame_node.h"
22 #include "core/components_ng/base/view_stack_processor.h"
23 #include "core/components_ng/pattern/flex/flex_layout_pattern.h"
24 #include "core/components_ng/pattern/flex/flex_layout_property.h"
25 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
26 #include "core/components_ng/property/measure_utils.h"
27 #include "core/components_v2/inspector/inspector_constants.h"
28
29 namespace OHOS::Ace::NG {
30
CreateFlexRow()31 void FlexModelNG::CreateFlexRow()
32 {
33 auto* stack = ViewStackProcessor::GetInstance();
34 auto nodeId = stack->ClaimNodeId();
35 ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::FLEX_ETS_TAG, nodeId);
36 auto childFrameNode = FrameNode::GetFrameNode(V2::FLEX_ETS_TAG, nodeId);
37 if (!childFrameNode) {
38 auto frameNode = FrameNode::GetOrCreateFrameNode(
39 V2::FLEX_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<FlexLayoutPattern>(); });
40 stack->Push(frameNode);
41
42 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, FlexDirection, FlexDirection::ROW);
43 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, MainAxisAlign, FlexAlign::FLEX_START);
44 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, CrossAxisAlign, FlexAlign::FLEX_START);
45 return;
46 }
47 stack->Push(childFrameNode);
48 auto pattern = childFrameNode->GetPattern<FlexLayoutPattern>();
49 if (!pattern->GetIsWrap()) {
50 return;
51 }
52 // wrap to flex
53 pattern->SetIsWrap(false);
54 auto layoutProperty = pattern->GetLayoutProperty<FlexLayoutProperty>();
55 CHECK_NULL_VOID(layoutProperty);
56 layoutProperty->ResetWrapLayoutAttribute();
57 }
58
CreateWrap()59 void FlexModelNG::CreateWrap()
60 {
61 auto* stack = ViewStackProcessor::GetInstance();
62 auto nodeId = stack->ClaimNodeId();
63 ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::FLEX_ETS_TAG, nodeId);
64 auto childFrameNode = FrameNode::GetFrameNode(V2::FLEX_ETS_TAG, nodeId);
65 if (!childFrameNode) {
66 auto frameNode = FrameNode::GetOrCreateFrameNode(
67 V2::FLEX_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<FlexLayoutPattern>(true); });
68 stack->Push(frameNode);
69 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, WrapDirection, WrapDirection::HORIZONTAL);
70 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, Alignment, WrapAlignment::START);
71 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, MainAlignment, WrapAlignment::START);
72 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, CrossAlignment, WrapAlignment::START);
73 return;
74 }
75 stack->Push(childFrameNode);
76 auto pattern = childFrameNode->GetPattern<FlexLayoutPattern>();
77 if (pattern->GetIsWrap()) {
78 return;
79 }
80 // flex to wrap
81 pattern->SetIsWrap(true);
82 auto layoutProperty = childFrameNode->GetLayoutProperty<FlexLayoutProperty>();
83 CHECK_NULL_VOID(layoutProperty);
84 layoutProperty->ResetFlexLayoutAttribute();
85 }
86
CreateFrameNode(int32_t nodeId)87 RefPtr<FrameNode> FlexModelNG::CreateFrameNode(int32_t nodeId)
88 {
89 auto frameNode = FrameNode::CreateFrameNode(
90 V2::FLEX_ETS_TAG, nodeId, AceType::MakeRefPtr<FlexLayoutPattern>());
91 auto pattern = frameNode->GetPattern<FlexLayoutPattern>();
92 auto layoutProperty = frameNode->GetLayoutProperty<FlexLayoutProperty>();
93 layoutProperty->UpdateFlexDirection(FlexDirection::ROW);
94 layoutProperty->UpdateMainAxisAlign(FlexAlign::FLEX_START);
95 layoutProperty->UpdateCrossAxisAlign(FlexAlign::FLEX_START);
96 return frameNode;
97 }
98
SetDirection(FlexDirection direction)99 void FlexModelNG::SetDirection(FlexDirection direction)
100 {
101 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, FlexDirection, direction);
102 }
103
SetWrapDirection(WrapDirection direction)104 void FlexModelNG::SetWrapDirection(WrapDirection direction)
105 {
106 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, WrapDirection, direction);
107 }
108
SetMainAxisAlign(FlexAlign align)109 void FlexModelNG::SetMainAxisAlign(FlexAlign align)
110 {
111 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, MainAxisAlign, align);
112 }
113
SetWrapMainAlignment(WrapAlignment value)114 void FlexModelNG::SetWrapMainAlignment(WrapAlignment value)
115 {
116 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, MainAlignment, value);
117 }
118
SetCrossAxisAlign(FlexAlign align)119 void FlexModelNG::SetCrossAxisAlign(FlexAlign align)
120 {
121 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, CrossAxisAlign, align);
122 }
123
SetWrapCrossAlignment(WrapAlignment value)124 void FlexModelNG::SetWrapCrossAlignment(WrapAlignment value)
125 {
126 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, CrossAlignment, value);
127 }
128
SetWrapAlignment(WrapAlignment value)129 void FlexModelNG::SetWrapAlignment(WrapAlignment value)
130 {
131 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, Alignment, value);
132 }
133
SetAlignItems(int32_t value)134 void FlexModelNG::SetAlignItems(int32_t value)
135 {
136 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
137 CHECK_NULL_VOID(frameNode);
138 auto pattern = frameNode->GetPattern<FlexLayoutPattern>();
139 if (!pattern->GetIsWrap()) {
140 SetCrossAxisAlign(static_cast<FlexAlign>(value));
141 return;
142 }
143 SetWrapCrossAlignment(static_cast<WrapAlignment>(value));
144 }
145
SetJustifyContent(int32_t value)146 void FlexModelNG::SetJustifyContent(int32_t value)
147 {
148 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
149 CHECK_NULL_VOID(frameNode);
150 auto pattern = frameNode->GetPattern<FlexLayoutPattern>();
151 if (!pattern->GetIsWrap()) {
152 SetMainAxisAlign(static_cast<FlexAlign>(value));
153 return;
154 }
155 SetWrapMainAlignment(static_cast<WrapAlignment>(value));
156 }
157
SetAlignContent(int32_t value)158 void FlexModelNG::SetAlignContent(int32_t value)
159 {
160 auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
161 CHECK_NULL_VOID(frameNode);
162 auto pattern = frameNode->GetPattern<FlexLayoutPattern>();
163 if (!pattern->GetIsWrap()) {
164 return;
165 }
166 SetWrapAlignment(static_cast<WrapAlignment>(value));
167 }
168
SetFlexRow(FrameNode * frameNode)169 void FlexModelNG::SetFlexRow(FrameNode* frameNode)
170 {
171 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, FlexDirection, FlexDirection::ROW, frameNode);
172 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, MainAxisAlign, FlexAlign::FLEX_START, frameNode);
173 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, CrossAxisAlign, FlexAlign::FLEX_START, frameNode);
174
175 auto pattern = frameNode->GetPattern<FlexLayoutPattern>();
176 pattern->SetIsWrap(false);
177 }
178
SetFlexWrap(FrameNode * frameNode)179 void FlexModelNG::SetFlexWrap(FrameNode* frameNode)
180 {
181 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, WrapDirection, WrapDirection::HORIZONTAL, frameNode);
182 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, Alignment, WrapAlignment::START, frameNode);
183 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, MainAlignment, WrapAlignment::START, frameNode);
184 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, CrossAlignment, WrapAlignment::START, frameNode);
185
186 auto pattern = frameNode->GetPattern<FlexLayoutPattern>();
187 pattern->SetIsWrap(true);
188 }
189
SetFlexDirection(FrameNode * frameNode,FlexDirection value)190 void FlexModelNG::SetFlexDirection(FrameNode* frameNode, FlexDirection value)
191 {
192 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, FlexDirection, value, frameNode);
193 }
194
SetFlexWrapDirection(FrameNode * frameNode,WrapDirection value)195 void FlexModelNG::SetFlexWrapDirection(FrameNode* frameNode, WrapDirection value)
196 {
197 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, WrapDirection, value, frameNode);
198 }
199
SetFlexJustifyContent(FrameNode * frameNode,int32_t value)200 void FlexModelNG::SetFlexJustifyContent(FrameNode* frameNode, int32_t value)
201 {
202 auto pattern = frameNode->GetPattern<FlexLayoutPattern>();
203 if (!pattern->GetIsWrap()) {
204 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, MainAxisAlign, static_cast<FlexAlign>(value), frameNode);
205 return;
206 }
207 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, MainAlignment, static_cast<WrapAlignment>(value), frameNode);
208 }
209
SetFlexAlignItems(FrameNode * frameNode,int32_t value)210 void FlexModelNG::SetFlexAlignItems(FrameNode* frameNode, int32_t value)
211 {
212 auto pattern = frameNode->GetPattern<FlexLayoutPattern>();
213 if (!pattern->GetIsWrap()) {
214 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, CrossAxisAlign, static_cast<FlexAlign>(value), frameNode);
215 return;
216 }
217 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, CrossAlignment, static_cast<WrapAlignment>(value), frameNode);
218 }
219
SetFlexAlignContent(FrameNode * frameNode,int32_t value)220 void FlexModelNG::SetFlexAlignContent(FrameNode* frameNode, int32_t value)
221 {
222 auto pattern = frameNode->GetPattern<FlexLayoutPattern>();
223 if (!pattern->GetIsWrap()) {
224 return;
225 }
226 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, Alignment, static_cast<WrapAlignment>(value), frameNode);
227 }
228
GetFlexWrap(FrameNode * frameNode)229 int FlexModelNG::GetFlexWrap(FrameNode* frameNode)
230 {
231 int value = 0;
232 auto pattern = frameNode->GetPattern<FlexLayoutPattern>();
233 if (!pattern->GetIsWrap()) {
234 value = static_cast<int>(FlexWrap::NO_WRAP);
235 } else {
236 WrapDirection direction = WrapDirection::HORIZONTAL;
237 ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(
238 FlexLayoutProperty, WrapDirection, direction, frameNode, direction);
239 int intDirection = static_cast<int>(direction);
240 if (intDirection == 0 || intDirection == 1) {
241 value = static_cast<int>(FlexWrap::WRAP);
242 } else {
243 value = static_cast<int>(FlexWrap::WRAP_REVERSE);
244 }
245 }
246 return value;
247 }
248
GetFlexDirection(FrameNode * frameNode)249 int FlexModelNG::GetFlexDirection(FrameNode* frameNode)
250 {
251 FlexDirection value = FlexDirection::ROW;
252 ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(FlexLayoutProperty, FlexDirection, value, frameNode, value);
253 return static_cast<int>(value);
254 }
255
GetFlexJustifyContent(FrameNode * frameNode)256 int FlexModelNG::GetFlexJustifyContent(FrameNode* frameNode)
257 {
258 auto pattern = frameNode->GetPattern<FlexLayoutPattern>();
259 if (!pattern->GetIsWrap()) {
260 FlexAlign value = FlexAlign::AUTO;
261 ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(FlexLayoutProperty, MainAxisAlign, value, frameNode, value);
262 return static_cast<int>(value);
263 }
264 WrapAlignment value = WrapAlignment::START;
265 ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(FlexLayoutProperty, MainAlignment, value, frameNode, value);
266 return static_cast<int>(value);
267 }
268
GetFlexAlignItems(FrameNode * frameNode)269 int FlexModelNG::GetFlexAlignItems(FrameNode* frameNode)
270 {
271 auto pattern = frameNode->GetPattern<FlexLayoutPattern>();
272 if (!pattern->GetIsWrap()) {
273 FlexAlign value = FlexAlign::AUTO;
274 ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(FlexLayoutProperty, CrossAxisAlign, value, frameNode, value);
275 return static_cast<int>(value);
276 }
277 WrapAlignment value = WrapAlignment::START;
278 ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(FlexLayoutProperty, CrossAlignment, value, frameNode, value);
279 return static_cast<int>(value);
280 }
281
GetFlexAlignContent(FrameNode * frameNode)282 int FlexModelNG::GetFlexAlignContent(FrameNode* frameNode)
283 {
284 auto pattern = frameNode->GetPattern<FlexLayoutPattern>();
285 if (!pattern->GetIsWrap()) {
286 return 0;
287 }
288 WrapAlignment value = WrapAlignment::START;
289 ACE_GET_NODE_LAYOUT_PROPERTY_WITH_DEFAULT_VALUE(FlexLayoutProperty, Alignment, value, frameNode, value);
290 return static_cast<int>(value);
291 }
292
SetMainSpace(const std::optional<Dimension> & space)293 void FlexModelNG::SetMainSpace(const std::optional<Dimension>& space)
294 {
295 CHECK_NULL_VOID(space);
296 if (GreatOrEqual(space->Value(), 0.0)) {
297 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, Space, space.value());
298 }
299 }
300
SetCrossSpace(const std::optional<Dimension> & space)301 void FlexModelNG::SetCrossSpace(const std::optional<Dimension>& space)
302 {
303 CHECK_NULL_VOID(space);
304 if (GreatOrEqual(space->Value(), 0.0)) {
305 ACE_UPDATE_LAYOUT_PROPERTY(FlexLayoutProperty, CrossSpace, space.value());
306 }
307 }
308
SetMainSpace(FrameNode * frameNode,const std::optional<Dimension> & space)309 void FlexModelNG::SetMainSpace(FrameNode* frameNode, const std::optional<Dimension>& space)
310 {
311 CHECK_NULL_VOID(space);
312 if (GreatOrEqual(space->Value(), 0.0)) {
313 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, Space, space.value(), frameNode);
314 }
315 }
316
SetCrossSpace(FrameNode * frameNode,const std::optional<Dimension> & space)317 void FlexModelNG::SetCrossSpace(FrameNode* frameNode, const std::optional<Dimension>& space)
318 {
319 CHECK_NULL_VOID(space);
320 if (GreatOrEqual(space->Value(), 0.0)) {
321 ACE_UPDATE_NODE_LAYOUT_PROPERTY(FlexLayoutProperty, CrossSpace, space.value(), frameNode);
322 }
323 }
324 } // namespace OHOS::Ace::NG
325