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 FlexModel::GetInstance()->CreateFlexRow();
31 return;
32 }
33 if (!info[0]->IsObject()) {
34 FlexModel::GetInstance()->CreateFlexRow();
35 return;
36 }
37 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
38 JSRef<JSVal> wrapVal = obj->GetProperty("wrap");
39 if (wrapVal->IsNumber()) {
40 auto wrapNum = wrapVal->ToNumber<int32_t>();
41 if (wrapNum == 0) {
42 CreateFlexComponent(info);
43 } else {
44 CreateWrapComponent(info, wrapNum);
45 }
46 } else {
47 CreateFlexComponent(info);
48 }
49 }
50
CreateFlexComponent(const JSCallbackInfo & info)51 void JSFlexImpl::CreateFlexComponent(const JSCallbackInfo& info)
52 {
53 if (info.Length() < 1) {
54 FlexModel::GetInstance()->CreateFlexRow();
55 return;
56 }
57 if (!info[0]->IsObject()) {
58 FlexModel::GetInstance()->CreateFlexRow();
59 return;
60 }
61 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
62 JSRef<JSVal> directionVal = obj->GetProperty("direction");
63 JSRef<JSVal> justifyVal = obj->GetProperty("justifyContent");
64 JSRef<JSVal> alignItemVal = obj->GetProperty("alignItems");
65 FlexModel::GetInstance()->CreateFlexRow();
66 if (directionVal->IsNumber()) {
67 auto direction = directionVal->ToNumber<int32_t>();
68 if (direction >= 0 && direction <= DIRECTION_MAX_VALUE) {
69 FlexModel::GetInstance()->SetDirection(static_cast<FlexDirection>(direction));
70 }
71 }
72 if (justifyVal->IsNumber()) {
73 auto mainAlign = justifyVal->ToNumber<int32_t>();
74 if (mainAlign >= 0 && mainAlign <= MAIN_ALIGN_MAX_VALUE) {
75 FlexModel::GetInstance()->SetMainAxisAlign(static_cast<FlexAlign>(mainAlign));
76 }
77 } else if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
78 FlexModel::GetInstance()->SetMainAxisAlign(FlexAlign::FLEX_START);
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 } else if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TEN)) {
86 FlexModel::GetInstance()->SetCrossAxisAlign(FlexAlign::FLEX_START);
87 }
88 }
89
CreateWrapComponent(const JSCallbackInfo & info,int32_t wrapVal)90 void JSFlexImpl::CreateWrapComponent(const JSCallbackInfo& info, int32_t wrapVal)
91 {
92 JSRef<JSObject> obj = JSRef<JSObject>::Cast(info[0]);
93 JSRef<JSVal> directionVal = obj->GetProperty("direction");
94 JSRef<JSVal> justifyVal = obj->GetProperty("justifyContent");
95 JSRef<JSVal> alignItemVal = obj->GetProperty("alignItems");
96 JSRef<JSVal> alignContentVal = obj->GetProperty("alignContent");
97 FlexModel::GetInstance()->CreateWrap();
98 if (directionVal->IsNumber()) {
99 auto direction = directionVal->ToNumber<int32_t>();
100 if (direction >= 0 && direction <= DIRECTION_MAX_VALUE) {
101 FlexModel::GetInstance()->SetDirection(static_cast<FlexDirection>(direction));
102 // WrapReverse means wrapVal = 2. Wrap means wrapVal = 1.
103 if (direction <= 1) {
104 direction += 2 * (wrapVal - 1);
105 } else {
106 direction -= 2 * (wrapVal - 1);
107 }
108 FlexModel::GetInstance()->SetWrapDirection(static_cast<WrapDirection>(direction));
109 }
110 } else {
111 // No direction set case: wrapVal == 2 means FlexWrap.WrapReverse.
112 WrapDirection wrapDirection = wrapVal == 2 ? WrapDirection::HORIZONTAL_REVERSE : WrapDirection::HORIZONTAL;
113 FlexModel::GetInstance()->SetWrapDirection(wrapDirection);
114 }
115 if (justifyVal->IsNumber()) {
116 auto mainAlign = justifyVal->ToNumber<int32_t>();
117 if (mainAlign >= 0 && mainAlign <= MAIN_ALIGN_MAX_VALUE) {
118 FlexModel::GetInstance()->SetWrapMainAlignment(WRAP_TABLE[mainAlign]);
119 }
120 }
121 if (alignItemVal->IsNumber()) {
122 auto crossAlign = alignItemVal->ToNumber<int32_t>();
123 if (crossAlign >= 0 && crossAlign <= CROSS_ALIGN_MAX_VALUE) {
124 FlexModel::GetInstance()->SetWrapCrossAlignment(WRAP_TABLE[crossAlign]);
125 }
126 }
127 if (alignContentVal->IsNumber()) {
128 auto alignContent = alignContentVal->ToNumber<int32_t>();
129 if (alignContent >= 0 && alignContent <= MAIN_ALIGN_MAX_VALUE) {
130 FlexModel::GetInstance()->SetWrapAlignment(WRAP_TABLE[alignContent]);
131 }
132 }
133 }
134
JsFlexWidth(const JSCallbackInfo & info)135 void JSFlexImpl::JsFlexWidth(const JSCallbackInfo& info)
136 {
137 if (info.Length() < 1) {
138 return;
139 }
140
141 JsFlexWidth(info[0]);
142 }
143
JsFlexWidth(const JSRef<JSVal> & jsValue)144 void JSFlexImpl::JsFlexWidth(const JSRef<JSVal>& jsValue)
145 {
146 JSViewAbstract::JsWidth(jsValue);
147 FlexModel::GetInstance()->SetFlexWidth();
148 }
149
JsFlexHeight(const JSCallbackInfo & info)150 void JSFlexImpl::JsFlexHeight(const JSCallbackInfo& info)
151 {
152 if (info.Length() < 1) {
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 return;
169 }
170
171 if (!info[0]->IsObject()) {
172 return;
173 }
174
175 JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
176 JsFlexWidth(sizeObj->GetProperty("width"));
177 JsFlexHeight(sizeObj->GetProperty("height"));
178 }
179
JSBind(BindingTarget globalObj)180 void JSFlexImpl::JSBind(BindingTarget globalObj)
181 {
182 JSClass<JSFlexImpl>::Declare("Flex");
183 MethodOptions opt = MethodOptions::NONE;
184 JSClass<JSFlexImpl>::StaticMethod("create", &JSFlexImpl::Create, opt);
185
186 JSClass<JSFlexImpl>::StaticMethod("width", &JSFlexImpl::JsFlexWidth);
187 JSClass<JSFlexImpl>::StaticMethod("height", &JSFlexImpl::JsFlexHeight);
188 JSClass<JSFlexImpl>::StaticMethod("size", &JSFlexImpl::JsFlexSize);
189
190 JSClass<JSFlexImpl>::StaticMethod("fillParent", &JSFlex::SetFillParent, opt);
191 JSClass<JSFlexImpl>::StaticMethod("wrapContent", &JSFlex::SetWrapContent, opt);
192 JSClass<JSFlexImpl>::StaticMethod("justifyContent", &JSFlex::SetJustifyContent, opt);
193 JSClass<JSFlexImpl>::StaticMethod("alignItems", &JSFlex::SetAlignItems, opt);
194 JSClass<JSFlexImpl>::StaticMethod("alignContent", &JSFlex::SetAlignContent, opt);
195 JSClass<JSFlexImpl>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
196 JSClass<JSFlexImpl>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
197 JSClass<JSFlexImpl>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
198 JSClass<JSFlexImpl>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
199 JSClass<JSFlexImpl>::StaticMethod("onPan", &JSInteractableView::JsOnPan);
200 JSClass<JSFlexImpl>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
201 JSClass<JSFlexImpl>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
202 JSClass<JSFlexImpl>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
203 JSClass<JSFlexImpl>::StaticMethod("pointLight", &JSViewAbstract::JsPointLight, opt);
204 JSClass<JSFlexImpl>::InheritAndBind<JSContainerBase>(globalObj);
205 }
206
207 } // namespace OHOS::Ace::Framework
208