1 /*
2 * Copyright (c) 2024 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/interfaces/native/node/node_custom_node_ext_modifier.h"
17
18 #include "base/utils/string_utils.h"
19 #include "core/components/common/properties/color.h"
20 #include "core/components_ng/pattern/custom_node_ext/custom_node_ext_model_ng.h"
21 #include "core/components_ng/property/layout_constraint.h"
22 #include "core/interfaces/arkoala/arkoala_api.h"
23 #include "core/pipeline_ng/pipeline_context.h"
24
25 namespace OHOS::Ace::NG {
26 namespace {
27 constexpr uint32_t STR_MAX_LENGTH = 2048;
28 }
29
ParseColorString(ArkUI_CharPtr colorStr,ArkUI_Uint32 * colorValue)30 ArkUI_Bool ParseColorString(ArkUI_CharPtr colorStr, ArkUI_Uint32* colorValue)
31 {
32 Color color;
33 if (Color::ParseColorString(std::string(colorStr), color)) {
34 *colorValue = color.GetValue();
35 return true;
36 }
37 return false;
38 }
39
ParseLengthString(ArkUI_CharPtr lengthStr,ArkUI_Int32 * unit,ArkUI_Float32 * floatData,ArkUI_CommonCharPtr strData)40 ArkUI_Bool ParseLengthString(ArkUI_CharPtr lengthStr, ArkUI_Int32* unit,
41 ArkUI_Float32* floatData, ArkUI_CommonCharPtr strData)
42 {
43 CalcDimension dimension = StringUtils::StringToCalcDimension(std::string(lengthStr), false, DimensionUnit::VP);
44 if (dimension.Unit() == DimensionUnit::VP || dimension.Unit() == DimensionUnit::FP) {
45 *floatData = dimension.ConvertToPx();
46 *unit = static_cast<ArkUI_Int32>(DimensionUnit::PX);
47 return true;
48 }
49
50 *unit = static_cast<ArkUI_Int32>(dimension.Unit());
51 *floatData = dimension.Value();
52 std::string str = dimension.CalcValue();
53 if (str.length() > STR_MAX_LENGTH) {
54 return false;
55 }
56 str[STR_MAX_LENGTH - 1] = '\0';
57 for (uint32_t index = 0; index < STR_MAX_LENGTH - 1; index++) {
58 strData[index] = str[index];
59 }
60 return true;
61 }
62
GetDpi()63 ArkUI_Float64 GetDpi()
64 {
65 return PipelineBase::GetCurrentDensity();
66 }
67
GetLayoutDirection(ArkUINodeHandle node)68 ArkUI_Int32 GetLayoutDirection(ArkUINodeHandle node)
69 {
70 auto* frameNode = reinterpret_cast<FrameNode*>(node);
71 CHECK_NULL_RETURN(frameNode, 0);
72 auto layoutProperty = frameNode->GetLayoutProperty();
73 CHECK_NULL_RETURN(layoutProperty, 0);
74 auto layoutDirection = layoutProperty->GetNonAutoLayoutDirection();
75 return static_cast<ArkUI_Int32>(layoutDirection);
76 }
77
SetCustomMeasureCallback(ArkUINodeHandle node,void (* setCustomMeasure)(ArkUINodeHandle node,ArkUIConstraintSizeOptions option))78 void SetCustomMeasureCallback(ArkUINodeHandle node,
79 void (*setCustomMeasure)(ArkUINodeHandle node, ArkUIConstraintSizeOptions option))
80 {
81 auto* frameNode = reinterpret_cast<FrameNode*>(node);
82 CHECK_NULL_VOID(frameNode);
83 auto onMeasure = [node, setCustomMeasure](LayoutConstraintF constraints) {
84 ArkUIConstraintSizeOptions options;
85 options.minWidth = constraints.minSize.Width();
86 options.minHeight = constraints.minSize.Height();
87 options.maxWidth = constraints.maxSize.Width();
88 options.maxHeight = constraints.maxSize.Height();
89 setCustomMeasure(node, options);
90 };
91 CustomNodeExtModelNG::SetMeasureCallback(frameNode, std::move(onMeasure));
92 }
93
SetCustomLayoutCallback(ArkUINodeHandle node,void (* setCustomLayout)(ArkUINodeHandle node,ArkUIRect rect))94 void SetCustomLayoutCallback(ArkUINodeHandle node, void (*setCustomLayout)(ArkUINodeHandle node, ArkUIRect rect))
95 {
96 auto* frameNode = reinterpret_cast<FrameNode*>(node);
97 CHECK_NULL_VOID(frameNode);
98 auto onLayout = [node, setCustomLayout](RectF rect) {
99 ArkUIRect rect_;
100 rect_.width = rect.Width();
101 rect_.height = rect.Height();
102 rect_.x = rect.GetX();
103 rect_.y = rect.GetY();
104 setCustomLayout(node, rect_);
105 };
106 CustomNodeExtModelNG::SetLayoutCallback(frameNode, std::move(onLayout));
107 }
108
SetCustomContentDrawCallback(ArkUINodeHandle node,CustomDrawFunc drawFunc)109 void SetCustomContentDrawCallback(ArkUINodeHandle node, CustomDrawFunc drawFunc)
110 {
111 auto* frameNode = reinterpret_cast<FrameNode*>(node);
112 CHECK_NULL_VOID(frameNode);
113 auto onContentDraw = [node, drawFunc](DrawingContext context) {
114 ArkUIDrawingContext drawContext;
115 drawContext.canvas = reinterpret_cast<ArkUICanvasHandle>(&context.canvas);
116 drawContext.width = context.width;
117 drawContext.height = context.height;
118 drawFunc(node, drawContext);
119 };
120 CustomNodeExtModelNG::SetContentDrawCallback(frameNode, std::move(onContentDraw));
121 }
122
SetCustomForegroundDrawCallback(ArkUINodeHandle node,CustomDrawFunc drawFunc)123 void SetCustomForegroundDrawCallback(ArkUINodeHandle node, CustomDrawFunc drawFunc)
124 {
125 auto* frameNode = reinterpret_cast<FrameNode*>(node);
126 CHECK_NULL_VOID(frameNode);
127 auto onForegroundDraw = [node, drawFunc](DrawingContext context) {
128 ArkUIDrawingContext drawContext;
129 drawContext.canvas = reinterpret_cast<ArkUICanvasHandle>(&context.canvas);
130 drawContext.width = context.width;
131 drawContext.height = context.height;
132 drawFunc(node, drawContext);
133 };
134 CustomNodeExtModelNG::SetForegroundDrawCallback(frameNode, std::move(onForegroundDraw));
135 }
136
SetCustomOverlayDrawCallback(ArkUINodeHandle node,CustomDrawFunc drawFunc)137 void SetCustomOverlayDrawCallback(ArkUINodeHandle node, CustomDrawFunc drawFunc)
138 {
139 auto* frameNode = reinterpret_cast<FrameNode*>(node);
140 CHECK_NULL_VOID(frameNode);
141 auto onOverlayDraw = [node, drawFunc](DrawingContext context) {
142 ArkUIDrawingContext drawContext;
143 drawContext.canvas = reinterpret_cast<ArkUICanvasHandle>(&context.canvas);
144 drawContext.width = context.width;
145 drawContext.height = context.height;
146 drawFunc(node, drawContext);
147 };
148 CustomNodeExtModelNG::SetOverlayDrawCallback(frameNode, std::move(onOverlayDraw));
149 }
150
SetOnConfigUpdateCallback(ArkUINodeHandle node,void (* onConfigUpdate)(ArkUINodeHandle node,ArkUIConfigType type))151 void SetOnConfigUpdateCallback(ArkUINodeHandle node,
152 void (*onConfigUpdate)(ArkUINodeHandle node, ArkUIConfigType type))
153 {
154 auto* frameNode = reinterpret_cast<FrameNode*>(node);
155 CHECK_NULL_VOID(frameNode);
156 auto onUpdate = [node, onConfigUpdate](ConfigurationType configType) {
157 ArkUIConfigType type = static_cast<ArkUIConfigType>(configType);
158 onConfigUpdate(node, type);
159 };
160 CustomNodeExtModelNG::SetOnConfigUpdateCallback(frameNode, std::move(onUpdate));
161 }
162
SetOnModifyDoneCallback(ArkUINodeHandle node,void (* onModifyDone)(ArkUINodeHandle node))163 void SetOnModifyDoneCallback(ArkUINodeHandle node, void (*onModifyDone)(ArkUINodeHandle node))
164 {
165 auto* frameNode = reinterpret_cast<FrameNode*>(node);
166 CHECK_NULL_VOID(frameNode);
167 auto onModifyDoneCallback = [node, onModifyDone]() {
168 onModifyDone(node);
169 };
170 CustomNodeExtModelNG::SetOnModifyDoneCallback(frameNode, std::move(onModifyDoneCallback));
171 }
172
SetOnDirtyLayoutWrapperSwap(ArkUINodeHandle node,void (* onDirtySwap)(ArkUINodeHandle node,ArkUIDirtySwapConfig config))173 void SetOnDirtyLayoutWrapperSwap(ArkUINodeHandle node,
174 void (*onDirtySwap)(ArkUINodeHandle node, ArkUIDirtySwapConfig config))
175 {
176 auto* frameNode = reinterpret_cast<FrameNode*>(node);
177 CHECK_NULL_VOID(frameNode);
178 auto onDirtySwapCallback = [node, onDirtySwap](const DirtySwapConfig& config) {
179 ArkUIDirtySwapConfig configuration;
180 configuration.frameSizeChange = config.frameSizeChange;
181 configuration.frameOffsetChange = config.frameOffsetChange;
182 configuration.contentSizeChange = config.contentSizeChange;
183 configuration.contentOffsetChange = config.contentOffsetChange;
184 configuration.skipMeasure = config.skipMeasure;
185 configuration.skipLayout = config.skipLayout;
186 onDirtySwap(node, configuration);
187 };
188 CustomNodeExtModelNG::SetOnDirtyLayoutWrapperSwap(frameNode, std::move(onDirtySwapCallback));
189 }
190
SetIsAtomic(ArkUINodeHandle node,const ArkUI_Bool isAtomic)191 void SetIsAtomic(ArkUINodeHandle node, const ArkUI_Bool isAtomic)
192 {
193 auto* frameNode = reinterpret_cast<FrameNode*>(node);
194 CHECK_NULL_VOID(frameNode);
195 CustomNodeExtModelNG::SetIsAtomic(frameNode, static_cast<bool>(isAtomic));
196 }
197
SetBeforeCreateLayoutWrapperCallback(ArkUINodeHandle node,void (* beforeCreateLayoutWrapper)(ArkUINodeHandle node))198 void SetBeforeCreateLayoutWrapperCallback(ArkUINodeHandle node, void (*beforeCreateLayoutWrapper)(ArkUINodeHandle node))
199 {
200 auto* frameNode = reinterpret_cast<FrameNode*>(node);
201 CHECK_NULL_VOID(frameNode);
202 auto beforeCreateLayoutWrapperCallback = [node, beforeCreateLayoutWrapper]() {
203 beforeCreateLayoutWrapper(node);
204 };
205 CustomNodeExtModelNG::SetBeforeCreateLayoutWrapperCallback(frameNode, std::move(beforeCreateLayoutWrapperCallback));
206 }
207
208 namespace NodeModifier {
GetCustomNodeExtModifier()209 const struct ArkUICustomNodeExtModifier* GetCustomNodeExtModifier()
210 {
211 CHECK_INITIALIZED_FIELDS_BEGIN(); // don't move this line
212 static const struct ArkUICustomNodeExtModifier modifiers = {
213 .parseColorString = ParseColorString,
214 .parseLengthString = ParseLengthString,
215 .getDpi = GetDpi,
216 .getLayoutDirection = GetLayoutDirection,
217 .setCustomMeasure = SetCustomMeasureCallback,
218 .setCustomLayout = SetCustomLayoutCallback,
219 .setCustomContentDraw = SetCustomContentDrawCallback,
220 .setCustomForegroundDraw = SetCustomForegroundDrawCallback,
221 .setCustomOverlayDraw = SetCustomOverlayDrawCallback,
222 .setOnConfigUpdate = SetOnConfigUpdateCallback,
223 .setOnModifyDone = SetOnModifyDoneCallback,
224 .setOnDirtyLayoutWrapperSwap = SetOnDirtyLayoutWrapperSwap,
225 .setIsAtomic = SetIsAtomic,
226 .setBeforeCreateLayoutWrapper = SetBeforeCreateLayoutWrapperCallback
227 };
228 CHECK_INITIALIZED_FIELDS_END(modifiers, 0, 0, 0); // don't move this line
229 return &modifiers;
230 }
231 } // NodeModifier
232 } // OHOS::Ace::NG