1 /*
2 * Copyright (c) 2023 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_folder_stack.h"
17
18 #include <algorithm>
19
20 #include "base/log/ace_scoring_log.h"
21 #include "base/log/ace_trace.h"
22 #include "base/log/log_wrapper.h"
23 #include "core/common/container.h"
24 #include "core/components_ng/pattern/folder_stack/folder_stack_event_info.h"
25 #include "frameworks/bridge/declarative_frontend/engine/js_ref_ptr.h"
26 #include "frameworks/bridge/declarative_frontend/jsview/js_view_common_def.h"
27 #include "frameworks/bridge/declarative_frontend/jsview/models/stack_model_impl.h"
28 #include "frameworks/core/components_ng/pattern/folder_stack/folder_stack_model_ng.h"
29
30 namespace OHOS::Ace {
31 std::unique_ptr<FolderStackModel> FolderStackModel::instance_ = nullptr;
32 std::mutex FolderStackModel::mutex_;
33
GetInstance()34 FolderStackModel* FolderStackModel::GetInstance()
35 {
36 if (!instance_) {
37 std::lock_guard<std::mutex> lock(mutex_);
38 if (!instance_) {
39 #ifdef NG_BUILD
40 instance_.reset(new NG::FolderStackModelNG());
41 #else
42 if (Container::IsCurrentUseNewPipeline()) {
43 instance_.reset(new NG::FolderStackModelNG());
44 }
45 #endif
46 }
47 }
48 return instance_.get();
49 }
50 } // namespace OHOS::Ace
51 namespace OHOS::Ace::Framework {
52 const static std::array<Alignment, 9> ALIGNMENT_ARR { Alignment::TOP_LEFT, Alignment::TOP_CENTER, Alignment::TOP_RIGHT,
53 Alignment::CENTER_LEFT, Alignment::CENTER, Alignment::CENTER_RIGHT, Alignment::BOTTOM_LEFT,
54 Alignment::BOTTOM_CENTER, Alignment::BOTTOM_RIGHT };
55
FolderStackEventToJSValue(const NG::FolderEventInfo & eventInfo)56 JSRef<JSVal> FolderStackEventToJSValue(const NG::FolderEventInfo& eventInfo)
57 {
58 JSRef<JSObject> obj = JSRef<JSObject>::New();
59 obj->SetProperty("foldStatus", static_cast<int32_t>(eventInfo.GetFolderState()));
60 return JSRef<JSVal>::Cast(obj);
61 }
62
HoverStatusChangeEventToJSValue(const NG::FolderEventInfo & eventInfo)63 JSRef<JSVal> HoverStatusChangeEventToJSValue(const NG::FolderEventInfo& eventInfo)
64 {
65 JSRef<JSObject> obj = JSRef<JSObject>::New();
66 obj->SetProperty("foldStatus", static_cast<int32_t>(eventInfo.GetFolderState()));
67 obj->SetProperty("isHoverMode", static_cast<int32_t>(eventInfo.IsHoverMode()));
68 obj->SetProperty("appRotation", static_cast<int32_t>(eventInfo.GetRotation()));
69 obj->SetProperty("windowMode", static_cast<int32_t>(eventInfo.GetWindowMode()));
70 return JSRef<JSVal>::Cast(obj);
71 }
72
Create(const JSCallbackInfo & info)73 void JSFolderStack::Create(const JSCallbackInfo& info)
74 {
75 if (info[0]->IsObject()) {
76 JSRef<JSArray> params = JSRef<JSArray>::Cast(info[0]);
77 auto upperId = params->GetProperty("upperItems");
78 if (upperId->IsNull() || upperId->IsUndefined()) {
79 FolderStackModel::GetInstance()->Create();
80 return;
81 }
82 auto upperIdParams = JSRef<JSArray>::Cast(upperId);
83 auto upperItemLength = upperIdParams->Length();
84 std::vector<std::string> upperItems(upperItemLength);
85 if (upperId->IsArray()) {
86 for (size_t i = 0; i < upperItemLength; i++) {
87 upperItems[i] = upperIdParams->GetValueAt(i)->ToString();
88 }
89 }
90 FolderStackModel::GetInstance()->Create(upperItems);
91 } else {
92 FolderStackModel::GetInstance()->Create();
93 }
94 }
95
SetAlignContent(const JSCallbackInfo & info)96 void JSFolderStack::SetAlignContent(const JSCallbackInfo& info)
97 {
98 if (info.Length() != 1 || !info[0]->IsNumber()) {
99 FolderStackModel::GetInstance()->SetAlignment(Alignment::CENTER);
100 return;
101 }
102 auto value = info[0]->ToNumber<size_t>();
103 if (value < 0 || static_cast<int32_t>(value) >= static_cast<int32_t>(ALIGNMENT_ARR.size())) {
104 FolderStackModel::GetInstance()->SetAlignment(Alignment::CENTER);
105 return;
106 }
107 FolderStackModel::GetInstance()->SetAlignment(ALIGNMENT_ARR[value]);
108 }
109
JsEnableAnimation(const JSCallbackInfo & info)110 void JSFolderStack::JsEnableAnimation(const JSCallbackInfo& info)
111 {
112 if (!info[0]->IsBoolean()) {
113 FolderStackModel::GetInstance()->SetEnableAnimation(true);
114 return;
115 }
116 auto isEnableAnimation = info[0]->ToBoolean();
117 FolderStackModel::GetInstance()->SetEnableAnimation(isEnableAnimation);
118 }
119
SetAutoHalfFold(const JSCallbackInfo & info)120 void JSFolderStack::SetAutoHalfFold(const JSCallbackInfo& info)
121 {
122 if (!info[0]->IsBoolean()) {
123 FolderStackModel::GetInstance()->SetAutoHalfFold(true);
124 return;
125 }
126 auto IsAutoHalfFold = info[0]->ToBoolean();
127 FolderStackModel::GetInstance()->SetAutoHalfFold(IsAutoHalfFold);
128 }
129
JSOnFolderStateChange(const JSCallbackInfo & info)130 void JSFolderStack::JSOnFolderStateChange(const JSCallbackInfo& info)
131 {
132 if (!info[0]->IsFunction()) {
133 return;
134 }
135 auto jsFunc = AceType::MakeRefPtr<JsEventFunction<NG::FolderEventInfo, 1>>(
136 JSRef<JSFunc>::Cast(info[0]), FolderStackEventToJSValue);
137 auto onFolderStateChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](
138 const NG::FolderEventInfo& value) {
139 ACE_SCORING_EVENT("FolderStack.onFolderStateChange");
140 func->Execute(value);
141 };
142 FolderStackModel::GetInstance()->SetOnFolderStateChange(std::move(onFolderStateChange));
143 }
144
JSOnHoverStatusChange(const JSCallbackInfo & info)145 void JSFolderStack::JSOnHoverStatusChange(const JSCallbackInfo& info)
146 {
147 if (!info[0]->IsFunction()) {
148 return;
149 }
150 auto jsFunc = AceType::MakeRefPtr<JsEventFunction<NG::FolderEventInfo, 1>>(
151 JSRef<JSFunc>::Cast(info[0]), HoverStatusChangeEventToJSValue);
152 auto onHoverStatusChange = [execCtx = info.GetExecutionContext(), func = std::move(jsFunc)](
153 const NG::FolderEventInfo& value) {
154 ACE_SCORING_EVENT("FolderStack.onHoverStatusChange");
155 func->Execute(value);
156 };
157 FolderStackModel::GetInstance()->SetOnHoverStatusChange(std::move(onHoverStatusChange));
158 }
159
JSBind(BindingTarget globalObj)160 void JSFolderStack::JSBind(BindingTarget globalObj)
161 {
162 JSClass<JSFolderStack>::Declare("FolderStack");
163 JSClass<JSFolderStack>::StaticMethod("create", &JSFolderStack::Create);
164 JSClass<JSFolderStack>::StaticMethod("alignContent", &JSFolderStack::SetAlignContent);
165 JSClass<JSFolderStack>::StaticMethod("enableAnimation", &JSFolderStack::JsEnableAnimation);
166 JSClass<JSFolderStack>::StaticMethod("autoHalfFold", &JSFolderStack::SetAutoHalfFold);
167 JSClass<JSFolderStack>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
168 JSClass<JSFolderStack>::StaticMethod("onFolderStateChange", &JSFolderStack::JSOnFolderStateChange);
169 JSClass<JSFolderStack>::StaticMethod("onHoverStatusChange", &JSFolderStack::JSOnHoverStatusChange);
170 JSClass<JSFolderStack>::InheritAndBind<JSContainerBase>(globalObj);
171 }
172 } // namespace OHOS::Ace::Framework
173