1 /*
2 * Copyright (c) 2021-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 "bridge/declarative_frontend/jsview/js_checkboxgroup.h"
17
18 #include "bridge/declarative_frontend/jsview/js_interactable_view.h"
19 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
20 #include "bridge/declarative_frontend/jsview/models/checkboxgroup_model_impl.h"
21 #include "bridge/declarative_frontend/view_stack_processor.h"
22 #include "core/components/checkable/checkable_component.h"
23 #include "core/components_ng/base/view_abstract.h"
24 #include "core/components_ng/base/view_stack_processor.h"
25 #include "core/components_ng/pattern/checkboxgroup/checkboxgroup_model_ng.h"
26 #include "frameworks/bridge/declarative_frontend/jsview/js_interactable_view.h"
27
28 namespace OHOS::Ace {
29
30 std::unique_ptr<CheckBoxGroupModel> CheckBoxGroupModel::instance_ = nullptr;
31
GetInstance()32 CheckBoxGroupModel* CheckBoxGroupModel::GetInstance()
33 {
34 if (!instance_) {
35 #ifdef NG_BUILD
36 instance_.reset(new NG::CheckBoxGroupModelNG());
37 #else
38 if (Container::IsCurrentUseNewPipeline()) {
39 instance_.reset(new NG::CheckBoxGroupModelNG());
40 } else {
41 instance_.reset(new Framework::CheckBoxGroupModelImpl());
42 }
43 #endif
44 }
45 return instance_.get();
46 }
47
48 } // namespace OHOS::Ace
49
50 namespace OHOS::Ace::Framework {
51
CheckboxGroupResultEventToJSValue(const CheckboxGroupResult & eventInfo)52 JSRef<JSVal> CheckboxGroupResultEventToJSValue(const CheckboxGroupResult& eventInfo)
53 {
54 JSRef<JSObject> obj = JSRef<JSObject>::New();
55 JSRef<JSArray> nameArr = JSRef<JSArray>::New();
56 std::vector<std::string> nameList = eventInfo.GetNameList();
57 for (int idx = 0; idx < static_cast<int32_t>(nameList.size()); ++idx) {
58 JSRef<JSVal> name = JSRef<JSVal>::Make(ToJSValue(nameList[idx]));
59 nameArr->SetValueAt(idx, name);
60 }
61 obj->SetPropertyObject("name", nameArr);
62 obj->SetProperty("status", eventInfo.GetStatus());
63 return JSRef<JSVal>::Cast(obj);
64 }
65
JSBind(BindingTarget globalObj)66 void JSCheckboxGroup::JSBind(BindingTarget globalObj)
67 {
68 JSClass<JSCheckboxGroup>::Declare("CheckboxGroup");
69
70 JSClass<JSCheckboxGroup>::StaticMethod("create", &JSCheckboxGroup::Create);
71 JSClass<JSCheckboxGroup>::StaticMethod("selectAll", &JSCheckboxGroup::SetSelectAll);
72 JSClass<JSCheckboxGroup>::StaticMethod("onChange", &JSCheckboxGroup::SetOnChange);
73 JSClass<JSCheckboxGroup>::StaticMethod("selectedColor", &JSCheckboxGroup::SelectedColor);
74 JSClass<JSCheckboxGroup>::StaticMethod("width", &JSCheckboxGroup::JsWidth);
75 JSClass<JSCheckboxGroup>::StaticMethod("height", &JSCheckboxGroup::JsHeight);
76 JSClass<JSCheckboxGroup>::StaticMethod("size", &JSCheckboxGroup::JsSize);
77 JSClass<JSCheckboxGroup>::StaticMethod("padding", &JSCheckboxGroup::JsPadding);
78 JSClass<JSCheckboxGroup>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
79 JSClass<JSCheckboxGroup>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
80 JSClass<JSCheckboxGroup>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
81 JSClass<JSCheckboxGroup>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
82 JSClass<JSCheckboxGroup>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
83 JSClass<JSCheckboxGroup>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
84 JSClass<JSCheckboxGroup>::Inherit<JSViewAbstract>();
85 JSClass<JSCheckboxGroup>::Bind<>(globalObj);
86 }
87
Create(const JSCallbackInfo & info)88 void JSCheckboxGroup::Create(const JSCallbackInfo& info)
89 {
90 std::optional<std::string> checkboxGroupName;
91 if ((info.Length() >= 1) && info[0]->IsObject()) {
92 auto paramObject = JSRef<JSObject>::Cast(info[0]);
93 auto groupName = paramObject->GetProperty("group");
94 if (groupName->IsString()) {
95 checkboxGroupName = groupName->ToString();
96 }
97 }
98
99 CheckBoxGroupModel::GetInstance()->Create(checkboxGroupName);
100 }
101
SetSelectAll(const JSCallbackInfo & info)102 void JSCheckboxGroup::SetSelectAll(const JSCallbackInfo& info)
103 {
104 if (info.Length() < 1 || !info[0]->IsBoolean()) {
105 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments, arg is not a bool");
106 return;
107 }
108
109 CheckBoxGroupModel::GetInstance()->SetSelectAll(info[0]->ToBoolean());
110 }
111
SetOnChange(const JSCallbackInfo & args)112 void JSCheckboxGroup::SetOnChange(const JSCallbackInfo& args)
113 {
114 if (args.Length() < 1 || !args[0]->IsFunction()) {
115 LOGI("args not function");
116 return;
117 }
118 auto jsFunc = AceType::MakeRefPtr<JsEventFunction<CheckboxGroupResult, 1>>(
119 JSRef<JSFunc>::Cast(args[0]), CheckboxGroupResultEventToJSValue);
120 auto onChange = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc)](const BaseEventInfo* info) {
121 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
122 const auto* eventInfo = TypeInfoHelper::DynamicCast<CheckboxGroupResult>(info);
123 func->Execute(*eventInfo);
124 };
125 CheckBoxGroupModel::GetInstance()->SetOnChange(onChange);
126 }
127
JsWidth(const JSCallbackInfo & info)128 void JSCheckboxGroup::JsWidth(const JSCallbackInfo& info)
129 {
130 if (info.Length() < 1) {
131 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
132 return;
133 }
134
135 JsWidth(info[0]);
136 }
137
JsWidth(const JSRef<JSVal> & jsValue)138 void JSCheckboxGroup::JsWidth(const JSRef<JSVal>& jsValue)
139 {
140 Dimension value;
141 if (!ParseJsDimensionVp(jsValue, value)) {
142 return;
143 }
144 if (Container::IsCurrentUseNewPipeline()) {
145 NG::ViewAbstract::SetWidth(NG::CalcLength(value));
146 return;
147 }
148
149 CheckBoxGroupModel::GetInstance()->SetWidth(value);
150 }
151
JsHeight(const JSCallbackInfo & info)152 void JSCheckboxGroup::JsHeight(const JSCallbackInfo& info)
153 {
154 if (info.Length() < 1) {
155 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
156 return;
157 }
158
159 JsHeight(info[0]);
160 }
161
JsHeight(const JSRef<JSVal> & jsValue)162 void JSCheckboxGroup::JsHeight(const JSRef<JSVal>& jsValue)
163 {
164 Dimension value;
165 if (!ParseJsDimensionVp(jsValue, value)) {
166 return;
167 }
168
169 if (Container::IsCurrentUseNewPipeline()) {
170 NG::ViewAbstract::SetHeight(NG::CalcLength(value));
171 return;
172 }
173
174 CheckBoxGroupModel::GetInstance()->SetHeight(value);
175 }
176
JsSize(const JSCallbackInfo & info)177 void JSCheckboxGroup::JsSize(const JSCallbackInfo& info)
178 {
179 if (info.Length() < 1) {
180 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
181 return;
182 }
183
184 if (!info[0]->IsObject()) {
185 LOGE("arg is not Object or String.");
186 return;
187 }
188
189 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
190 JsWidth(sizeObj->GetProperty("width"));
191 JsHeight(sizeObj->GetProperty("height"));
192 }
193
SelectedColor(const JSCallbackInfo & info)194 void JSCheckboxGroup::SelectedColor(const JSCallbackInfo& info)
195 {
196 if (info.Length() < 1) {
197 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
198 return;
199 }
200 Color selectedColor;
201 auto theme = GetTheme<CheckboxTheme>();
202 if (!ParseJsColor(info[0], selectedColor)) {
203 selectedColor = theme->GetActiveColor();
204 }
205
206 CheckBoxGroupModel::GetInstance()->SetSelectedColor(selectedColor);
207 }
208
JsPadding(const JSCallbackInfo & info)209 void JSCheckboxGroup::JsPadding(const JSCallbackInfo& info)
210 {
211 if (info.Length() < 1) {
212 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
213 return;
214 }
215 if (!info[0]->IsString() && !info[0]->IsNumber() && !info[0]->IsObject()) {
216 LOGE("arg is not a string, number or object.");
217 return;
218 }
219
220 Dimension value;
221 if (!ParseJsDimensionVp(info[0], value)) {
222 return;
223 }
224 if (Container::IsCurrentUseNewPipeline()) {
225 NG::ViewAbstract::SetPadding(NG::CalcLength(value));
226 return;
227 }
228
229 if (info[0]->IsObject()) {
230 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
231 if (!argsPtrItem || argsPtrItem->IsNull()) {
232 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
233 return;
234 }
235 if (argsPtrItem->Contains("top") || argsPtrItem->Contains("bottom") || argsPtrItem->Contains("left") ||
236 argsPtrItem->Contains("right")) {
237 Dimension topDimen = Dimension(0.0, DimensionUnit::VP);
238 Dimension leftDimen = Dimension(0.0, DimensionUnit::VP);
239 Dimension rightDimen = Dimension(0.0, DimensionUnit::VP);
240 Dimension bottomDimen = Dimension(0.0, DimensionUnit::VP);
241 ParseJsonDimensionVp(argsPtrItem->GetValue("top"), topDimen);
242 ParseJsonDimensionVp(argsPtrItem->GetValue("left"), leftDimen);
243 ParseJsonDimensionVp(argsPtrItem->GetValue("right"), rightDimen);
244 ParseJsonDimensionVp(argsPtrItem->GetValue("bottom"), bottomDimen);
245 if (leftDimen == 0.0_vp) {
246 leftDimen = rightDimen;
247 }
248 if (topDimen == 0.0_vp) {
249 topDimen = bottomDimen;
250 }
251 if (leftDimen == 0.0_vp) {
252 leftDimen = topDimen;
253 }
254 NG::PaddingPropertyF padding;
255 padding.left = leftDimen.ConvertToPx();
256 padding.right = rightDimen.ConvertToPx();
257 padding.top = topDimen.ConvertToPx();
258 padding.bottom = bottomDimen.ConvertToPx();
259 CheckBoxGroupModel::GetInstance()->SetPadding(padding);
260 return;
261 }
262 }
263 Dimension length;
264 if (!ParseJsDimensionVp(info[0], length)) {
265 return;
266 }
267 NG::PaddingPropertyF padding;
268 padding.left = length.ConvertToPx();
269 padding.right = length.ConvertToPx();
270 padding.top = length.ConvertToPx();
271 padding.bottom = length.ConvertToPx();
272 CheckBoxGroupModel::GetInstance()->SetPadding(padding);
273 }
274
275 } // namespace OHOS::Ace::Framework
276