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_grid_item.h"
17
18 #include "base/log/ace_scoring_log.h"
19 #include "bridge/declarative_frontend/engine/functions/js_mouse_function.h"
20 #include "bridge/declarative_frontend/jsview/models/grid_item_model_impl.h"
21 #include "core/common/container.h"
22 #include "core/components_ng/pattern/grid/grid_item_model_ng.h"
23
24 namespace OHOS::Ace {
25
26 std::unique_ptr<GridItemModel> GridItemModel::instance_ = nullptr;
27 std::mutex GridItemModel::mutex_;
28
GetInstance()29 GridItemModel* GridItemModel::GetInstance()
30 {
31 if (!instance_) {
32 std::lock_guard<std::mutex> lock(mutex_);
33 if (!instance_) {
34 #ifdef NG_BUILD
35 instance_.reset(new NG::GridItemModelNG());
36 #else
37 if (Container::IsCurrentUseNewPipeline()) {
38 instance_.reset(new NG::GridItemModelNG());
39 } else {
40 instance_.reset(new Framework::GridItemModelImpl());
41 }
42 #endif
43 }
44 }
45 return instance_.get();
46 }
47
48 } // namespace OHOS::Ace
49
50 namespace OHOS::Ace::Framework {
51
Create(const JSCallbackInfo & args)52 void JSGridItem::Create(const JSCallbackInfo& args)
53 {
54 if (Container::IsCurrentUsePartialUpdate()) {
55 CreateForPartialUpdate(args);
56 return;
57 }
58 GridItemModel::GetInstance()->Create();
59 }
60
CreateForPartialUpdate(const JSCallbackInfo & args)61 void JSGridItem::CreateForPartialUpdate(const JSCallbackInfo& args)
62 {
63 if (args.Length() < 2 || !args[0]->IsFunction() || !args[1]->IsBoolean()) {
64 LOGE("parameter not valid");
65 GridItemModel::GetInstance()->Create();
66 return;
67 }
68
69 auto isLazy = args[1]->ToBoolean();
70 auto jsDeepRender = AceType::MakeRefPtr<JsFunction>(args.This(), JSRef<JSFunc>::Cast(args[0]));
71 auto gridItemDeepRenderFunc = [execCtx = args.GetExecutionContext(), jsDeepRenderFunc = std::move(jsDeepRender)](
72 int32_t elmtId) {
73 ACE_SCOPED_TRACE("JSGridItem::ExecuteDeepRender");
74 LOGD("GridItem elmtId %{public}d DeepRender JS function execution start ....", elmtId);
75 ACE_DCHECK(componentsStack_.empty());
76 JAVASCRIPT_EXECUTION_SCOPE(execCtx);
77 JSRef<JSVal> jsParams[2];
78 jsParams[0] = JSRef<JSVal>::Make(ToJSValue(elmtId));
79 jsParams[1] = JSRef<JSVal>::Make(ToJSValue(true));
80 jsDeepRenderFunc->ExecuteJS(2, jsParams);
81 LOGD("GridItem elmtId %{public}d DeepRender JS function execution - done ", elmtId);
82 };
83 GridItemModel::GetInstance()->Create(std::move(gridItemDeepRenderFunc), isLazy);
84 }
85
SetColumnStart(int32_t columnStart)86 void JSGridItem::SetColumnStart(int32_t columnStart)
87 {
88 GridItemModel::GetInstance()->SetColumnStart(columnStart);
89 }
90
SetColumnEnd(int32_t columnEnd)91 void JSGridItem::SetColumnEnd(int32_t columnEnd)
92 {
93 GridItemModel::GetInstance()->SetColumnEnd(columnEnd);
94 }
95
SetRowStart(int32_t rowStart)96 void JSGridItem::SetRowStart(int32_t rowStart)
97 {
98 GridItemModel::GetInstance()->SetRowStart(rowStart);
99 }
100
SetRowEnd(int32_t rowEnd)101 void JSGridItem::SetRowEnd(int32_t rowEnd)
102 {
103 GridItemModel::GetInstance()->SetRowEnd(rowEnd);
104 }
105
ForceRebuild(bool forceRebuild)106 void JSGridItem::ForceRebuild(bool forceRebuild)
107 {
108 GridItemModel::GetInstance()->SetForceRebuild(forceRebuild);
109 }
110
SetSelectable(bool selectable)111 void JSGridItem::SetSelectable(bool selectable)
112 {
113 GridItemModel::GetInstance()->SetSelectable(selectable);
114 }
115
SelectCallback(const JSCallbackInfo & args)116 void JSGridItem::SelectCallback(const JSCallbackInfo& args)
117 {
118 if (!args[0]->IsFunction()) {
119 LOGE("fail to bind onSelect event due to info is not function");
120 return;
121 }
122
123 RefPtr<JsMouseFunction> jsOnSelectFunc = AceType::MakeRefPtr<JsMouseFunction>(JSRef<JSFunc>::Cast(args[0]));
124 auto onSelectId = [execCtx = args.GetExecutionContext(), func = std::move(jsOnSelectFunc)](bool isSelected) {
125 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
126 func->SelectExecute(isSelected);
127 };
128 GridItemModel::GetInstance()->SetOnSelect(std::move(onSelectId));
129 }
130
SetSelected(const JSCallbackInfo & info)131 void JSGridItem::SetSelected(const JSCallbackInfo& info)
132 {
133 if (info.Length() < 1) {
134 LOGW("The arg is wrong, it is supposed to have 1 or 2 arguments");
135 return;
136 }
137 bool select = false;
138 if (info[0]->IsBoolean()) {
139 select = info[0]->ToBoolean();
140 }
141 GridItemModel::GetInstance()->SetSelected(select);
142
143 if (info.Length() > 1 && info[1]->IsFunction()) {
144 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(info[1]));
145 auto changeEvent = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](bool param) {
146 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
147 ACE_SCORING_EVENT("GridItem.ChangeEvent");
148 auto newJSVal = JSRef<JSVal>::Make(ToJSValue(param));
149 func->ExecuteJS(1, &newJSVal);
150 };
151 GridItemModel::GetInstance()->SetSelectChangeEvent(std::move(changeEvent));
152 }
153 }
154
JSBind(BindingTarget globalObj)155 void JSGridItem::JSBind(BindingTarget globalObj)
156 {
157 LOGD("GridItem:JSBind");
158 JSClass<JSGridItem>::Declare("GridItem");
159
160 MethodOptions opt = MethodOptions::NONE;
161 JSClass<JSGridItem>::StaticMethod("create", &JSGridItem::Create, opt);
162 JSClass<JSGridItem>::StaticMethod("columnStart", &JSGridItem::SetColumnStart, opt);
163 JSClass<JSGridItem>::StaticMethod("columnEnd", &JSGridItem::SetColumnEnd, opt);
164 JSClass<JSGridItem>::StaticMethod("rowStart", &JSGridItem::SetRowStart, opt);
165 JSClass<JSGridItem>::StaticMethod("rowEnd", &JSGridItem::SetRowEnd, opt);
166 JSClass<JSGridItem>::StaticMethod("forceRebuild", &JSGridItem::ForceRebuild, opt);
167 JSClass<JSGridItem>::StaticMethod("selectable", &JSGridItem::SetSelectable, opt);
168 JSClass<JSGridItem>::StaticMethod("onSelect", &JSGridItem::SelectCallback);
169 JSClass<JSGridItem>::StaticMethod("width", &JSGridItem::SetGridItemWidth);
170 JSClass<JSGridItem>::StaticMethod("height", &JSGridItem::SetGridItemHeight);
171 JSClass<JSGridItem>::StaticMethod("selected", &JSGridItem::SetSelected);
172 JSClass<JSGridItem>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
173 JSClass<JSGridItem>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
174 JSClass<JSGridItem>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
175 JSClass<JSGridItem>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
176 JSClass<JSGridItem>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
177 JSClass<JSGridItem>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
178 JSClass<JSGridItem>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
179 JSClass<JSGridItem>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
180
181 JSClass<JSGridItem>::InheritAndBind<JSContainerBase>(globalObj);
182 }
183
184 } // namespace OHOS::Ace::Framework
185