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_flex_impl.h"
17
18 #include "core/components_ng/pattern/flex/flex_model.h"
19 #include "frameworks/bridge/declarative_frontend/engine/js_ref_ptr.h"
20 #include "frameworks/bridge/declarative_frontend/jsview/js_view_common_def.h"
21 #include "frameworks/bridge/declarative_frontend/jsview/models/flex_model_impl.h"
22 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
23 #include "frameworks/core/components_ng/pattern/flex/flex_model_ng.h"
24
25 namespace OHOS::Ace::Framework {
26
Create(const JSCallbackInfo & info)27 void JSFlexImpl::Create(const JSCallbackInfo& info)
28 {
29 if (info.Length() < 1) {
30 LOGD("No input args, use default row setting");
31 FlexModel::GetInstance()->CreateFlexRow();
32 return;
33 }
34 if (!info[0]->IsObject()) {
35 LOGD("arg is not a object, use default row setting");
36 FlexModel::GetInstance()->CreateFlexRow();
37 return;
38 }
39 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
40 JSRef<JSVal> wrapVal = obj->GetProperty("wrap");
41 if (wrapVal->IsNumber()) {
42 auto wrapNum = wrapVal->ToNumber<int32_t>();
43 if (wrapNum == 0) {
44 CreateFlexComponent(info);
45 } else {
46 CreateWrapComponent(info, wrapNum);
47 }
48 } else {
49 CreateFlexComponent(info);
50 }
51 }
52
CreateFlexComponent(const JSCallbackInfo & info)53 void JSFlexImpl::CreateFlexComponent(const JSCallbackInfo& info)
54 {
55 if (info.Length() < 1) {
56 FlexModel::GetInstance()->CreateFlexRow();
57 return;
58 }
59 if (!info[0]->IsObject()) {
60 FlexModel::GetInstance()->CreateFlexRow();
61 return;
62 }
63 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
64 JSRef<JSVal> directionVal = obj->GetProperty("direction");
65 JSRef<JSVal> justifyVal = obj->GetProperty("justifyContent");
66 JSRef<JSVal> alignItemVal = obj->GetProperty("alignItems");
67 FlexModel::GetInstance()->CreateFlexRow();
68 if (directionVal->IsNumber()) {
69 auto direction = directionVal->ToNumber<int32_t>();
70 if (direction >= 0 && direction <= DIRECTION_MAX_VALUE) {
71 FlexModel::GetInstance()->SetDirection(static_cast<FlexDirection>(direction));
72 }
73 }
74 if (justifyVal->IsNumber()) {
75 auto mainAlign = justifyVal->ToNumber<int32_t>();
76 if (mainAlign >= 0 && mainAlign <= MAIN_ALIGN_MAX_VALUE) {
77 FlexModel::GetInstance()->SetMainAxisAlign(static_cast<FlexAlign>(mainAlign));
78 }
79 }
80 if (alignItemVal->IsNumber()) {
81 auto crossAlign = alignItemVal->ToNumber<int32_t>();
82 if (crossAlign >= 0 && crossAlign <= CROSS_ALIGN_MAX_VALUE) {
83 FlexModel::GetInstance()->SetCrossAxisAlign(static_cast<FlexAlign>(crossAlign));
84 }
85 }
86 }
87
CreateWrapComponent(const JSCallbackInfo & info,int32_t wrapVal)88 void JSFlexImpl::CreateWrapComponent(const JSCallbackInfo& info, int32_t wrapVal)
89 {
90 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
91 JSRef<JSVal> directionVal = obj->GetProperty("direction");
92 JSRef<JSVal> justifyVal = obj->GetProperty("justifyContent");
93 JSRef<JSVal> alignItemVal = obj->GetProperty("alignItems");
94 JSRef<JSVal> alignContentVal = obj->GetProperty("alignContent");
95 FlexModel::GetInstance()->CreateWrap();
96 if (directionVal->IsNumber()) {
97 auto direction = directionVal->ToNumber<int32_t>();
98 if (direction >= 0 && direction <= DIRECTION_MAX_VALUE) {
99 FlexModel::GetInstance()->SetDirection(static_cast<FlexDirection>(direction));
100 // WrapReverse means wrapVal = 2. Wrap means wrapVal = 1.
101 if (direction <= 1) {
102 direction += 2 * (wrapVal - 1);
103 } else {
104 direction -= 2 * (wrapVal - 1);
105 }
106 FlexModel::GetInstance()->SetWrapDirection(static_cast<WrapDirection>(direction));
107 }
108 } else {
109 // No direction set case: wrapVal == 2 means FlexWrap.WrapReverse.
110 WrapDirection wrapDirection = wrapVal == 2 ? WrapDirection::HORIZONTAL_REVERSE : WrapDirection::HORIZONTAL;
111 FlexModel::GetInstance()->SetWrapDirection(wrapDirection);
112 }
113 if (justifyVal->IsNumber()) {
114 auto mainAlign = justifyVal->ToNumber<int32_t>();
115 if (mainAlign >= 0 && mainAlign <= MAIN_ALIGN_MAX_VALUE) {
116 FlexModel::GetInstance()->SetWrapMainAlignment(WRAP_TABLE[mainAlign]);
117 }
118 }
119 if (alignItemVal->IsNumber()) {
120 auto crossAlign = alignItemVal->ToNumber<int32_t>();
121 if (crossAlign >= 0 && crossAlign <= CROSS_ALIGN_MAX_VALUE) {
122 FlexModel::GetInstance()->SetWrapCrossAlignment(WRAP_TABLE[crossAlign]);
123 }
124 }
125 if (alignContentVal->IsNumber()) {
126 auto alignContent = alignContentVal->ToNumber<int32_t>();
127 if (alignContent >= 0 && alignContent <= MAIN_ALIGN_MAX_VALUE) {
128 FlexModel::GetInstance()->SetWrapAlignment(WRAP_TABLE[alignContent]);
129 }
130 }
131 }
132
JsFlexWidth(const JSCallbackInfo & info)133 void JSFlexImpl::JsFlexWidth(const JSCallbackInfo& info)
134 {
135 if (info.Length() < 1) {
136 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
137 return;
138 }
139
140 JsFlexWidth(info[0]);
141 }
142
JsFlexWidth(const JSRef<JSVal> & jsValue)143 void JSFlexImpl::JsFlexWidth(const JSRef<JSVal>& jsValue)
144 {
145 JSViewAbstract::JsWidth(jsValue);
146 FlexModel::GetInstance()->SetFlexWidth();
147 }
148
JsFlexHeight(const JSCallbackInfo & info)149 void JSFlexImpl::JsFlexHeight(const JSCallbackInfo& info)
150 {
151 if (info.Length() < 1) {
152 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
153 return;
154 }
155
156 JsFlexHeight(info[0]);
157 }
158
JsFlexHeight(const JSRef<JSVal> & jsValue)159 void JSFlexImpl::JsFlexHeight(const JSRef<JSVal>& jsValue)
160 {
161 JSViewAbstract::JsHeight(jsValue);
162 FlexModel::GetInstance()->SetFlexHeight();
163 }
164
JsFlexSize(const JSCallbackInfo & info)165 void JSFlexImpl::JsFlexSize(const JSCallbackInfo& info)
166 {
167 if (info.Length() < 1) {
168 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
169 return;
170 }
171
172 if (!info[0]->IsObject()) {
173 LOGE("arg is not Object or String.");
174 return;
175 }
176
177 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
178 JsFlexWidth(sizeObj->GetProperty("width"));
179 JsFlexHeight(sizeObj->GetProperty("height"));
180 }
181
JSBind(BindingTarget globalObj)182 void JSFlexImpl::JSBind(BindingTarget globalObj)
183 {
184 JSClass<JSFlexImpl>::Declare("Flex");
185 MethodOptions opt = MethodOptions::NONE;
186 JSClass<JSFlexImpl>::StaticMethod("create", &JSFlexImpl::Create, opt);
187
188 JSClass<JSFlexImpl>::StaticMethod("width", &JSFlexImpl::JsFlexWidth);
189 JSClass<JSFlexImpl>::StaticMethod("height", &JSFlexImpl::JsFlexHeight);
190 JSClass<JSFlexImpl>::StaticMethod("size", &JSFlexImpl::JsFlexSize);
191
192 JSClass<JSFlexImpl>::StaticMethod("fillParent", &JSFlex::SetFillParent, opt);
193 JSClass<JSFlexImpl>::StaticMethod("wrapContent", &JSFlex::SetWrapContent, opt);
194 JSClass<JSFlexImpl>::StaticMethod("justifyContent", &JSFlex::SetJustifyContent, opt);
195 JSClass<JSFlexImpl>::StaticMethod("alignItems", &JSFlex::SetAlignItems, opt);
196 JSClass<JSFlexImpl>::StaticMethod("alignContent", &JSFlex::SetAlignContent, opt);
197 JSClass<JSFlexImpl>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
198 JSClass<JSFlexImpl>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
199 JSClass<JSFlexImpl>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
200 JSClass<JSFlexImpl>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
201 JSClass<JSFlexImpl>::StaticMethod("onPan", &JSInteractableView::JsOnPan);
202 JSClass<JSFlexImpl>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
203 JSClass<JSFlexImpl>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
204 JSClass<JSFlexImpl>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
205 JSClass<JSFlexImpl>::Inherit<JSContainerBase>();
206 JSClass<JSFlexImpl>::Inherit<JSViewAbstract>();
207 JSClass<JSFlexImpl>::Bind<>(globalObj);
208 }
209
210 } // namespace OHOS::Ace::Framework
211