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_stack.h"
17
18 #include "base/log/ace_trace.h"
19 #include "core/common/container.h"
20 #include "frameworks/bridge/declarative_frontend/engine/js_ref_ptr.h"
21 #include "frameworks/bridge/declarative_frontend/jsview/js_view_common_def.h"
22 #include "frameworks/bridge/declarative_frontend/jsview/models/stack_model_impl.h"
23 #include "frameworks/core/components_ng/pattern/stack/stack_model_ng.h"
24
25 namespace OHOS::Ace {
26
27 std::unique_ptr<StackModel> StackModel::instance_ = nullptr;
28
GetInstance()29 StackModel* StackModel::GetInstance()
30 {
31 if (!instance_) {
32 #ifdef NG_BUILD
33 instance_.reset(new NG::StackModelNG());
34 #else
35 if (Container::IsCurrentUseNewPipeline()) {
36 instance_.reset(new NG::StackModelNG());
37 } else {
38 instance_.reset(new Framework::StackModelImpl());
39 }
40 #endif
41 }
42 return instance_.get();
43 }
44 } // namespace OHOS::Ace
45 namespace OHOS::Ace::Framework {
46
47 const static std::array<Alignment, 9> ALIGNMENT_ARR { Alignment::TOP_LEFT, Alignment::TOP_CENTER, Alignment::TOP_RIGHT,
48 Alignment::CENTER_LEFT, Alignment::CENTER, Alignment::CENTER_RIGHT, Alignment::BOTTOM_LEFT,
49 Alignment::BOTTOM_CENTER, Alignment::BOTTOM_RIGHT };
50
SetStackFit(int value)51 void JSStack::SetStackFit(int value)
52 {
53 if (value >= static_cast<int>(StackFit::KEEP) && value <= static_cast<int>(StackFit::FIRST_CHILD)) {
54 StackModel::GetInstance()->SetStackFit(static_cast<StackFit>(value));
55 } else {
56 LOGE("Invalid value for stackfit");
57 }
58 }
59
SetOverflow(int value)60 void JSStack::SetOverflow(int value)
61 {
62 if (value >= static_cast<int>(Overflow::CLIP) && value <= static_cast<int>(Overflow::OBSERVABLE)) {
63 StackModel::GetInstance()->SetOverflow(static_cast<Overflow>(value));
64 } else {
65 LOGE("Invalid value for overflow");
66 }
67 }
68
SetAlignment(int value)69 void JSStack::SetAlignment(int value)
70 {
71 Alignment alignment = Alignment::TOP_LEFT;
72
73 switch (value) {
74 case 0:
75 alignment = Alignment::TOP_LEFT;
76 break;
77 case 1:
78 alignment = Alignment::TOP_CENTER;
79 break;
80 case 2:
81 alignment = Alignment::TOP_RIGHT;
82 break;
83 case 3:
84 alignment = Alignment::CENTER_LEFT;
85 break;
86 case 4:
87 alignment = Alignment::CENTER;
88 break;
89 case 5:
90 alignment = Alignment::CENTER_RIGHT;
91 break;
92 case 6:
93 alignment = Alignment::BOTTOM_LEFT;
94 break;
95 case 7:
96 alignment = Alignment::BOTTOM_CENTER;
97 break;
98 case 8:
99 alignment = Alignment::BOTTOM_RIGHT;
100 break;
101 default:
102 LOGE("Invalid value for alignment");
103 return;
104 }
105
106 StackModel::GetInstance()->SetAlignment(alignment);
107 }
108
SetWidth(const JSCallbackInfo & info)109 void JSStack::SetWidth(const JSCallbackInfo& info)
110 {
111 if (info.Length() < 1) {
112 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
113 return;
114 }
115
116 SetWidth(info[0]);
117 }
118
SetWidth(const JSRef<JSVal> & jsValue)119 void JSStack::SetWidth(const JSRef<JSVal>& jsValue)
120 {
121 JSViewAbstract::JsWidth(jsValue);
122 StackModel::GetInstance()->SetHasWidth();
123 }
124
SetHeight(const JSCallbackInfo & info)125 void JSStack::SetHeight(const JSCallbackInfo& info)
126 {
127 if (info.Length() < 1) {
128 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
129 return;
130 }
131
132 SetHeight(info[0]);
133 }
134
SetHeight(const JSRef<JSVal> & jsValue)135 void JSStack::SetHeight(const JSRef<JSVal>& jsValue)
136 {
137 JSViewAbstract::JsHeight(jsValue);
138 StackModel::GetInstance()->SetHasHeight();
139 }
140
SetSize(const JSCallbackInfo & info)141 void JSStack::SetSize(const JSCallbackInfo& info)
142 {
143 if (info.Length() < 1) {
144 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
145 return;
146 }
147
148 if (!info[0]->IsObject()) {
149 LOGE("arg is not Object or String.");
150 return;
151 }
152
153 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
154 SetWidth(sizeObj->GetProperty("width"));
155 SetHeight(sizeObj->GetProperty("height"));
156 }
157
Create(const JSCallbackInfo & info)158 void JSStack::Create(const JSCallbackInfo& info)
159 {
160 Alignment alignment = Alignment::CENTER;
161
162 if (info.Length() > 0 && info[0]->IsObject()) {
163 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
164 JSRef<JSVal> stackAlign = obj->GetProperty("alignContent");
165 if (stackAlign->IsNumber()) {
166 int32_t value = stackAlign->ToNumber<int32_t>();
167 alignment = (value >= 0 && value < static_cast<int>(ALIGNMENT_ARR.size())) ? ALIGNMENT_ARR[value]
168 : Alignment::CENTER;
169 }
170 }
171
172 StackModel::GetInstance()->Create(alignment);
173 }
174
JSBind(BindingTarget globalObj)175 void JSStack::JSBind(BindingTarget globalObj)
176 {
177 JSClass<JSStack>::Declare("Stack");
178
179 MethodOptions opt = MethodOptions::NONE;
180 JSClass<JSStack>::StaticMethod("create", &JSStack::Create, opt);
181 JSClass<JSStack>::StaticMethod("stackFit", &JSStack::SetStackFit, opt);
182 JSClass<JSStack>::StaticMethod("overflow", &JSStack::SetOverflow, opt);
183 JSClass<JSStack>::StaticMethod("alignContent", &JSStack::SetAlignment, opt);
184 JSClass<JSStack>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
185 JSClass<JSStack>::StaticMethod("width", SetWidth);
186 JSClass<JSStack>::StaticMethod("height", SetHeight);
187 JSClass<JSStack>::StaticMethod("size", SetSize);
188 JSClass<JSStack>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
189 JSClass<JSStack>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
190 JSClass<JSStack>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
191 JSClass<JSStack>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
192 JSClass<JSStack>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
193 JSClass<JSStack>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
194 JSClass<JSStack>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
195 JSClass<JSStack>::Inherit<JSContainerBase>();
196 JSClass<JSStack>::Inherit<JSViewAbstract>();
197 JSClass<JSStack>::Bind<>(globalObj);
198 }
199
200 } // namespace OHOS::Ace::Framework
201