• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_water_flow.h"
17 
18 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
19 #include "frameworks/bridge/declarative_frontend/jsview/js_interactable_view.h"
20 #include "frameworks/bridge/declarative_frontend/jsview/js_scroller.h"
21 #include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
22 #include "frameworks/core/components_v2/water_flow/water_flow_component.h"
23 
24 namespace OHOS::Ace::Framework {
25 namespace {
26 const std::vector<FlexDirection> LAYOUT_DIRECTION = { FlexDirection::ROW, FlexDirection::COLUMN,
27     FlexDirection::ROW_REVERSE, FlexDirection::COLUMN_REVERSE };
28 } // namespace
29 
Create(const JSCallbackInfo & args)30 void JSWaterFlow::Create(const JSCallbackInfo& args)
31 {
32     LOGI("Create component: WaterFLow");
33     if (args.Length() > 1) {
34         LOGW("Arg is wrong, it is supposed to have at most one argument");
35         return;
36     }
37 
38     // create waterflow component
39     std::list<RefPtr<OHOS::Ace::Component>> componentChildren;
40     auto waterflowComponent = AceType::MakeRefPtr<V2::WaterFlowComponent>(componentChildren);
41     CHECK_NULL_VOID(waterflowComponent);
42 
43     if (args.Length() == 1) {
44         if (!args[0]->IsObject()) {
45             LOGE("The arg must be object");
46             return;
47         }
48         JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
49         auto footerObject = obj->GetProperty("footer");
50         if (footerObject->IsFunction()) {
51             ScopedViewStackProcessor builderViewStackProcessor;
52             auto builderFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSFunc>::Cast(footerObject));
53             builderFunc->Execute();
54             RefPtr<Component> customComponent = ViewStackProcessor::GetInstance()->Finish();
55             waterflowComponent->SetFooterComponent(customComponent);
56         }
57         auto scroller = obj->GetProperty("scroller");
58         if (scroller->IsObject()) {
59             auto *jsScroller = JSRef<JSObject>::Cast(scroller)->Unwrap<JSScroller>();
60             CHECK_NULL_VOID(jsScroller);
61             auto positionController = AceType::MakeRefPtr<V2::WaterFlowPositionController>();
62             jsScroller->SetController(positionController);
63             waterflowComponent->SetController(positionController);
64             // Init scroll bar proxy.
65             auto proxy = AceType::DynamicCast<ScrollBarProxy>(jsScroller->GetScrollBarProxy());
66             if (!proxy) {
67                 proxy = AceType::MakeRefPtr<ScrollBarProxy>();
68                 jsScroller->SetScrollBarProxy(proxy);
69             }
70             waterflowComponent->SetScrollBarProxy(proxy);
71         }
72     }
73     ViewStackProcessor::GetInstance()->Push(waterflowComponent);
74 }
75 
JSBind(BindingTarget globalObj)76 void JSWaterFlow::JSBind(BindingTarget globalObj)
77 {
78     LOGD("JSWaterFlow:JSBind");
79     JSClass<JSWaterFlow>::Declare("WaterFlow");
80 
81     MethodOptions opt = MethodOptions::NONE;
82     JSClass<JSWaterFlow>::StaticMethod("create", &JSWaterFlow::Create, opt);
83     JSClass<JSWaterFlow>::StaticMethod("columnsGap", &JSWaterFlow::SetColumnsGap, opt);
84     JSClass<JSWaterFlow>::StaticMethod("rowsGap", &JSWaterFlow::SetRowsGap, opt);
85     JSClass<JSWaterFlow>::StaticMethod("layoutDirection", &JSWaterFlow::SetLayoutDirection, opt);
86     JSClass<JSWaterFlow>::StaticMethod("columnsTemplate", &JSWaterFlow::SetColumnsTemplate, opt);
87     JSClass<JSWaterFlow>::StaticMethod("itemConstraintSize", &JSWaterFlow::SetItemConstraintSize, opt);
88     JSClass<JSWaterFlow>::StaticMethod("rowsTemplate", &JSWaterFlow::SetRowsTemplate, opt);
89     JSClass<JSWaterFlow>::StaticMethod("onReachStart", &JSWaterFlow::ReachStartCallback);
90     JSClass<JSWaterFlow>::StaticMethod("onReachEnd", &JSWaterFlow::ReachEndCallback);
91     JSClass<JSWaterFlow>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
92     JSClass<JSWaterFlow>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
93     JSClass<JSWaterFlow>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
94     JSClass<JSWaterFlow>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
95     JSClass<JSWaterFlow>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
96     JSClass<JSWaterFlow>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
97     JSClass<JSWaterFlow>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
98     JSClass<JSWaterFlow>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
99 
100     JSClass<JSWaterFlow>::Inherit<JSContainerBase>();
101     JSClass<JSWaterFlow>::Inherit<JSViewAbstract>();
102     JSClass<JSWaterFlow>::Bind<>(globalObj);
103 }
104 
SetColumnsGap(const JSCallbackInfo & info)105 void JSWaterFlow::SetColumnsGap(const JSCallbackInfo& info)
106 {
107     if (info.Length() < 1) {
108         LOGW("Arg is wrong, it is supposed to have at least 1 argument");
109         return;
110     }
111     Dimension colGap;
112     if (!ParseJsDimensionVp(info[0], colGap)) {
113         return;
114     }
115     auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
116     auto waterflow = AceType::DynamicCast<V2::WaterFlowComponent>(component);
117     if (waterflow) {
118         waterflow->SetColumnsGap(colGap);
119     }
120 }
121 
SetRowsGap(const JSCallbackInfo & info)122 void JSWaterFlow::SetRowsGap(const JSCallbackInfo& info)
123 {
124     if (info.Length() < 1) {
125         LOGW("Arg is wrong, it is supposed to have at least 1 argument");
126         return;
127     }
128     Dimension rowGap;
129     if (!ParseJsDimensionVp(info[0], rowGap)) {
130         return;
131     }
132     auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
133     auto waterflow = AceType::DynamicCast<V2::WaterFlowComponent>(component);
134     if (waterflow) {
135         waterflow->SetRowsGap(rowGap);
136     }
137 }
138 
SetLayoutDirection(int32_t value)139 void JSWaterFlow::SetLayoutDirection(int32_t value)
140 {
141     if (value >= 0 && value < static_cast<int32_t>(LAYOUT_DIRECTION.size())) {
142         auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
143         auto waterflow = AceType::DynamicCast<V2::WaterFlowComponent>(component);
144         if (waterflow) {
145             waterflow->SetLayoutDirection(LAYOUT_DIRECTION[value]);
146         }
147     }
148 }
SetColumnsTemplate(const std::string & value)149 void JSWaterFlow::SetColumnsTemplate(const std::string& value)
150 {
151     auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
152     auto waterflow = AceType::DynamicCast<V2::WaterFlowComponent>(component);
153     if (waterflow) {
154         waterflow->SetColumnsArgs(value);
155     }
156 }
157 
SetItemConstraintSize(const JSCallbackInfo & info)158 void JSWaterFlow::SetItemConstraintSize(const JSCallbackInfo& info)
159 {
160     if (info.Length() < 1 || !info[0]->IsObject()) {
161         LOGI("waterflow create error, info is invalid");
162         return;
163     }
164     auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
165     auto waterflow = AceType::DynamicCast<V2::WaterFlowComponent>(component);
166     JSRef<JSObject> sizeObj = JSRef<JSObject>::Cast(info[0]);
167 
168     JSRef<JSVal> minWidthValue = sizeObj->GetProperty("minWidth");
169     Dimension minWidth;
170     if (ParseJsDimensionVp(minWidthValue, minWidth)) {
171         waterflow->SetMinWidth(minWidth);
172     }
173 
174     JSRef<JSVal> maxWidthValue = sizeObj->GetProperty("maxWidth");
175     Dimension maxWidth;
176     if (ParseJsDimensionVp(maxWidthValue, maxWidth)) {
177         waterflow->SetMaxWidth(maxWidth);
178     }
179 
180     JSRef<JSVal> minHeightValue = sizeObj->GetProperty("minHeight");
181     Dimension minHeight;
182     if (ParseJsDimensionVp(minHeightValue, minHeight)) {
183         waterflow->SetMinHeight(minHeight);
184     }
185 
186     JSRef<JSVal> maxHeightValue = sizeObj->GetProperty("maxHeight");
187     Dimension maxHeight;
188     if (ParseJsDimensionVp(maxHeightValue, maxHeight)) {
189         waterflow->SetMaxHeight(maxHeight);
190     }
191 }
192 
SetRowsTemplate(const std::string & value)193 void JSWaterFlow::SetRowsTemplate(const std::string& value)
194 {
195     auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
196     auto waterflow = AceType::DynamicCast<V2::WaterFlowComponent>(component);
197     if (waterflow) {
198         waterflow->SetRowsArgs(value);
199     }
200 }
201 
ReachStartCallback(const JSCallbackInfo & args)202 void JSWaterFlow::ReachStartCallback(const JSCallbackInfo& args)
203 {
204     if (!JSViewBindEvent(&V2::WaterFlowComponent::SetOnReachStart, args)) {
205         LOGW("Failed to bind event");
206     }
207     args.ReturnSelf();
208 }
209 
ReachEndCallback(const JSCallbackInfo & args)210 void JSWaterFlow::ReachEndCallback(const JSCallbackInfo& args)
211 {
212     if (!JSViewBindEvent(&V2::WaterFlowComponent::SetOnReachEnd, args)) {
213         LOGW("Failed to bind event");
214     }
215     args.ReturnSelf();
216 }
217 } // namespace OHOS::Ace::Framework
218