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_checkbox.h"
17
18 #include "base/memory/referenced.h"
19 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
20 #include "bridge/declarative_frontend/view_stack_processor.h"
21 #include "core/components/checkable/checkable_component.h"
22 #include "frameworks/bridge/declarative_frontend/jsview/js_interactable_view.h"
23
24 namespace OHOS::Ace::Framework {
25
Create(const JSCallbackInfo & info)26 void JSCheckbox::Create(const JSCallbackInfo& info)
27 {
28 RefPtr<CheckboxTheme> checkBoxTheme = GetTheme<CheckboxTheme>();
29 auto checkboxComponent = AceType::MakeRefPtr<OHOS::Ace::CheckboxComponent>(checkBoxTheme);
30 if ((info.Length() >= 1) && info[0]->IsObject()) {
31 auto paramObject = JSRef<JSObject>::Cast(info[0]);
32 auto name = paramObject->GetProperty("name");
33 auto group = paramObject->GetProperty("group");
34 if (name->IsString()) {
35 auto checkboxName = name->ToString();
36 checkboxComponent->SetCheckboxName(checkboxName);
37 }
38 if (group->IsString()) {
39 auto checkboxGroup = group->ToString();
40 checkboxComponent->SetBelongGroup(checkboxGroup);
41 auto& checkboxGroupmap = CheckboxComponent::GetCheckboxGroupComponent();
42 auto item = checkboxGroupmap.find(checkboxGroup);
43 if (item != checkboxGroupmap.end()) {
44 item->second->AddCheckbox(checkboxComponent);
45 checkboxComponent->SetGroup(item->second);
46 } else {
47 auto& ungroupedCheckboxs = CheckboxComponent::GetUngroupedCheckboxs();
48 auto retPair = ungroupedCheckboxs.try_emplace(checkboxGroup, std::list<WeakPtr<CheckboxComponent>>());
49 retPair.first->second.push_back(checkboxComponent);
50 }
51 }
52 }
53 checkboxComponent->SetInspectorTag("Checkbox");
54 ViewStackProcessor::GetInstance()->Push(checkboxComponent);
55
56 auto box = ViewStackProcessor::GetInstance()->GetBoxComponent();
57 auto horizontalPadding = checkBoxTheme->GetHotZoneHorizontalPadding();
58 auto verticalPadding = checkBoxTheme->GetHotZoneVerticalPadding();
59 box->SetWidth(checkBoxTheme->GetWidth() + horizontalPadding * 2);
60 box->SetHeight(checkBoxTheme->GetHeight() + verticalPadding * 2);
61 }
62
JSBind(BindingTarget globalObj)63 void JSCheckbox::JSBind(BindingTarget globalObj)
64 {
65 JSClass<JSCheckbox>::Declare("Checkbox");
66
67 JSClass<JSCheckbox>::StaticMethod("create", &JSCheckbox::Create);
68 JSClass<JSCheckbox>::StaticMethod("select", &JSCheckbox::SetSelect);
69 JSClass<JSCheckbox>::StaticMethod("onChange", &JSCheckbox::SetOnChange);
70 JSClass<JSCheckbox>::StaticMethod("selectedColor", &JSCheckbox::SelectedColor);
71 JSClass<JSCheckbox>::StaticMethod("width", &JSCheckbox::JsWidth);
72 JSClass<JSCheckbox>::StaticMethod("height", &JSCheckbox::JsHeight);
73 JSClass<JSCheckbox>::StaticMethod("size", &JSCheckbox::JsSize);
74 JSClass<JSCheckbox>::StaticMethod("padding", &JSCheckbox::JsPadding);
75 JSClass<JSCheckbox>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
76 JSClass<JSCheckbox>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
77 JSClass<JSCheckbox>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
78 JSClass<JSCheckbox>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
79 JSClass<JSCheckbox>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
80 JSClass<JSCheckbox>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
81 JSClass<JSCheckbox>::Inherit<JSViewAbstract>();
82 JSClass<JSCheckbox>::Bind<>(globalObj);
83 }
84
SetSelect(const JSCallbackInfo & info)85 void JSCheckbox::SetSelect(const JSCallbackInfo& info)
86 {
87 if (info.Length() < 1 || !info[0]->IsBoolean()) {
88 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments, arg is not a bool");
89 return;
90 }
91 auto stack = ViewStackProcessor::GetInstance();
92 auto checkboxComponent = AceType::DynamicCast<CheckboxComponent>(stack->GetMainComponent());
93 checkboxComponent->SetValue(info[0]->ToBoolean());
94 }
95
SetOnChange(const JSCallbackInfo & args)96 void JSCheckbox::SetOnChange(const JSCallbackInfo& args)
97 {
98 if (!JSViewBindEvent(&CheckboxComponent::SetOnChange, args)) {
99 LOGW("Failed to bind event");
100 }
101 args.ReturnSelf();
102 }
103
JsWidth(const JSCallbackInfo & info)104 void JSCheckbox::JsWidth(const JSCallbackInfo& info)
105 {
106 if (info.Length() < 1) {
107 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
108 return;
109 }
110
111 JsWidth(info[0]);
112 }
113
JsWidth(const JSRef<JSVal> & jsValue)114 void JSCheckbox::JsWidth(const JSRef<JSVal>& jsValue)
115 {
116 Dimension value;
117 if (!ParseJsDimensionVp(jsValue, value)) {
118 return;
119 }
120 auto stack = ViewStackProcessor::GetInstance();
121 Dimension padding;
122 auto box = stack->GetBoxComponent();
123 auto checkboxComponent = AceType::DynamicCast<CheckboxComponent>(stack->GetMainComponent());
124 if (checkboxComponent) {
125 padding = checkboxComponent->GetHotZoneHorizontalPadding();
126 checkboxComponent->SetWidth(value + padding * 2);
127 box->SetWidth(value + padding * 2);
128 }
129 }
130
JsHeight(const JSCallbackInfo & info)131 void JSCheckbox::JsHeight(const JSCallbackInfo& info)
132 {
133 if (info.Length() < 1) {
134 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
135 return;
136 }
137
138 JsHeight(info[0]);
139 }
140
JsHeight(const JSRef<JSVal> & jsValue)141 void JSCheckbox::JsHeight(const JSRef<JSVal>& jsValue)
142 {
143 Dimension value;
144 if (!ParseJsDimensionVp(jsValue, value)) {
145 return;
146 }
147 auto stack = ViewStackProcessor::GetInstance();
148 auto box = stack->GetBoxComponent();
149 Dimension padding;
150 auto checkboxComponent = AceType::DynamicCast<CheckboxComponent>(stack->GetMainComponent());
151 if (checkboxComponent) {
152 padding = checkboxComponent->GetHotZoneVerticalPadding();
153 checkboxComponent->SetHeight(value + padding * 2);
154 box->SetHeight(value + padding * 2);
155 }
156 }
157
JsSize(const JSCallbackInfo & info)158 void JSCheckbox::JsSize(const JSCallbackInfo& info)
159 {
160 if (info.Length() < 1) {
161 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
162 return;
163 }
164
165 if (!info[0]->IsObject()) {
166 LOGE("arg is not Object or String.");
167 return;
168 }
169
170 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
171 JsWidth(sizeObj->GetProperty("width"));
172 JsHeight(sizeObj->GetProperty("height"));
173 }
174
SelectedColor(const JSCallbackInfo & info)175 void JSCheckbox::SelectedColor(const JSCallbackInfo& info)
176 {
177 if (info.Length() < 1) {
178 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
179 return;
180 }
181 Color selectedColor;
182 if (!ParseJsColor(info[0], selectedColor)) {
183 return;
184 }
185 auto mainComponent = ViewStackProcessor::GetInstance()->GetMainComponent();
186 auto checkable = AceType::DynamicCast<CheckboxComponent>(mainComponent);
187 if (checkable) {
188 checkable->SetActiveColor(selectedColor);
189 return;
190 }
191 }
192
JsPadding(const JSCallbackInfo & info)193 void JSCheckbox::JsPadding(const JSCallbackInfo& info)
194 {
195 if (info.Length() < 1) {
196 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
197 return;
198 }
199 if (!info[0]->IsString() && !info[0]->IsNumber() && !info[0]->IsObject()) {
200 LOGE("arg is not a string, number or object.");
201 return;
202 }
203
204 auto stack = ViewStackProcessor::GetInstance();
205 auto box = stack->GetBoxComponent();
206 if (info[0]->IsObject()) {
207 auto argsPtrItem = JsonUtil::ParseJsonString(info[0]->ToString());
208 if (!argsPtrItem || argsPtrItem->IsNull()) {
209 LOGE("Js Parse object failed. argsPtr is null. %s", info[0]->ToString().c_str());
210 return;
211 }
212 if (argsPtrItem->Contains("top") || argsPtrItem->Contains("bottom") || argsPtrItem->Contains("left") ||
213 argsPtrItem->Contains("right")) {
214 Dimension topDimen = Dimension(0.0, DimensionUnit::VP);
215 Dimension leftDimen = Dimension(0.0, DimensionUnit::VP);
216 Dimension rightDimen = Dimension(0.0, DimensionUnit::VP);
217 Dimension bottomDimen = Dimension(0.0, DimensionUnit::VP);
218 ParseJsonDimensionVp(argsPtrItem->GetValue("top"), topDimen);
219 ParseJsonDimensionVp(argsPtrItem->GetValue("left"), leftDimen);
220 ParseJsonDimensionVp(argsPtrItem->GetValue("right"), rightDimen);
221 ParseJsonDimensionVp(argsPtrItem->GetValue("bottom"), bottomDimen);
222 if (leftDimen == 0.0_vp) {
223 leftDimen = rightDimen;
224 }
225 if (topDimen == 0.0_vp) {
226 topDimen = bottomDimen;
227 }
228 if (leftDimen == 0.0_vp) {
229 leftDimen = topDimen;
230 }
231 auto checkboxComponent = AceType::DynamicCast<CheckboxComponent>(stack->GetMainComponent());
232 if (checkboxComponent) {
233 auto width = checkboxComponent->GetWidth() - checkboxComponent->GetHotZoneHorizontalPadding();
234 auto height = checkboxComponent->GetHeight() - checkboxComponent->GetHotZoneVerticalPadding();
235 checkboxComponent->SetHeight(height + topDimen * 2);
236 checkboxComponent->SetWidth(width + leftDimen * 2);
237 box->SetHeight(height + topDimen * 2);
238 box->SetWidth(width + leftDimen * 2);
239 checkboxComponent->SetHotZoneVerticalPadding(topDimen);
240 checkboxComponent->SetHorizontalPadding(leftDimen);
241 }
242 return;
243 }
244 }
245 Dimension length;
246 if (!ParseJsDimensionVp(info[0], length)) {
247 return;
248 }
249 auto checkboxComponent = AceType::DynamicCast<CheckboxComponent>(stack->GetMainComponent());
250 if (checkboxComponent) {
251 auto width = checkboxComponent->GetWidth() - checkboxComponent->GetHotZoneHorizontalPadding();
252 auto height = checkboxComponent->GetHeight() - checkboxComponent->GetHotZoneVerticalPadding();
253 checkboxComponent->SetHeight(height + length * 2);
254 checkboxComponent->SetWidth(width + length * 2);
255 box->SetHeight(height + length * 2);
256 box->SetWidth(width + length * 2);
257 checkboxComponent->SetHotZoneVerticalPadding(length);
258 checkboxComponent->SetHorizontalPadding(length);
259 }
260 }
261 } // namespace OHOS::Ace::Framework
262