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 "bridge/declarative_frontend/jsview/models/scroll_model_impl.h"
17
18 #include "base/geometry/dimension.h"
19 #include "base/utils/utils.h"
20 #include "bridge/declarative_frontend/jsview/js_scroller.h"
21 #include "bridge/declarative_frontend/jsview/js_view_common_def.h"
22 #include "bridge/declarative_frontend/view_stack_processor.h"
23 #include "core/components/common/layout/constants.h"
24 #include "core/components/scroll/scroll_component.h"
25 #include "core/components_ng/pattern/scroll/scroll_event_hub.h"
26
27 namespace OHOS::Ace::Framework {
28 namespace {
29 const std::vector<DisplayMode> DISPLAY_MODE = { DisplayMode::OFF, DisplayMode::AUTO, DisplayMode::ON };
30 } // namespace
31
Create()32 void ScrollModelImpl::Create()
33 {
34 RefPtr<Component> child;
35 auto scrollComponent = AceType::MakeRefPtr<OHOS::Ace::ScrollComponent>(child);
36 ViewStackProcessor::GetInstance()->ClaimElementId(scrollComponent);
37 auto positionController = AceType::MakeRefPtr<ScrollPositionController>();
38 scrollComponent->SetScrollPositionController(positionController);
39 ViewStackProcessor::GetInstance()->Push(scrollComponent);
40 }
41
GetOrCreateController()42 RefPtr<ScrollControllerBase> ScrollModelImpl::GetOrCreateController()
43 {
44 auto component = AceType::DynamicCast<ScrollComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
45 CHECK_NULL_RETURN(component, nullptr);
46 if (!component->GetScrollPositionController()) {
47 component->SetScrollPositionController(AceType::MakeRefPtr<ScrollPositionController>());
48 }
49 return component->GetScrollPositionController();
50 }
51
CreateScrollBarProxy()52 RefPtr<ScrollProxy> ScrollModelImpl::CreateScrollBarProxy()
53 {
54 return AceType::MakeRefPtr<ScrollBarProxy>();
55 }
56
SetAxis(Axis axis)57 void ScrollModelImpl::SetAxis(Axis axis)
58 {
59 JSViewSetProperty(&ScrollComponent::SetAxisDirection, axis);
60 }
61
SetOnScrollBegin(OnScrollBeginEvent && event)62 void ScrollModelImpl::SetOnScrollBegin(OnScrollBeginEvent&& event)
63 {
64 JSViewSetProperty(&ScrollComponent::SetOnScrollBegin, std::move(event));
65 }
66
SetOnScrollFrameBegin(OnScrollFrameBeginEvent && event)67 void ScrollModelImpl::SetOnScrollFrameBegin(OnScrollFrameBeginEvent&& event)
68 {
69 }
70
SetOnScroll(NG::ScrollEvent && event)71 void ScrollModelImpl::SetOnScroll(NG::ScrollEvent&& event)
72 {
73 auto onScroll = EventMarker([scrollEvent = std::move(event)](const BaseEventInfo* info) {
74 auto eventInfo = TypeInfoHelper::DynamicCast<ScrollEventInfo>(info);
75 if (!eventInfo || !scrollEvent) {
76 return;
77 }
78 Dimension x(eventInfo->GetScrollX(), DimensionUnit::VP);
79 Dimension y(eventInfo->GetScrollY(), DimensionUnit::VP);
80 scrollEvent(x, y);
81 });
82 JSViewSetProperty(&ScrollComponent::SetOnScroll, std::move(onScroll));
83 }
84
SetOnScrollEdge(NG::ScrollEdgeEvent && event)85 void ScrollModelImpl::SetOnScrollEdge(NG::ScrollEdgeEvent&& event)
86 {
87 auto onScrollEdge = EventMarker([scrollEvent = std::move(event)](const BaseEventInfo* info) {
88 auto eventInfo = TypeInfoHelper::DynamicCast<ScrollEventInfo>(info);
89 if (!eventInfo || !scrollEvent) {
90 return;
91 }
92 if (eventInfo->GetType() == ScrollEvent::SCROLL_TOP) {
93 scrollEvent(NG::ScrollEdge::TOP);
94 } else if (eventInfo->GetType() == ScrollEvent::SCROLL_BOTTOM) {
95 scrollEvent(NG::ScrollEdge::BOTTOM);
96 } else {
97 LOGW("EventType is not support: %{public}d", static_cast<int32_t>(eventInfo->GetType()));
98 }
99 });
100 JSViewSetProperty(&ScrollComponent::SetOnScrollEdge, std::move(onScrollEdge));
101 }
102
SetOnScrollEnd(NG::ScrollEndEvent && event)103 void ScrollModelImpl::SetOnScrollEnd(NG::ScrollEndEvent&& event)
104 {
105 auto onScrollEnd = EventMarker([scrollEvent = std::move(event)](const BaseEventInfo* info) {
106 if (scrollEvent) {
107 scrollEvent();
108 }
109 });
110 JSViewSetProperty(&ScrollComponent::SetOnScrollEnd, std::move(onScrollEnd));
111 }
112
SetScrollBarProxy(const RefPtr<ScrollProxy> & proxy)113 void ScrollModelImpl::SetScrollBarProxy(const RefPtr<ScrollProxy>& proxy)
114 {
115 auto scrollBarProxy = AceType::DynamicCast<ScrollBarProxy>(proxy);
116 JSViewSetProperty(&ScrollComponent::SetScrollBarProxy, scrollBarProxy);
117 }
118
InitScrollBar(const RefPtr<ScrollBarTheme> & theme,const std::pair<bool,Color> & color,const std::pair<bool,Dimension> & width,EdgeEffect effect)119 void ScrollModelImpl::InitScrollBar(const RefPtr<ScrollBarTheme>& theme, const std::pair<bool, Color>& color,
120 const std::pair<bool, Dimension>& width, EdgeEffect effect)
121 {
122 auto component = AceType::DynamicCast<ScrollComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
123 CHECK_NULL_VOID(component);
124 component->InitScrollBar(theme, color, width, effect);
125 }
126
SetDisplayMode(int displayMode)127 void ScrollModelImpl::SetDisplayMode(int displayMode)
128 {
129 if (displayMode >= 0 && displayMode < static_cast<int32_t>(DISPLAY_MODE.size())) {
130 JSViewSetProperty(&ScrollComponent::SetDisplayMode, DISPLAY_MODE[displayMode]);
131 }
132 }
133
SetScrollBarWidth(const Dimension & dimension)134 void ScrollModelImpl::SetScrollBarWidth(const Dimension& dimension)
135 {
136 JSViewSetProperty(&ScrollComponent::SetScrollBarWidth, dimension);
137 }
138
SetScrollBarColor(const Color & color)139 void ScrollModelImpl::SetScrollBarColor(const Color& color)
140 {
141 JSViewSetProperty(&ScrollComponent::SetScrollBarColor, color);
142 }
143
SetEdgeEffect(EdgeEffect edgeEffect,bool alwaysEnabled)144 void ScrollModelImpl::SetEdgeEffect(EdgeEffect edgeEffect, bool alwaysEnabled)
145 {
146 auto scrollComponent = AceType::DynamicCast<ScrollComponent>(ViewStackProcessor::GetInstance()->GetMainComponent());
147 CHECK_NULL_VOID(scrollComponent);
148 RefPtr<ScrollEdgeEffect> scrollEdgeEffect;
149 if (edgeEffect == EdgeEffect::SPRING) {
150 scrollEdgeEffect = AceType::MakeRefPtr<ScrollSpringEffect>();
151 } else if (edgeEffect == EdgeEffect::FADE) {
152 scrollEdgeEffect = AceType::MakeRefPtr<ScrollFadeEffect>(Color::GRAY);
153 } else {
154 scrollEdgeEffect = AceType::MakeRefPtr<ScrollEdgeEffect>(EdgeEffect::NONE);
155 }
156 scrollComponent->SetScrollEffect(scrollEdgeEffect);
157 }
158
SetHasWidth(bool hasWidth)159 void ScrollModelImpl::SetHasWidth(bool hasWidth)
160 {
161 JSViewSetProperty(&ScrollComponent::SetHasWidth, hasWidth);
162 }
163
SetHasHeight(bool hasHeight)164 void ScrollModelImpl::SetHasHeight(bool hasHeight)
165 {
166 JSViewSetProperty(&ScrollComponent::SetHasHeight, hasHeight);
167 }
168
169 } // namespace OHOS::Ace::Framework
170