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 "bridge/cj_frontend/interfaces/cj_ffi/cj_alert_dialog_ffi.h"
17 
18 #include "cj_lambda.h"
19 #include "core/components_ng/pattern/dialog/alert_dialog_model_ng.h"
20 #include "bridge/common/utils/engine_helper.h"
21 
22 using namespace OHOS::Ace;
23 
24 namespace {
25 const std::vector<DialogAlignment> DIALOG_ALIGNMENT = { DialogAlignment::TOP, DialogAlignment::CENTER,
26     DialogAlignment::BOTTOM, DialogAlignment::DEFAULT, DialogAlignment::TOP_START, DialogAlignment::TOP_END,
27     DialogAlignment::CENTER_START, DialogAlignment::CENTER_END, DialogAlignment::BOTTOM_START,
28     DialogAlignment::BOTTOM_END };
29 const std::vector<DialogButtonDirection> DIALOG_BUTTONS_DIRECTION = { DialogButtonDirection::AUTO,
30     DialogButtonDirection::HORIZONTAL, DialogButtonDirection::VERTICAL };
31 
32 constexpr uint32_t COLOR_ALPHA_OFFSET = 24;
33 constexpr uint32_t COLOR_ALPHA_VALUE = 0xFF000000;
34 
ColorAlphaAdapt(uint32_t origin)35 uint32_t ColorAlphaAdapt(uint32_t origin)
36 {
37     uint32_t result = origin;
38     if ((origin >> COLOR_ALPHA_OFFSET) == 0) {
39         result = origin | COLOR_ALPHA_VALUE;
40     }
41     return result;
42 }
43 
44 extern "C" {
ParseAlertDialogConfirm(NativeAlertDialogParam alertDialog,DialogProperties & properties)45     static void ParseAlertDialogConfirm(NativeAlertDialogParam alertDialog, DialogProperties& properties)
46     {
47         // Parse title.
48         properties.title = std::string(alertDialog.title);
49 
50         // Parse subtitle.
51         properties.subtitle = std::string(alertDialog.subtitle);
52 
53         // Parses message.
54         properties.content = std::string(alertDialog.message);
55 
56         // Parse autoCancel.
57         properties.autoCancel = alertDialog.autoCancel;
58 
59         // Parse cancel.
60         auto cancel = [lambda = CJLambda::Create(alertDialog.cancel)]() {
61             lambda();
62         };
63         AlertDialogModel::GetInstance()->SetOnCancel(cancel, properties);
64 
65         // Parse alignment
66         auto alignment = alertDialog.alignment;
67         if (alignment >= 0 && alignment <= static_cast<int32_t>(DIALOG_ALIGNMENT.size())) {
68             properties.alignment = DIALOG_ALIGNMENT[alignment];
69         }
70 
71         // Parse offset
72         double dxVal = alertDialog.offset.dx.value;
73         int32_t dxType = alertDialog.offset.dx.unitType;
74         CalcDimension dx = CalcDimension(dxVal, static_cast<DimensionUnit>(dxType));
75 
76         double dyVal = alertDialog.offset.dy.value;
77         int32_t dyType = alertDialog.offset.dy.unitType;
78         CalcDimension dy = CalcDimension(dyVal, static_cast<DimensionUnit>(dyType));
79         properties.offset = DimensionOffset(dx, dy);
80 
81         // Parses gridCount.
82         properties.gridCount = alertDialog.gridCount;
83 
84         // Parse maskRect.
85         Dimension xDimen = Dimension(alertDialog.maskRect.x, static_cast<DimensionUnit>(alertDialog.maskRect.xUnit));
86         Dimension yDimen = Dimension(alertDialog.maskRect.y, static_cast<DimensionUnit>(alertDialog.maskRect.yUnit));
87         Dimension widthDimen =
88             Dimension(alertDialog.maskRect.width, static_cast<DimensionUnit>(alertDialog.maskRect.widthUnit));
89         Dimension heightDimen =
90             Dimension(alertDialog.maskRect.height, static_cast<DimensionUnit>(alertDialog.maskRect.heightUnit));
91         DimensionOffset offsetDimen(xDimen, yDimen);
92         properties.maskRect = DimensionRect(widthDimen, heightDimen, offsetDimen);
93 
94         // Parse showInSubWindowValue.
95         properties.isShowInSubWindow = alertDialog.showInSubWindow;
96 
97         // Parse isModal.
98         properties.isModal = alertDialog.isModal;
99 
100         // Parse backgroundColor.
101         Color backgroundColor = Color(ColorAlphaAdapt(alertDialog.backgroundColor));
102         properties.backgroundColor = backgroundColor;
103 
104         // Parse backgroundColor.
105         int32_t blurStyle = alertDialog.backgroundBlurStyle;
106         if (blurStyle >= static_cast<int>(BlurStyle::NO_MATERIAL) &&
107             blurStyle <= static_cast<int>(BlurStyle::COMPONENT_ULTRA_THICK)) {
108             properties.backgroundBlurStyle = blurStyle;
109         }
110     }
111 
ParseButtonObj(DialogProperties & properties,NativeAlertDialogButtonOptions objInner,const std::string & property)112     static void ParseButtonObj(
113         DialogProperties& properties,
114         NativeAlertDialogButtonOptions objInner,
115         const std::string& property)
116     {
117         ButtonInfo buttonInfo;
118         // Parse enabled
119         buttonInfo.enabled = objInner.enabled;
120 
121         // Parse defaultFocus
122         buttonInfo.defaultFocus = objInner.defaultFocus;
123 
124         // Parse style
125         if (objInner.style != nullptr) {
126             int32_t styleValue = *objInner.style;
127             if (styleValue >= static_cast<int32_t>(DialogButtonStyle::DEFAULT) &&
128                 styleValue <= static_cast<int32_t>(DialogButtonStyle::HIGHTLIGHT)) {
129                 buttonInfo.dlgButtonStyle = static_cast<DialogButtonStyle>(styleValue);
130             }
131         }
132 
133         // Parse value
134         buttonInfo.text = std::string(objInner.value);
135 
136         // Parse fontColor
137         if (objInner.fontColor != nullptr) {
138             Color fontColor = Color(ColorAlphaAdapt(*objInner.fontColor));
139             buttonInfo.textColor = fontColor.ColorToString();
140         }
141 
142         // Parse backgroundColor
143         if (objInner.backgroundColor != nullptr) {
144             Color backgroundColor = Color(ColorAlphaAdapt(*objInner.backgroundColor));
145             buttonInfo.isBgColorSetted = true;
146             buttonInfo.bgColor = backgroundColor;
147         }
148 
149         // Parse action
150         auto action = [lambda = CJLambda::Create(objInner.action)]() {
151             lambda();
152         };
153         AlertDialogModel::GetInstance()->SetParseButtonObj(action, buttonInfo, properties, property);
154 
155         if (buttonInfo.IsValid()) {
156             properties.buttons.emplace_back(buttonInfo);
157         }
158     }
159 
FfiOHOSShowAlertDialogParamWithConfirm(NativeAlertDialogParam alertDialog,NativeAlertDialogButtonOptions confirm)160     void FfiOHOSShowAlertDialogParamWithConfirm(
161         NativeAlertDialogParam alertDialog,
162         NativeAlertDialogButtonOptions confirm)
163     {
164         DialogProperties properties { .type = DialogType::ALERT_DIALOG };
165 
166         // Parse common Param.
167         ParseAlertDialogConfirm(alertDialog, properties);
168 
169         ParseButtonObj(properties, confirm, "confirm");
170 
171         AlertDialogModel::GetInstance()->SetShowDialog(properties);
172     }
173 
FfiOHOSShowAlertDialogParamWithButtons(NativeAlertDialogParam alertDialog,NativeAlertDialogButtonOptions primaryButton,NativeAlertDialogButtonOptions secondaryButton)174     void FfiOHOSShowAlertDialogParamWithButtons(
175         NativeAlertDialogParam alertDialog,
176         NativeAlertDialogButtonOptions primaryButton,
177         NativeAlertDialogButtonOptions secondaryButton)
178     {
179         DialogProperties properties { .type = DialogType::ALERT_DIALOG };
180 
181         // Parse common Param.
182         ParseAlertDialogConfirm(alertDialog, properties);
183 
184         // Parse primaryButton and secondaryButton.
185         ParseButtonObj(properties, primaryButton, "primaryButton");
186 
187         ParseButtonObj(properties, secondaryButton, "secondaryButton");
188 
189         AlertDialogModel::GetInstance()->SetShowDialog(properties);
190     }
191 
ParseButtonArray(DialogProperties & properties,CArrNativeAlertDialogButtonOptions buttons,const std::string & property)192     void ParseButtonArray(
193         DialogProperties& properties,
194         CArrNativeAlertDialogButtonOptions buttons,
195         const std::string& property)
196     {
197         if (buttons.size <= 0) {
198             return;
199         }
200         for (int32_t i = 0; i < buttons.size; i++) {
201             NativeAlertDialogButtonOptions buttonItem = buttons.head[i];
202             ParseButtonObj(properties, buttonItem, property + std::to_string(i));
203         }
204     }
205 
FfiOHOSShowAlertDialogParamWithOptions(NativeAlertDialogParam alertDialog,CArrNativeAlertDialogButtonOptions buttons,int32_t buttonDirection)206     void FfiOHOSShowAlertDialogParamWithOptions(
207         NativeAlertDialogParam alertDialog,
208         CArrNativeAlertDialogButtonOptions buttons,
209         int32_t buttonDirection)
210     {
211         DialogProperties properties { .type = DialogType::ALERT_DIALOG };
212 
213         // Parse common Param.
214         ParseAlertDialogConfirm(alertDialog, properties);
215 
216         // Parse buttons array.
217         ParseButtonArray(properties, buttons, "buttons");
218 
219         // Parse buttons direction.
220         if (buttonDirection >= 0 && buttonDirection <= static_cast<int32_t>(DIALOG_BUTTONS_DIRECTION.size())) {
221             properties.buttonDirection = DIALOG_BUTTONS_DIRECTION[buttonDirection];
222         }
223 
224         AlertDialogModel::GetInstance()->SetShowDialog(properties);
225     }
226 }
227 }
228