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 } else if (PipelineBase::GetCurrentContext() && PipelineBase::GetCurrentContext()->GetMinPlatformVersion() > 9) {
80 FlexModel::GetInstance()->SetMainAxisAlign(FlexAlign::FLEX_START);
81 }
82 if (alignItemVal->IsNumber()) {
83 auto crossAlign = alignItemVal->ToNumber<int32_t>();
84 if (crossAlign >= 0 && crossAlign <= CROSS_ALIGN_MAX_VALUE) {
85 FlexModel::GetInstance()->SetCrossAxisAlign(static_cast<FlexAlign>(crossAlign));
86 }
87 } else if (PipelineBase::GetCurrentContext() && PipelineBase::GetCurrentContext()->GetMinPlatformVersion() > 9) {
88 FlexModel::GetInstance()->SetCrossAxisAlign(FlexAlign::FLEX_START);
89 }
90 }
91
CreateWrapComponent(const JSCallbackInfo & info,int32_t wrapVal)92 void JSFlexImpl::CreateWrapComponent(const JSCallbackInfo& info, int32_t wrapVal)
93 {
94 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
95 JSRef<JSVal> directionVal = obj->GetProperty("direction");
96 JSRef<JSVal> justifyVal = obj->GetProperty("justifyContent");
97 JSRef<JSVal> alignItemVal = obj->GetProperty("alignItems");
98 JSRef<JSVal> alignContentVal = obj->GetProperty("alignContent");
99 FlexModel::GetInstance()->CreateWrap();
100 if (directionVal->IsNumber()) {
101 auto direction = directionVal->ToNumber<int32_t>();
102 if (direction >= 0 && direction <= DIRECTION_MAX_VALUE) {
103 FlexModel::GetInstance()->SetDirection(static_cast<FlexDirection>(direction));
104 // WrapReverse means wrapVal = 2. Wrap means wrapVal = 1.
105 if (direction <= 1) {
106 direction += 2 * (wrapVal - 1);
107 } else {
108 direction -= 2 * (wrapVal - 1);
109 }
110 FlexModel::GetInstance()->SetWrapDirection(static_cast<WrapDirection>(direction));
111 }
112 } else {
113 // No direction set case: wrapVal == 2 means FlexWrap.WrapReverse.
114 WrapDirection wrapDirection = wrapVal == 2 ? WrapDirection::HORIZONTAL_REVERSE : WrapDirection::HORIZONTAL;
115 FlexModel::GetInstance()->SetWrapDirection(wrapDirection);
116 }
117 if (justifyVal->IsNumber()) {
118 auto mainAlign = justifyVal->ToNumber<int32_t>();
119 if (mainAlign >= 0 && mainAlign <= MAIN_ALIGN_MAX_VALUE) {
120 FlexModel::GetInstance()->SetWrapMainAlignment(WRAP_TABLE[mainAlign]);
121 }
122 }
123 if (alignItemVal->IsNumber()) {
124 auto crossAlign = alignItemVal->ToNumber<int32_t>();
125 if (crossAlign >= 0 && crossAlign <= CROSS_ALIGN_MAX_VALUE) {
126 FlexModel::GetInstance()->SetWrapCrossAlignment(WRAP_TABLE[crossAlign]);
127 }
128 }
129 if (alignContentVal->IsNumber()) {
130 auto alignContent = alignContentVal->ToNumber<int32_t>();
131 if (alignContent >= 0 && alignContent <= MAIN_ALIGN_MAX_VALUE) {
132 FlexModel::GetInstance()->SetWrapAlignment(WRAP_TABLE[alignContent]);
133 }
134 }
135 }
136
JsFlexWidth(const JSCallbackInfo & info)137 void JSFlexImpl::JsFlexWidth(const JSCallbackInfo& info)
138 {
139 if (info.Length() < 1) {
140 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
141 return;
142 }
143
144 JsFlexWidth(info[0]);
145 }
146
JsFlexWidth(const JSRef<JSVal> & jsValue)147 void JSFlexImpl::JsFlexWidth(const JSRef<JSVal>& jsValue)
148 {
149 JSViewAbstract::JsWidth(jsValue);
150 FlexModel::GetInstance()->SetFlexWidth();
151 }
152
JsFlexHeight(const JSCallbackInfo & info)153 void JSFlexImpl::JsFlexHeight(const JSCallbackInfo& info)
154 {
155 if (info.Length() < 1) {
156 LOGE("The arg is wrong, it is supposed to have at least 1 arguments");
157 return;
158 }
159
160 JsFlexHeight(info[0]);
161 }
162
JsFlexHeight(const JSRef<JSVal> & jsValue)163 void JSFlexImpl::JsFlexHeight(const JSRef<JSVal>& jsValue)
164 {
165 JSViewAbstract::JsHeight(jsValue);
166 FlexModel::GetInstance()->SetFlexHeight();
167 }
168
JsFlexSize(const JSCallbackInfo & info)169 void JSFlexImpl::JsFlexSize(const JSCallbackInfo& info)
170 {
171 if (info.Length() < 1) {
172 LOGE("The arg is wrong, it is supposed to have atleast 1 arguments");
173 return;
174 }
175
176 if (!info[0]->IsObject()) {
177 LOGE("arg is not Object or String.");
178 return;
179 }
180
181 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
182 JsFlexWidth(sizeObj->GetProperty("width"));
183 JsFlexHeight(sizeObj->GetProperty("height"));
184 }
185
JSBind(BindingTarget globalObj)186 void JSFlexImpl::JSBind(BindingTarget globalObj)
187 {
188 JSClass<JSFlexImpl>::Declare("Flex");
189 MethodOptions opt = MethodOptions::NONE;
190 JSClass<JSFlexImpl>::StaticMethod("create", &JSFlexImpl::Create, opt);
191
192 JSClass<JSFlexImpl>::StaticMethod("width", &JSFlexImpl::JsFlexWidth);
193 JSClass<JSFlexImpl>::StaticMethod("height", &JSFlexImpl::JsFlexHeight);
194 JSClass<JSFlexImpl>::StaticMethod("size", &JSFlexImpl::JsFlexSize);
195
196 JSClass<JSFlexImpl>::StaticMethod("fillParent", &JSFlex::SetFillParent, opt);
197 JSClass<JSFlexImpl>::StaticMethod("wrapContent", &JSFlex::SetWrapContent, opt);
198 JSClass<JSFlexImpl>::StaticMethod("justifyContent", &JSFlex::SetJustifyContent, opt);
199 JSClass<JSFlexImpl>::StaticMethod("alignItems", &JSFlex::SetAlignItems, opt);
200 JSClass<JSFlexImpl>::StaticMethod("alignContent", &JSFlex::SetAlignContent, opt);
201 JSClass<JSFlexImpl>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
202 JSClass<JSFlexImpl>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
203 JSClass<JSFlexImpl>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
204 JSClass<JSFlexImpl>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
205 JSClass<JSFlexImpl>::StaticMethod("onPan", &JSInteractableView::JsOnPan);
206 JSClass<JSFlexImpl>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
207 JSClass<JSFlexImpl>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
208 JSClass<JSFlexImpl>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
209 JSClass<JSFlexImpl>::InheritAndBind<JSContainerBase>(globalObj);
210 }
211
212 } // namespace OHOS::Ace::Framework
213