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 #include "core/interfaces/native/node/custom_dialog_model.h"
16
17 #include "interfaces/native/node/dialog_model.h"
18
19 #include "base/error/error_code.h"
20 #include "core/components_ng/pattern/dialog/custom_dialog_controller_model_ng.h"
21
22 namespace OHOS::Ace::NG::CustomDialog {
23 namespace {
24 constexpr int32_t DEFAULT_DIALOG_ALIGNMENT = -1;
25 constexpr uint32_t DEFAULT_MASK_COLOR = 0x33000000;
26 constexpr uint32_t DEFAULT_DIALOG_BACKGROUND_COLOR = 0x00000000;
27 constexpr int32_t ARKUI_ALIGNMENT_TOP_START_INDEX = 0;
28 constexpr int32_t ARKUI_ALIGNMENT_TOP_INDEX = 1;
29 constexpr int32_t ARKUI_ALIGNMENT_TOP_END_INDEX = 2;
30 constexpr int32_t ARKUI_ALIGNMENT_START_INDEX = 3;
31 constexpr int32_t ARKUI_ALIGNMENT_CENTER_INDEX = 4;
32 constexpr int32_t ARKUI_ALIGNMENT_END_INDEX = 5;
33 constexpr int32_t ARKUI_ALIGNMENT_BOTTOM_START_INDEX = 6;
34 constexpr int32_t ARKUI_ALIGNMENT_BOTTOM_INDEX = 7;
35 constexpr int32_t ARKUI_ALIGNMENT_BOTTOM_END_INDEX = 8;
36 } // namespace
37
CreateDialog()38 ArkUIDialogHandle CreateDialog()
39 {
40 return new _ArkUIDialog({ .dialogHandle = nullptr,
41 .contentHandle = nullptr,
42 .alignment = DEFAULT_DIALOG_ALIGNMENT,
43 .offsetX = 0.0f,
44 .offsetY = 0.0f,
45 .isModal = true,
46 .autoCancel = true,
47 .maskColor = DEFAULT_MASK_COLOR,
48 .maskRect = nullptr,
49 .backgroundColor = DEFAULT_DIALOG_BACKGROUND_COLOR,
50 .cornerRadiusRect = nullptr,
51 .gridCount = -1,
52 .enableCustomStyle = false,
53 .showInSubWindow = false,
54 .enableCustomAnimation = false,
55 .onWillDismissCall = nullptr,
56 .onWillDismissCallByNDK = nullptr,
57 .userData = nullptr });
58 }
59
DisposeDialog(ArkUIDialogHandle controllerHandler)60 void DisposeDialog(ArkUIDialogHandle controllerHandler)
61 {
62 CHECK_NULL_VOID(controllerHandler);
63 auto* dialog = reinterpret_cast<FrameNode*>(controllerHandler->dialogHandle);
64 if (dialog) {
65 dialog->DecRefCount();
66 }
67 controllerHandler->dialogHandle = nullptr;
68 auto* content = reinterpret_cast<FrameNode*>(controllerHandler->contentHandle);
69 if (content) {
70 content->DecRefCount();
71 }
72 controllerHandler->contentHandle = nullptr;
73 auto* maskRect = controllerHandler->maskRect;
74 if (maskRect) {
75 delete maskRect;
76 }
77 auto* cornerRadiusRect = controllerHandler->cornerRadiusRect;
78 if (cornerRadiusRect) {
79 delete cornerRadiusRect;
80 }
81 controllerHandler->onWillDismissCall = nullptr;
82 controllerHandler->onWillDismissCallByNDK = nullptr;
83 controllerHandler->userData = nullptr;
84 delete controllerHandler;
85 }
86
GetDialogAlignment(int32_t alignment)87 DialogAlignment GetDialogAlignment(int32_t alignment)
88 {
89 switch (alignment) {
90 case ARKUI_ALIGNMENT_TOP_START_INDEX:
91 return DialogAlignment::TOP_START;
92 case ARKUI_ALIGNMENT_TOP_INDEX:
93 return DialogAlignment::TOP;
94 case ARKUI_ALIGNMENT_TOP_END_INDEX:
95 return DialogAlignment::TOP_END;
96 case ARKUI_ALIGNMENT_START_INDEX:
97 return DialogAlignment::CENTER_START;
98 case ARKUI_ALIGNMENT_CENTER_INDEX:
99 return DialogAlignment::CENTER;
100 case ARKUI_ALIGNMENT_END_INDEX:
101 return DialogAlignment::CENTER_END;
102 case ARKUI_ALIGNMENT_BOTTOM_START_INDEX:
103 return DialogAlignment::BOTTOM_START;
104 case ARKUI_ALIGNMENT_BOTTOM_INDEX:
105 return DialogAlignment::BOTTOM;
106 case ARKUI_ALIGNMENT_BOTTOM_END_INDEX:
107 return DialogAlignment::BOTTOM_END;
108 default:
109 break;
110 }
111 return DialogAlignment::DEFAULT;
112 }
113
ParseDialogMask(DialogProperties & dialogProperties,ArkUIDialogHandle controllerHandler)114 void ParseDialogMask(DialogProperties& dialogProperties, ArkUIDialogHandle controllerHandler)
115 {
116 CHECK_NULL_VOID(controllerHandler);
117 dialogProperties.maskColor = Color(controllerHandler->maskColor);
118 if (!controllerHandler->maskRect) {
119 return;
120 }
121 DimensionRect maskRect;
122 maskRect.SetOffset(DimensionOffset(Dimension(controllerHandler->maskRect->x, DimensionUnit::VP),
123 Dimension(controllerHandler->maskRect->y, DimensionUnit::VP)));
124 maskRect.SetSize(DimensionSize(Dimension(controllerHandler->maskRect->width, DimensionUnit::VP),
125 Dimension(controllerHandler->maskRect->height, DimensionUnit::VP)));
126 dialogProperties.maskRect = maskRect;
127 }
128
ParseDialogCornerRadiusRect(DialogProperties & dialogProperties,ArkUIDialogHandle controllerHandler)129 void ParseDialogCornerRadiusRect(DialogProperties& dialogProperties, ArkUIDialogHandle controllerHandler)
130 {
131 CHECK_NULL_VOID(controllerHandler);
132 if (!controllerHandler->cornerRadiusRect) {
133 return;
134 }
135 NG::BorderRadiusProperty radius;
136 radius.radiusTopLeft = Dimension(controllerHandler->cornerRadiusRect->topLeft, DimensionUnit::VP);
137 radius.radiusTopRight = Dimension(controllerHandler->cornerRadiusRect->topRight, DimensionUnit::VP);
138 radius.radiusBottomLeft = Dimension(controllerHandler->cornerRadiusRect->bottomLeft, DimensionUnit::VP);
139 radius.radiusBottomRight = Dimension(controllerHandler->cornerRadiusRect->bottomRight, DimensionUnit::VP);
140 radius.multiValued = true;
141 dialogProperties.borderRadius = radius;
142 }
143
ParseDialogProperties(DialogProperties & dialogProperties,ArkUIDialogHandle controllerHandler)144 void ParseDialogProperties(DialogProperties& dialogProperties, ArkUIDialogHandle controllerHandler)
145 {
146 CHECK_NULL_VOID(controllerHandler);
147 dialogProperties.autoCancel = controllerHandler->autoCancel;
148 dialogProperties.alignment = GetDialogAlignment(controllerHandler->alignment);
149 dialogProperties.offset = DimensionOffset(Dimension(controllerHandler->offsetX, DimensionUnit::VP),
150 Dimension(controllerHandler->offsetY, DimensionUnit::VP));
151 dialogProperties.isShowInSubWindow = controllerHandler->showInSubWindow;
152 dialogProperties.isModal = controllerHandler->isModal;
153 dialogProperties.backgroundColor = Color(controllerHandler->backgroundColor);
154 dialogProperties.customStyle = controllerHandler->enableCustomStyle;
155 dialogProperties.gridCount = controllerHandler->gridCount;
156 ParseDialogMask(dialogProperties, controllerHandler);
157 ParseDialogCornerRadiusRect(dialogProperties, controllerHandler);
158 if (controllerHandler->onWillDismissCall) {
159 dialogProperties.onWillDismiss = [controllerHandler](int32_t reason) {
160 CHECK_NULL_VOID(controllerHandler);
161 CHECK_NULL_VOID(controllerHandler->onWillDismissCall);
162 (*(controllerHandler->onWillDismissCall))(reason);
163 };
164 }
165
166 if (controllerHandler->onWillDismissCallByNDK) {
167 dialogProperties.onWillDismissCallByNDK = [controllerHandler](int32_t reason) {
168 ArkUI_DialogDismissEvent event = { controllerHandler->userData, reason, false };
169 controllerHandler->onWillDismissCallByNDK(&event);
170 return event.BlockDismiss;
171 };
172 }
173
174 if (controllerHandler->enableCustomAnimation && !dialogProperties.openAnimation.has_value()) {
175 AnimationOption animation;
176 dialogProperties.openAnimation = animation;
177 }
178 if (controllerHandler->enableCustomAnimation && !dialogProperties.closeAnimation.has_value()) {
179 AnimationOption animation;
180 dialogProperties.closeAnimation = animation;
181 }
182 }
183
SetDialogContent(ArkUIDialogHandle controllerHandler,ArkUINodeHandle contentNode)184 ArkUI_Int32 SetDialogContent(ArkUIDialogHandle controllerHandler, ArkUINodeHandle contentNode)
185 {
186 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
187 CHECK_NULL_RETURN(contentNode, ERROR_CODE_PARAM_INVALID);
188 auto* frameNode = reinterpret_cast<FrameNode*>(contentNode);
189 CHECK_NULL_RETURN(frameNode, ERROR_CODE_PARAM_INVALID);
190 frameNode->IncRefCount();
191 controllerHandler->contentHandle = frameNode;
192 return ERROR_CODE_NO_ERROR;
193 }
194
RemoveDialogContent(ArkUIDialogHandle controllerHandler)195 ArkUI_Int32 RemoveDialogContent(ArkUIDialogHandle controllerHandler)
196 {
197 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
198 if (controllerHandler->contentHandle) {
199 auto* frameNode = reinterpret_cast<FrameNode*>(controllerHandler->contentHandle);
200 CHECK_NULL_RETURN(frameNode, ERROR_CODE_PARAM_INVALID);
201 frameNode->DecRefCount();
202 controllerHandler->contentHandle = nullptr;
203 }
204 return ERROR_CODE_NO_ERROR;
205 }
206
SetDialogContentAlignment(ArkUIDialogHandle controllerHandler,ArkUI_Int32 alignment,ArkUI_Float32 offsetX,ArkUI_Float32 offsetY)207 ArkUI_Int32 SetDialogContentAlignment(ArkUIDialogHandle controllerHandler,
208 ArkUI_Int32 alignment, ArkUI_Float32 offsetX, ArkUI_Float32 offsetY)
209 {
210 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
211 if (alignment < DEFAULT_DIALOG_ALIGNMENT || alignment > ARKUI_ALIGNMENT_BOTTOM_END_INDEX) {
212 return ERROR_CODE_PARAM_INVALID;
213 }
214 controllerHandler->alignment = alignment;
215 controllerHandler->offsetX = offsetX;
216 controllerHandler->offsetY = offsetY;
217 return ERROR_CODE_NO_ERROR;
218 }
219
ResetDialogContentAlignment(ArkUIDialogHandle controllerHandler)220 ArkUI_Int32 ResetDialogContentAlignment(ArkUIDialogHandle controllerHandler)
221 {
222 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
223 controllerHandler->alignment = DEFAULT_DIALOG_ALIGNMENT;
224 controllerHandler->offsetX = 0.0f;
225 controllerHandler->offsetY = 0.0f;
226 return ERROR_CODE_NO_ERROR;
227 }
228
SetDialogModalMode(ArkUIDialogHandle controllerHandler,bool isModal)229 ArkUI_Int32 SetDialogModalMode(ArkUIDialogHandle controllerHandler, bool isModal)
230 {
231 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
232 controllerHandler->isModal = isModal;
233 return ERROR_CODE_NO_ERROR;
234 }
235
SetDialogAutoCancel(ArkUIDialogHandle controllerHandler,bool autoCancel)236 ArkUI_Int32 SetDialogAutoCancel(ArkUIDialogHandle controllerHandler, bool autoCancel)
237 {
238 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
239 controllerHandler->autoCancel = autoCancel;
240 return ERROR_CODE_NO_ERROR;
241 }
242
SetDialogMask(ArkUIDialogHandle controllerHandler,ArkUI_Uint32 maskColor,ArkUIRect * rect)243 ArkUI_Int32 SetDialogMask(ArkUIDialogHandle controllerHandler, ArkUI_Uint32 maskColor, ArkUIRect* rect)
244 {
245 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
246 controllerHandler->maskColor = maskColor;
247 if (rect) {
248 controllerHandler->maskRect = new ArkUIRect({ .x = rect->x, .y = rect->y,
249 .width = rect->width, .height = rect->height });
250 }
251 return ERROR_CODE_NO_ERROR;
252 }
253
SetDialogBackgroundColor(ArkUIDialogHandle controllerHandler,ArkUI_Uint32 backgroundColor)254 ArkUI_Int32 SetDialogBackgroundColor(ArkUIDialogHandle controllerHandler, ArkUI_Uint32 backgroundColor)
255 {
256 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
257 controllerHandler->backgroundColor = backgroundColor;
258 return ERROR_CODE_NO_ERROR;
259 }
260
SetDialogCornerRadius(ArkUIDialogHandle controllerHandler,ArkUI_Float32 topLeft,ArkUI_Float32 topRight,ArkUI_Float32 bottomLeft,ArkUI_Float32 bottomRight)261 ArkUI_Int32 SetDialogCornerRadius(ArkUIDialogHandle controllerHandler, ArkUI_Float32 topLeft,
262 ArkUI_Float32 topRight, ArkUI_Float32 bottomLeft, ArkUI_Float32 bottomRight)
263 {
264 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
265 controllerHandler->cornerRadiusRect = new ArkUICornerRadius({ .topLeft = topLeft, .topRight = topRight,
266 .bottomLeft = bottomLeft, .bottomRight = bottomRight });
267 return ERROR_CODE_NO_ERROR;
268 }
269
SetDialogGridColumnCount(ArkUIDialogHandle controllerHandler,ArkUI_Int32 gridCount)270 ArkUI_Int32 SetDialogGridColumnCount(ArkUIDialogHandle controllerHandler, ArkUI_Int32 gridCount)
271 {
272 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
273 controllerHandler->gridCount = gridCount;
274 return ERROR_CODE_NO_ERROR;
275 }
276
EnableDialogCustomStyle(ArkUIDialogHandle controllerHandler,bool enableCustomStyle)277 ArkUI_Int32 EnableDialogCustomStyle(ArkUIDialogHandle controllerHandler, bool enableCustomStyle)
278 {
279 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
280 controllerHandler->enableCustomStyle = enableCustomStyle;
281 return ERROR_CODE_NO_ERROR;
282 }
283
EnableDialogCustomAnimation(ArkUIDialogHandle controllerHandler,bool enableCustomAnimation)284 ArkUI_Int32 EnableDialogCustomAnimation(ArkUIDialogHandle controllerHandler, bool enableCustomAnimation)
285 {
286 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
287 controllerHandler->enableCustomAnimation = enableCustomAnimation;
288 return ERROR_CODE_NO_ERROR;
289 }
290
ShowDialog(ArkUIDialogHandle controllerHandler,bool showInSubWindow)291 ArkUI_Int32 ShowDialog(ArkUIDialogHandle controllerHandler, bool showInSubWindow)
292 {
293 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
294 controllerHandler->showInSubWindow = showInSubWindow;
295 DialogProperties dialogProperties;
296 ParseDialogProperties(dialogProperties, controllerHandler);
297 auto* contentNode = reinterpret_cast<FrameNode*>(controllerHandler->contentHandle);
298 CHECK_NULL_RETURN(contentNode, ERROR_CODE_PARAM_INVALID);
299 auto contentPtr = AceType::Claim<FrameNode>(contentNode);
300 auto dialogNode = CustomDialogControllerModelNG::SetOpenDialogWithNode(dialogProperties, contentPtr);
301 if (dialogNode) {
302 dialogNode->IncRefCount();
303 }
304 controllerHandler->dialogHandle = AceType::RawPtr(dialogNode);
305 return ERROR_CODE_NO_ERROR;
306 }
307
CloseDialog(ArkUIDialogHandle controllerHandler)308 ArkUI_Int32 CloseDialog(ArkUIDialogHandle controllerHandler)
309 {
310 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
311 auto* dialogNode = reinterpret_cast<FrameNode*>(controllerHandler->dialogHandle);
312 CHECK_NULL_RETURN(dialogNode, ERROR_CODE_PARAM_INVALID);
313 CustomDialogControllerModelNG::SetCloseDialogForNDK(dialogNode);
314 if (dialogNode) {
315 dialogNode->DecRefCount();
316 }
317 controllerHandler->dialogHandle = nullptr;
318 return ERROR_CODE_NO_ERROR;
319 }
320
RegisterOnWillDialogDismiss(ArkUIDialogHandle controllerHandler,bool (* eventHandler)(ArkUI_Int32))321 ArkUI_Int32 RegisterOnWillDialogDismiss(ArkUIDialogHandle controllerHandler, bool (*eventHandler)(ArkUI_Int32))
322 {
323 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
324 controllerHandler->onWillDismissCall = eventHandler;
325 return ERROR_CODE_NO_ERROR;
326 }
327
RegisterOnWillDialogDismissWithUserData(ArkUIDialogHandle controllerHandler,void * userData,void (* callback)(ArkUI_DialogDismissEvent * event))328 ArkUI_Int32 RegisterOnWillDialogDismissWithUserData(
329 ArkUIDialogHandle controllerHandler, void* userData, void (*callback)(ArkUI_DialogDismissEvent* event))
330 {
331 CHECK_NULL_RETURN(controllerHandler, ERROR_CODE_PARAM_INVALID);
332 controllerHandler->onWillDismissCallByNDK = callback;
333 controllerHandler->userData = userData;
334 return ERROR_CODE_NO_ERROR;
335 }
336
337 } // namespace OHOS::Ace::NG::ViewModel