• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "bridge/declarative_frontend/jsview/js_scroll.h"
17 
18 #include "bridge/declarative_frontend/jsview/js_scroller.h"
19 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
20 #include "bridge/declarative_frontend/view_stack_processor.h"
21 #include "core/components/scroll/scroll_component.h"
22 
23 namespace OHOS::Ace::Framework {
24 namespace {
25     const std::vector<DisplayMode> DISPLAY_MODE = {DisplayMode::OFF, DisplayMode::AUTO, DisplayMode::ON};
26 }
Create(const JSCallbackInfo & info)27 void JSScroll::Create(const JSCallbackInfo& info)
28 {
29     RefPtr<Component> child;
30     auto scrollComponent = AceType::MakeRefPtr<OHOS::Ace::ScrollComponent>(child);
31     if (info.Length() > 0 && info[0]->IsObject()) {
32         JSScroller* jsScroller = JSRef<JSObject>::Cast(info[0])->Unwrap<JSScroller>();
33         if (jsScroller) {
34             auto positionController = AceType::MakeRefPtr<ScrollPositionController>();
35             jsScroller->SetController(positionController);
36             scrollComponent->SetScrollPositionController(positionController);
37 
38             // Init scroll bar proxy.
39             auto proxy = jsScroller->GetScrollBarProxy();
40             if (!proxy) {
41                 proxy = AceType::MakeRefPtr<ScrollBarProxy>();
42                 jsScroller->SetScrollBarProxy(proxy);
43             }
44             scrollComponent->SetScrollBarProxy(proxy);
45         }
46     } else {
47         auto positionController = AceType::MakeRefPtr<ScrollPositionController>();
48         scrollComponent->SetScrollPositionController(positionController);
49     }
50     // init scroll bar
51     std::pair<bool, Color> barColor;
52     barColor.first = false;
53     std::pair<bool, Dimension> barWidth;
54     barWidth.first = false;
55     scrollComponent->InitScrollBar(GetTheme<ScrollBarTheme>(), barColor, barWidth, EdgeEffect::NONE);
56     ViewStackProcessor::GetInstance()->Push(scrollComponent);
57 }
58 
SetScrollable(int32_t value)59 void JSScroll::SetScrollable(int32_t value)
60 {
61     if (value >= 0 && value < 4) {
62         auto component = ViewStackProcessor::GetInstance()->GetMainComponent();
63         auto scrollComponent = AceType::DynamicCast<ScrollComponent>(component);
64         if (scrollComponent) {
65             scrollComponent->SetAxisDirection((Axis)value);
66         }
67     } else {
68         LOGE("invalid value for SetScrollable");
69     }
70 }
71 
OnScrollCallback(const JSCallbackInfo & args)72 void JSScroll::OnScrollCallback(const JSCallbackInfo& args)
73 {
74     if (args[0]->IsFunction()) {
75         auto onScroll = EventMarker(
76             [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](const BaseEventInfo* info) {
77                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
78                 auto eventInfo = TypeInfoHelper::DynamicCast<ScrollEventInfo>(info);
79                 if (!eventInfo) {
80                     return;
81                 }
82                 auto params = ConvertToJSValues(eventInfo->GetScrollX(), eventInfo->GetScrollY());
83                 func->Call(JSRef<JSObject>(), params.size(), params.data());
84             });
85         auto scrollComponent =
86             AceType::DynamicCast<ScrollComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
87         if (scrollComponent) {
88             if (!scrollComponent->GetScrollPositionController()) {
89                 scrollComponent->SetScrollPositionController(AceType::MakeRefPtr<ScrollPositionController>());
90             }
91             scrollComponent->SetOnScroll(onScroll);
92         }
93     }
94     args.SetReturnValue(args.This());
95 }
96 
OnScrollEdgeCallback(const JSCallbackInfo & args)97 void JSScroll::OnScrollEdgeCallback(const JSCallbackInfo& args)
98 {
99     if (args[0]->IsFunction()) {
100         auto onScroll = EventMarker(
101             [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](const BaseEventInfo* info) {
102                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
103                 auto eventInfo = TypeInfoHelper::DynamicCast<ScrollEventInfo>(info);
104                 if (!eventInfo) {
105                     return;
106                 }
107                 auto param = ConvertToJSValue(static_cast<int32_t>(eventInfo->GetType()));
108                 func->Call(JSRef<JSObject>(), 1, &param);
109             });
110         auto scrollComponent =
111             AceType::DynamicCast<ScrollComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
112         if (scrollComponent) {
113             if (!scrollComponent->GetScrollPositionController()) {
114                 scrollComponent->SetScrollPositionController(AceType::MakeRefPtr<ScrollPositionController>());
115             }
116             scrollComponent->SetOnScrollEdge(onScroll);
117         }
118     }
119     args.SetReturnValue(args.This());
120 }
121 
OnScrollEndCallback(const JSCallbackInfo & args)122 void JSScroll::OnScrollEndCallback(const JSCallbackInfo& args)
123 {
124     if (args[0]->IsFunction()) {
125         auto onScrollStop = EventMarker(
126             [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](const BaseEventInfo* info) {
127                 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
128                 func->Call(JSRef<JSObject>(), 0, nullptr);
129             });
130         auto scrollComponent =
131             AceType::DynamicCast<ScrollComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
132         if (scrollComponent) {
133             if (!scrollComponent->GetScrollPositionController()) {
134                 scrollComponent->SetScrollPositionController(AceType::MakeRefPtr<ScrollPositionController>());
135             }
136             scrollComponent->SetOnScrollEnd(onScrollStop);
137         }
138     }
139     args.SetReturnValue(args.This());
140 }
141 
JSBind(BindingTarget globalObj)142 void JSScroll::JSBind(BindingTarget globalObj)
143 {
144     JSClass<JSScroll>::Declare("Scroll");
145     MethodOptions opt = MethodOptions::NONE;
146     JSClass<JSScroll>::StaticMethod("create", &JSScroll::Create, opt);
147     JSClass<JSScroll>::StaticMethod("scrollable", &JSScroll::SetScrollable, opt);
148     JSClass<JSScroll>::StaticMethod("onScroll", &JSScroll::OnScrollCallback, opt);
149     JSClass<JSScroll>::StaticMethod("onScrollEdge", &JSScroll::OnScrollEdgeCallback, opt);
150     JSClass<JSScroll>::StaticMethod("onScrollEnd", &JSScroll::OnScrollEndCallback, opt);
151     JSClass<JSScroll>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
152     JSClass<JSScroll>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
153     JSClass<JSScroll>::StaticMethod("onHover", &JSInteractableView::JsOnHover);
154     JSClass<JSScroll>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
155     JSClass<JSScroll>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
156     JSClass<JSScroll>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
157     JSClass<JSScroll>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
158     JSClass<JSScroll>::StaticMethod("edgeEffect", &JSScroll::SetEdgeEffect, opt);
159     JSClass<JSScroll>::StaticMethod("scrollBar", &JSScroll::SetScrollBar, opt);
160     JSClass<JSScroll>::StaticMethod("scrollBarColor", &JSScroll::SetScrollBarColor, opt);
161     JSClass<JSScroll>::StaticMethod("scrollBarWidth", &JSScroll::SetScrollBarWidth, opt);
162     JSClass<JSScroll>::StaticMethod("remoteMessage", &JSInteractableView::JsCommonRemoteMessage);
163     JSClass<JSScroll>::Inherit<JSContainerBase>();
164     JSClass<JSScroll>::Inherit<JSViewAbstract>();
165     JSClass<JSScroll>::Bind<>(globalObj);
166 }
167 
SetScrollBar(int displayMode)168 void JSScroll::SetScrollBar(int displayMode)
169 {
170     auto scrollComponent = AceType::DynamicCast<ScrollComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
171     if (!scrollComponent) {
172         return;
173     }
174     if (displayMode >= 0 && displayMode < static_cast<int32_t>(DISPLAY_MODE.size())) {
175         scrollComponent->SetDisplayMode(DISPLAY_MODE[displayMode]);
176     }
177 }
178 
SetScrollBarWidth(const std::string & scrollBarWidth)179 void JSScroll::SetScrollBarWidth(const std::string& scrollBarWidth)
180 {
181     auto scrollComponent = AceType::DynamicCast<ScrollComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
182     if (!scrollComponent || scrollBarWidth.empty()) {
183         return;
184     }
185     scrollComponent->SetScrollBarWidth(StringUtils::StringToDimension(scrollBarWidth));
186 }
187 
SetScrollBarColor(const std::string & scrollBarColor)188 void JSScroll::SetScrollBarColor(const  std::string& scrollBarColor)
189 {
190     auto scrollComponent = AceType::DynamicCast<ScrollComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
191     if (!scrollComponent || scrollBarColor.empty()) {
192         return;
193     }
194     scrollComponent->SetScrollBarColor(Color::FromString(scrollBarColor));
195 }
196 
SetEdgeEffect(int edgeEffect)197 void JSScroll::SetEdgeEffect(int edgeEffect)
198 {
199     auto scrollComponent = AceType::DynamicCast<ScrollComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
200     if (!scrollComponent) {
201         return;
202     }
203     RefPtr<ScrollEdgeEffect> scrollEdgeEffect;
204     if (edgeEffect == 0) {
205         scrollEdgeEffect = AceType::MakeRefPtr<ScrollSpringEffect>();
206     } else if (edgeEffect == 1) {
207         scrollEdgeEffect = AceType::MakeRefPtr<ScrollFadeEffect>(Color::GRAY);
208     } else {
209         scrollEdgeEffect = AceType::MakeRefPtr<ScrollEdgeEffect>(EdgeEffect::NONE);
210     }
211     scrollComponent->SetScrollEffect(scrollEdgeEffect);
212 }
213 
214 } // namespace OHOS::Ace::Framework
215