• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "frameworks/bridge/declarative_frontend/jsview/js_sliding_panel.h"
17 
18 #include <algorithm>
19 #include <iterator>
20 
21 #include "base/log/ace_scoring_log.h"
22 #include "bridge/declarative_frontend/jsview/js_view_abstract.h"
23 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
24 #include "bridge/declarative_frontend/jsview/models/sliding_panel_model_impl.h"
25 #include "core/components_ng/base/view_abstract_model_ng.h"
26 #include "core/components_ng/pattern/panel/sliding_panel_model.h"
27 #include "core/components_ng/pattern/panel/sliding_panel_model_ng.h"
28 
29 namespace OHOS::Ace {
30 
31 std::unique_ptr<SlidingPanelModel> SlidingPanelModel::instance_ = nullptr;
32 
GetInstance()33 SlidingPanelModel* SlidingPanelModel::GetInstance()
34 {
35     if (!instance_) {
36 #ifdef NG_BUILD
37         instance_.reset(new NG::SlidingPanelModelNG());
38 #else
39         if (Container::IsCurrentUseNewPipeline()) {
40             instance_.reset(new NG::SlidingPanelModelNG());
41         } else {
42             instance_.reset(new Framework::SlidingPanelModelImpl());
43         }
44 #endif
45     }
46     return instance_.get();
47 }
48 
49 } // namespace OHOS::Ace
50 namespace OHOS::Ace::Framework {
51 namespace {
52 
53 const std::vector<PanelMode> PANEL_MODES = { PanelMode::MINI, PanelMode::HALF, PanelMode::FULL, PanelMode::AUTO };
54 const std::vector<PanelType> PANEL_TYPES = { PanelType::MINI_BAR, PanelType::FOLDABLE_BAR, PanelType::TEMP_DISPLAY };
55 const std::vector<VisibleType> PANEL_VISIBLE_TYPES = { VisibleType::GONE, VisibleType::VISIBLE,
56     VisibleType::INVISIBLE };
57 
58 } // namespace
59 
Create(const JSCallbackInfo & info)60 void JSSlidingPanel::Create(const JSCallbackInfo& info)
61 {
62     if (info.Length() > 0 && info[0]->IsBoolean()) {
63         bool isShow = true;
64         isShow = info[0]->ToBoolean();
65         SlidingPanelModel::GetInstance()->Create(isShow);
66         return;
67     }
68 }
69 
JSBind(BindingTarget globalObj)70 void JSSlidingPanel::JSBind(BindingTarget globalObj)
71 {
72     JSClass<JSSlidingPanel>::Declare("Panel");
73     MethodOptions opt = MethodOptions::NONE;
74     JSClass<JSSlidingPanel>::StaticMethod("create", &JSSlidingPanel::Create, opt);
75     JSClass<JSSlidingPanel>::StaticMethod("pop", &JSSlidingPanel::Pop, opt);
76     JSClass<JSSlidingPanel>::StaticMethod("dragBar", &JSSlidingPanel::SetHasDragBar, opt);
77     JSClass<JSSlidingPanel>::StaticMethod("show", &JSSlidingPanel::SetShow, opt);
78     JSClass<JSSlidingPanel>::StaticMethod("mode", &JSSlidingPanel::SetPanelMode, opt);
79     JSClass<JSSlidingPanel>::StaticMethod("type", &JSSlidingPanel::SetPanelType, opt);
80     JSClass<JSSlidingPanel>::StaticMethod("backgroundMask", &JSSlidingPanel::SetBackgroundMask, opt);
81     JSClass<JSSlidingPanel>::StaticMethod("fullHeight", &JSSlidingPanel::SetFullHeight, opt);
82     JSClass<JSSlidingPanel>::StaticMethod("halfHeight", &JSSlidingPanel::SetHalfHeight, opt);
83     JSClass<JSSlidingPanel>::StaticMethod("miniHeight", &JSSlidingPanel::SetMiniHeight, opt);
84     JSClass<JSSlidingPanel>::StaticMethod("backgroundColor", JsBackgroundColor);
85     JSClass<JSSlidingPanel>::StaticMethod("border", JsPanelBorder);
86     JSClass<JSSlidingPanel>::StaticMethod("borderWidth", JsPanelBorderWidth);
87     JSClass<JSSlidingPanel>::StaticMethod("borderColor", JsPanelBorderColor);
88     JSClass<JSSlidingPanel>::StaticMethod("borderStyle", JsPanelBorderStyle);
89     JSClass<JSSlidingPanel>::StaticMethod("borderRadius", JsPanelBorderRadius);
90 
91     JSClass<JSSlidingPanel>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
92     JSClass<JSSlidingPanel>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
93     JSClass<JSSlidingPanel>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
94     JSClass<JSSlidingPanel>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
95     JSClass<JSSlidingPanel>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
96     JSClass<JSSlidingPanel>::StaticMethod("onChange", &JSSlidingPanel::SetOnSizeChange);
97     JSClass<JSSlidingPanel>::StaticMethod("onHeightChange", &JSSlidingPanel::SetOnHeightChange);
98 
99     JSClass<JSSlidingPanel>::Inherit<JSContainerBase>();
100     JSClass<JSSlidingPanel>::Inherit<JSViewAbstract>();
101     JSClass<JSSlidingPanel>::Bind<>(globalObj);
102 }
103 
SetBackgroundMask(const JSCallbackInfo & info)104 void JSSlidingPanel::SetBackgroundMask(const JSCallbackInfo& info)
105 {
106     if (info.Length() < 1) {
107         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
108         return;
109     }
110     Color color;
111     if (!ParseJsColor(info[0], color)) {
112         return;
113     }
114 
115     SlidingPanelModel::GetInstance()->SetBackgroundMask(color);
116 }
117 
ParsePanelRadius(const JSRef<JSVal> & args,BorderRadius & borderRadius)118 void JSSlidingPanel::ParsePanelRadius(const JSRef<JSVal>& args, BorderRadius& borderRadius)
119 {
120     if (!args->IsObject() && !args->IsNumber() && !args->IsString()) {
121         LOGE("args need a object or number or string. %{public}s", args->ToString().c_str());
122         return;
123     }
124 
125     Dimension radius;
126     if (ParseJsDimensionVp(args, radius)) {
127         borderRadius.radiusTopLeft = radius;
128         borderRadius.radiusTopRight = radius;
129         borderRadius.radiusBottomLeft = radius;
130         borderRadius.radiusBottomRight = radius;
131         return;
132     }
133     if (args->IsObject()) {
134         JSRef<JSObject> object = JSRef<JSObject>::Cast(args);
135         auto valueTopLeft = object->GetProperty("topLeft");
136         if (!valueTopLeft->IsUndefined()) {
137             ParseJsDimensionVp(valueTopLeft, borderRadius.radiusTopLeft);
138         }
139         auto valueTopRight = object->GetProperty("topRight");
140         if (!valueTopRight->IsUndefined()) {
141             ParseJsDimensionVp(valueTopRight, borderRadius.radiusTopRight);
142         }
143         auto valueBottomLeft = object->GetProperty("bottomLeft");
144         if (!valueBottomLeft->IsUndefined()) {
145             ParseJsDimensionVp(valueBottomLeft, borderRadius.radiusBottomLeft);
146         }
147         auto valueBottomRight = object->GetProperty("bottomRight");
148         if (!valueBottomRight->IsUndefined()) {
149             ParseJsDimensionVp(valueBottomRight, borderRadius.radiusBottomRight);
150         }
151         return;
152     }
153     LOGE("args format error. %{public}s", args->ToString().c_str());
154 }
155 
JsPanelBorderRadius(const JSCallbackInfo & info)156 void JSSlidingPanel::JsPanelBorderRadius(const JSCallbackInfo& info)
157 {
158     BorderRadius borderRadius;
159     ParsePanelRadius(info[0], borderRadius);
160 
161     ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius.radiusTopLeft, borderRadius.radiusTopRight,
162         borderRadius.radiusBottomLeft, borderRadius.radiusBottomRight);
163 }
164 
JsBackgroundColor(const JSCallbackInfo & info)165 void JSSlidingPanel::JsBackgroundColor(const JSCallbackInfo& info)
166 {
167     if (info.Length() < 1) {
168         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
169         return;
170     }
171     Color backgroundColor;
172     if (!ParseJsColor(info[0], backgroundColor)) {
173         return;
174     }
175 
176     SlidingPanelModel::GetInstance()->SetBackgroundColor(backgroundColor);
177 }
178 
JsPanelBorderColor(const JSCallbackInfo & info)179 void JSSlidingPanel::JsPanelBorderColor(const JSCallbackInfo& info)
180 {
181     if (info.Length() < 1) {
182         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
183         return;
184     }
185     Color borderColor;
186     if (!ParseJsColor(info[0], borderColor)) {
187         return;
188     }
189 
190     SlidingPanelModel::GetInstance()->SetBorderColor(borderColor);
191 }
192 
JsPanelBorderWidth(const JSCallbackInfo & info)193 void JSSlidingPanel::JsPanelBorderWidth(const JSCallbackInfo& info)
194 {
195     if (info.Length() < 1) {
196         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
197         return;
198     }
199     Dimension borderWidth;
200     if (!ParseJsDimensionVp(info[0], borderWidth)) {
201         return;
202     }
203     SlidingPanelModel::GetInstance()->SetBorderWidth(borderWidth);
204 }
205 
JsPanelBorderStyle(int32_t style)206 void JSSlidingPanel::JsPanelBorderStyle(int32_t style)
207 {
208     BorderStyle borderStyle = BorderStyle::SOLID;
209     if (style > 0 && style < 4) {
210         borderStyle = static_cast<BorderStyle>(style);
211     }
212     SlidingPanelModel::GetInstance()->SetBorderStyle(borderStyle);
213 }
214 
JsPanelBorder(const JSCallbackInfo & info)215 void JSSlidingPanel::JsPanelBorder(const JSCallbackInfo& info)
216 {
217     if (info.Length() < 1) {
218         LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
219         return;
220     }
221     if (!info[0]->IsObject()) {
222         LOGE("arg is not a object.");
223         return;
224     }
225 
226     auto argsPtrItem = JSRef<JSObject>::Cast(info[0]);
227     Dimension width = Dimension(0.0, DimensionUnit::VP);
228     ParseJsDimensionVp(argsPtrItem->GetProperty("width"), width);
229     SlidingPanelModel::GetInstance()->SetBorderWidth(width);
230 
231     BorderRadius borderRadius;
232     ParsePanelRadius(argsPtrItem->GetProperty("radius"), borderRadius);
233     ViewAbstractModel::GetInstance()->SetBorderRadius(borderRadius.radiusTopLeft, borderRadius.radiusTopRight,
234         borderRadius.radiusBottomLeft, borderRadius.radiusBottomRight);
235 
236     auto styleJsValue = argsPtrItem->GetProperty("style");
237     auto borderStyle = BorderStyle::SOLID;
238     if (!styleJsValue->IsUndefined() && styleJsValue->IsNumber()) {
239         auto styleValue = styleJsValue->ToNumber<uint32_t>();
240         if (styleValue > 0 && styleValue < 4) {
241             borderStyle = static_cast<BorderStyle>(styleValue);
242         }
243     }
244     SlidingPanelModel::GetInstance()->SetBorderStyle(borderStyle);
245 
246     Color borderColor;
247     ParseJsColor(argsPtrItem->GetProperty("color"), borderColor);
248     SlidingPanelModel::GetInstance()->SetBorderColor(borderColor);
249 }
250 
SetOnSizeChange(const JSCallbackInfo & args)251 void JSSlidingPanel::SetOnSizeChange(const JSCallbackInfo& args)
252 {
253     if (!args[0]->IsFunction()) {
254         return;
255     }
256 
257     auto onSizeChangeNG = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](
258                               const BaseEventInfo* info) {
259         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
260         auto eventInfo = TypeInfoHelper::DynamicCast<SlidingPanelSizeChangeEvent>(info);
261         if (!eventInfo) {
262             return;
263         }
264         auto params = ConvertToJSValues(eventInfo->GetWidth(), eventInfo->GetHeight(), eventInfo->GetMode());
265         ACE_SCORING_EVENT("SlidingPanel.OnSizeChange");
266         func->Call(JSRef<JSObject>(), params.size(), params.data());
267     };
268     SlidingPanelModel::GetInstance()->SetOnSizeChange(onSizeChangeNG);
269 
270     args.ReturnSelf();
271 }
272 
SetOnHeightChange(const JSCallbackInfo & args)273 void JSSlidingPanel::SetOnHeightChange(const JSCallbackInfo& args)
274 {
275     if (args.Length() < 1) {
276         LOGE("The argv is wrong, it is supposed to have at least 1 argument");
277         return;
278     }
279     if (!args[0]->IsFunction()) {
280         return;
281     }
282 
283     auto onHeightChangeCallback = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
284     auto onHeightChange = [execCtx = args.GetExecutionContext(), func = std::move(onHeightChangeCallback)](
285                               int32_t height) {
286         JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
287         ACE_SCORING_EVENT("OnHeightChange");
288         JSRef<JSVal> param = JSRef<JSVal>::Make(ToJSValue(height));
289         func->ExecuteJS(1, &param);
290     };
291 
292     SlidingPanelModel::GetInstance()->SetOnHeightChange(std::move(onHeightChange));
293 
294     args.ReturnSelf();
295 }
296 
SetHasDragBar(bool hasDragBar)297 void JSSlidingPanel::SetHasDragBar(bool hasDragBar)
298 {
299     SlidingPanelModel::GetInstance()->SetHasDragBar(hasDragBar);
300 }
301 
SetShow(bool isShow)302 void JSSlidingPanel::SetShow(bool isShow)
303 {
304     SlidingPanelModel::GetInstance()->SetIsShow(isShow);
305 }
306 
SetPanelMode(int32_t mode)307 void JSSlidingPanel::SetPanelMode(int32_t mode)
308 {
309     if (mode < 0 || mode >= static_cast<int32_t>(PANEL_MODES.size())) {
310         return;
311     }
312 
313     SlidingPanelModel::GetInstance()->SetPanelMode(PANEL_MODES[mode]);
314 }
315 
SetPanelType(int32_t type)316 void JSSlidingPanel::SetPanelType(int32_t type)
317 {
318     if (type < 0 || type >= static_cast<int32_t>(PANEL_TYPES.size())) {
319         return;
320     }
321 
322     SlidingPanelModel::GetInstance()->SetPanelType(PANEL_TYPES[type]);
323 }
324 
SetMiniHeight(const JSCallbackInfo & info)325 void JSSlidingPanel::SetMiniHeight(const JSCallbackInfo& info)
326 {
327     if (info.Length() < 1) {
328         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
329         return;
330     }
331     Dimension miniHeight;
332     if (!ParseJsDimensionVp(info[0], miniHeight)) {
333         return;
334     }
335 
336     SlidingPanelModel::GetInstance()->SetMiniHeight(miniHeight);
337 }
338 
SetHalfHeight(const JSCallbackInfo & info)339 void JSSlidingPanel::SetHalfHeight(const JSCallbackInfo& info)
340 {
341     if (info.Length() < 1) {
342         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
343         return;
344     }
345     Dimension halfHeight;
346     if (!ParseJsDimensionVp(info[0], halfHeight)) {
347         return;
348     }
349     SlidingPanelModel::GetInstance()->SetHalfHeight(halfHeight);
350 }
351 
SetFullHeight(const JSCallbackInfo & info)352 void JSSlidingPanel::SetFullHeight(const JSCallbackInfo& info)
353 {
354     if (info.Length() < 1) {
355         LOGE("The arg is wrong, it is supposed to have at least 1 argument");
356         return;
357     }
358     Dimension fullHeight;
359     if (!ParseJsDimensionVp(info[0], fullHeight)) {
360         return;
361     }
362     SlidingPanelModel::GetInstance()->SetFullHeight(fullHeight);
363 }
364 
Pop()365 void JSSlidingPanel::Pop()
366 {
367     SlidingPanelModel::GetInstance()->Pop();
368 }
369 
370 } // namespace OHOS::Ace::Framework
371