1 /*
2 * Copyright (c) 2023 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 #include "core/interfaces/native/node/flex_modifier.h"
16
17 #include "base/utils/utils.h"
18 #include "core/components/common/layout/constants.h"
19 #include "core/components/common/properties/alignment.h"
20 #include "core/components_ng/base/frame_node.h"
21 #include "core/components_ng/base/view_abstract.h"
22 #include "core/components_ng/pattern/flex/flex_model_ng.h"
23 #include "core/pipeline/base/element_register.h"
24 #include "frameworks/core/components/common/layout/constants.h"
25
26 namespace OHOS::Ace::NG {
27 constexpr int NUM_0 = 0;
28 constexpr int NUM_1 = 1;
29 constexpr int NUM_2 = 2;
30 constexpr int NUM_3 = 3;
31 constexpr int NUM_4 = 4;
32 constexpr int NUM_5 = 5;
33 constexpr int NUM_6 = 6;
34 constexpr int NUM_7 = 7;
35
ParseFlexToWrap(int align)36 int ParseFlexToWrap(int align)
37 {
38 FlexAlign alignment = FlexAlign::AUTO;
39 switch (align) {
40 case NUM_0: //WrapAlignment::START
41 alignment = FlexAlign::FLEX_START;
42 break;
43 case NUM_1: //WrapAlignment::CENTER
44 alignment = FlexAlign::CENTER;
45 break;
46 case NUM_2: //WrapAlignment::END
47 alignment = FlexAlign::FLEX_END;
48 break;
49 case NUM_3: //WrapAlignment::SPACE_AROUND
50 alignment = FlexAlign::SPACE_AROUND;
51 break;
52 case NUM_4: //WrapAlignment::SPACE_BETWEEN
53 alignment = FlexAlign::SPACE_BETWEEN;
54 break;
55 case NUM_5: //WrapAlignment::STRETCH
56 alignment = FlexAlign::STRETCH;
57 break;
58 case NUM_6: //WrapAlignment::SPACE_EVENLY
59 alignment = FlexAlign::SPACE_EVENLY;
60 break;
61 case NUM_7: //WrapAlignment::BASELINE
62 alignment = FlexAlign::BASELINE;
63 break;
64 default:
65 break;
66 }
67 return static_cast<int32_t>(alignment);
68 }
69
SetFlexOptions(ArkUINodeHandle node,int * options,int length)70 void SetFlexOptions(ArkUINodeHandle node, int* options, int length)
71 {
72 auto* frameNode = reinterpret_cast<FrameNode*>(node);
73 CHECK_NULL_VOID(frameNode);
74 CHECK_NULL_VOID(options);
75 int direction = options[NUM_0];
76 int wrap = options[NUM_1];
77 int justifyContent = options[NUM_2];
78 int alignItems = options[NUM_3];
79 int alignContent = options[NUM_4];
80 if (wrap <= 0) {
81 FlexModelNG::SetFlexRow(frameNode);
82 if (direction >= 0 && direction <= DIRECTION_MAX_VALUE) {
83 FlexModelNG::SetFlexDirection(frameNode, static_cast<OHOS::Ace::FlexDirection>(direction));
84 }
85
86 if (justifyContent >= 0 && justifyContent <= MAIN_ALIGN_MAX_VALUE) {
87 FlexModelNG::SetFlexJustifyContent(frameNode, justifyContent);
88 }
89
90 if (alignItems >= 0 && alignItems <= CROSS_ALIGN_MAX_VALUE) {
91 FlexModelNG::SetFlexAlignItems(frameNode, alignItems);
92 }
93 } else if (wrap > 0) {
94 FlexModelNG::SetFlexWrap(frameNode);
95 if (direction >= 0 && direction <= DIRECTION_MAX_VALUE) {
96 FlexModelNG::SetFlexDirection(frameNode, static_cast<OHOS::Ace::FlexDirection>(direction));
97 // WrapReverse means wrapVal = 2. Wrap means wrapVal = 1.
98 direction <= 1 ? direction += NUM_2 * (wrap - NUM_1) : direction -= NUM_2 * (wrap - NUM_1);
99 FlexModelNG::SetFlexWrapDirection(frameNode, static_cast<WrapDirection>(direction));
100 } else {
101 // No direction set case: wrapVal == 2 means FlexWrap.WrapReverse.
102 WrapDirection wrapDirection = wrap == NUM_2 ? WrapDirection::HORIZONTAL_REVERSE : WrapDirection::HORIZONTAL;
103 FlexModelNG::SetFlexWrapDirection(frameNode, wrapDirection);
104 }
105
106 if (justifyContent >= 0 && justifyContent <= MAIN_ALIGN_MAX_VALUE) {
107 FlexModelNG::SetFlexJustifyContent(frameNode, static_cast<int>(WRAP_TABLE[justifyContent]));
108 }
109
110 if (alignItems >= 0 && alignItems <= CROSS_ALIGN_MAX_VALUE) {
111 FlexModelNG::SetFlexAlignItems(frameNode, static_cast<int>(WRAP_TABLE[alignItems]));
112 }
113
114 if (alignContent >= 0 && alignContent <= MAIN_ALIGN_MAX_VALUE) {
115 FlexModelNG::SetFlexAlignContent(frameNode, static_cast<int>(WRAP_TABLE[alignContent]));
116 }
117 }
118 }
119
ResetFlexOptions(ArkUINodeHandle node)120 void ResetFlexOptions(ArkUINodeHandle node)
121 {
122 auto* frameNode = reinterpret_cast<FrameNode*>(node);
123 CHECK_NULL_VOID(frameNode);
124 FlexModelNG::SetFlexRow(frameNode);
125 FlexModelNG::SetFlexDirection(frameNode, OHOS::Ace::FlexDirection::ROW);
126 FlexModelNG::SetFlexJustifyContent(frameNode, NUM_1);
127 FlexModelNG::SetFlexAlignItems(frameNode, NUM_1);
128 FlexModelNG::SetFlexAlignContent(frameNode, NUM_1);
129 }
130
GetFlexOptions(ArkUINodeHandle node,ArkUIFlexOptions * options)131 void GetFlexOptions(ArkUINodeHandle node, ArkUIFlexOptions* options)
132 {
133 auto* frameNode = reinterpret_cast<FrameNode*>(node);
134 CHECK_NULL_VOID(frameNode);
135 options->direction = FlexModelNG::GetFlexDirection(frameNode);
136 options->wrap = FlexModelNG::GetFlexWrap(frameNode);
137 if (FlexModelNG::GetFlexWrap(frameNode) <= 0) {
138 options->justifyContent = FlexModelNG::GetFlexJustifyContent(frameNode);
139 options->alignItems = FlexModelNG::GetFlexAlignItems(frameNode);
140 options->alignContent = FlexModelNG::GetFlexAlignContent(frameNode);
141 } else {
142 options->justifyContent = ParseFlexToWrap(FlexModelNG::GetFlexJustifyContent(frameNode));
143 options->alignItems = ParseFlexToWrap(FlexModelNG::GetFlexAlignItems(frameNode));
144 options->alignContent = ParseFlexToWrap(FlexModelNG::GetFlexAlignContent(frameNode));
145 }
146 }
147
setFlexCrossSpace(ArkUINodeHandle node,ArkUI_Float32 value,ArkUI_Int32 unit)148 void setFlexCrossSpace(ArkUINodeHandle node, ArkUI_Float32 value, ArkUI_Int32 unit)
149 {
150 auto* frameNode = reinterpret_cast<FrameNode*>(node);
151 CHECK_NULL_VOID(frameNode);
152 FlexModelNG::SetCrossSpace(frameNode, CalcDimension(value, (DimensionUnit)unit));
153 }
154
SetMainSpace(ArkUINodeHandle node,ArkUI_Float32 value,ArkUI_Int32 unit)155 void SetMainSpace(ArkUINodeHandle node, ArkUI_Float32 value, ArkUI_Int32 unit)
156 {
157 auto* frameNode = reinterpret_cast<FrameNode*>(node);
158 CHECK_NULL_VOID(frameNode);
159 FlexModelNG::SetMainSpace(frameNode, CalcDimension(value, (DimensionUnit)unit));
160 }
161
162 namespace NodeModifier {
GetFlexModifier()163 const ArkUIFlexModifier* GetFlexModifier()
164 {
165 static const ArkUIFlexModifier modifier = { SetFlexOptions, ResetFlexOptions, GetFlexOptions, setFlexCrossSpace,
166 SetMainSpace };
167 return &modifier;
168 }
169
GetCJUIFlexModifier()170 const CJUIFlexModifier* GetCJUIFlexModifier()
171 {
172 static const CJUIFlexModifier modifier = {
173 SetFlexOptions, ResetFlexOptions, GetFlexOptions, setFlexCrossSpace, SetMainSpace
174 };
175 return &modifier;
176 }
177 }
178 }
179