• 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_SCROLLABLE_EVENT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_SCROLLABLE_EVENT_H
18 
19 #include <list>
20 #include <unordered_map>
21 
22 #include "base/geometry/axis.h"
23 #include "base/memory/referenced.h"
24 #include "core/components_ng/event/target_component.h"
25 #include "core/components_ng/pattern/scrollable/scrollable.h"
26 #include "core/components_ng/event/gesture_event_actuator.h"
27 #include "core/components_ng/pattern/scroll/scroll_edge_effect.h"
28 
29 namespace OHOS::Ace::NG {
30 namespace {
31 constexpr float HTMBLOCK_VELOCITY = 200;
32 }
33 
34 class GestureEventHub;
35 
36 using BarCollectTouchTargetCallback = std::function<void(const OffsetF&, const GetEventTargetImpl&, TouchTestResult&,
37     const RefPtr<FrameNode>&, const RefPtr<TargetComponent>&, ResponseLinkResult& responseLinkResult)>;
38 using InBarRegionCallback = std::function<bool(const PointF&, SourceType source)>;
39 using GetAnimateVelocityCallback = std::function<double()>;
40 using ClickJudgeCallback = std::function<bool(const PointF&)>;
41 
42 class ScrollableEvent : public AceType {
DECLARE_ACE_TYPE(ScrollableEvent,AceType)43     DECLARE_ACE_TYPE(ScrollableEvent, AceType)
44 public:
45     explicit ScrollableEvent(Axis axis) : axis_(axis) {};
46     ~ScrollableEvent() override = default;
47 
GetAxis()48     Axis GetAxis() const
49     {
50         return axis_;
51     }
52 
SetAxis(Axis axis)53     void SetAxis(Axis axis)
54     {
55         axis_ = axis;
56         if (scrollable_) {
57             scrollable_->SetAxis(axis);
58         }
59     }
60 
SetScrollable(const RefPtr<Scrollable> & scrollable)61     void SetScrollable(const RefPtr<Scrollable>& scrollable)
62     {
63         scrollable_ = scrollable;
64     }
65 
GetScrollable()66     const RefPtr<Scrollable>& GetScrollable() const
67     {
68         return scrollable_;
69     }
70 
SetEnabled(bool enabled)71     void SetEnabled(bool enabled)
72     {
73         enabled_ = enabled;
74     }
75 
GetEnabled()76     bool GetEnabled() const
77     {
78         return enabled_;
79     }
80 
Idle()81     bool Idle() const
82     {
83         if (scrollable_) {
84             return scrollable_->Idle();
85         }
86         return true;
87     }
88 
IsHitTestBlock()89     bool IsHitTestBlock() const
90     {
91         if (scrollable_ && !scrollable_->Idle() &&
92             std::abs(scrollable_->GetCurrentVelocity()) > PipelineBase::Vp2PxWithCurrentDensity(HTMBLOCK_VELOCITY)) {
93             return true;
94         }
95         if (getAnimateVelocityCallback_) {
96             return std::abs(getAnimateVelocityCallback_()) > PipelineBase::Vp2PxWithCurrentDensity(HTMBLOCK_VELOCITY);
97         }
98         return false;
99     }
100 
SetBarCollectTouchTargetCallback(const BarCollectTouchTargetCallback && barCollectTouchTarget)101     void SetBarCollectTouchTargetCallback(const BarCollectTouchTargetCallback&& barCollectTouchTarget)
102     {
103         barCollectTouchTarget_ = std::move(barCollectTouchTarget);
104     }
105 
SetInBarRegionCallback(const InBarRegionCallback && inBarRegionCallback)106     void SetInBarRegionCallback(const InBarRegionCallback&& inBarRegionCallback)
107     {
108         inBarRegionCallback_ = std::move(inBarRegionCallback);
109     }
110 
InBarRegion(const PointF & localPoint,SourceType source)111     bool InBarRegion(const PointF& localPoint, SourceType source) const
112     {
113         return inBarRegionCallback_ && barCollectTouchTarget_ && inBarRegionCallback_(localPoint, source);
114     }
115 
BarCollectTouchTarget(const OffsetF & coordinateOffset,const GetEventTargetImpl & getEventTargetImpl,TouchTestResult & result,const RefPtr<FrameNode> & frameNode,const RefPtr<TargetComponent> & targetComponent,ResponseLinkResult & responseLinkResult)116     void BarCollectTouchTarget(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl,
117         TouchTestResult& result, const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent,
118         ResponseLinkResult& responseLinkResult)
119     {
120         if (barCollectTouchTarget_) {
121             barCollectTouchTarget_(
122                 coordinateOffset, getEventTargetImpl, result, frameNode, targetComponent, responseLinkResult);
123         }
124     }
125 
SetAnimateVelocityCallback(const GetAnimateVelocityCallback && getAnimateVelocityCallback)126     void SetAnimateVelocityCallback(const GetAnimateVelocityCallback&& getAnimateVelocityCallback)
127     {
128         getAnimateVelocityCallback_ = std::move(getAnimateVelocityCallback);
129     }
130 
AddPreviewMenuHandleDragEnd(GestureEventFunc && actionEnd)131     void AddPreviewMenuHandleDragEnd(GestureEventFunc&& actionEnd)
132     {
133         if (scrollable_) {
134             scrollable_->AddPreviewMenuHandleDragEnd(std::move(actionEnd));
135         }
136     }
137 
ClickJudge(const PointF & localPoint)138     bool ClickJudge(const PointF& localPoint) const
139     {
140         return clickJudgeCallback_ && clickJudgeCallback_(localPoint);
141     }
142 
SetClickJudgeCallback(const ClickJudgeCallback && clickJudgeCallback)143     void SetClickJudgeCallback(const ClickJudgeCallback&& clickJudgeCallback)
144     {
145         clickJudgeCallback_ = std::move(clickJudgeCallback);
146     }
147 
148 private:
149     Axis axis_ = Axis::VERTICAL;
150     bool enabled_ = true;
151     RefPtr<Scrollable> scrollable_;
152     BarCollectTouchTargetCallback barCollectTouchTarget_;
153     InBarRegionCallback inBarRegionCallback_;
154     GetAnimateVelocityCallback getAnimateVelocityCallback_;
155     ClickJudgeCallback clickJudgeCallback_;
156 };
157 
158 class ScrollableActuator : public GestureEventActuator {
159     DECLARE_ACE_TYPE(ScrollableActuator, GestureEventActuator)
160 public:
161     explicit ScrollableActuator(const WeakPtr<GestureEventHub>& gestureEventHub);
162     ~ScrollableActuator() override = default;
163 
AddScrollableEvent(const RefPtr<ScrollableEvent> & scrollableEvent)164     void AddScrollableEvent(const RefPtr<ScrollableEvent>& scrollableEvent)
165     {
166         scrollableEvents_[scrollableEvent->GetAxis()] = scrollableEvent;
167     }
168 
RemoveScrollableEvent(const RefPtr<ScrollableEvent> & scrollableEvent)169     void RemoveScrollableEvent(const RefPtr<ScrollableEvent>& scrollableEvent)
170     {
171         scrollableEvents_.erase(scrollableEvent->GetAxis());
172     }
173 
AddPreviewMenuHandleDragEnd(GestureEventFunc && actionEnd)174     void AddPreviewMenuHandleDragEnd(GestureEventFunc&& actionEnd)
175     {
176         for (auto it = scrollableEvents_.begin(); it != scrollableEvents_.end(); ++it) {
177             auto scrollableEvent = it->second;
178             if (!scrollableEvent) {
179                 continue;
180             }
181             scrollableEvent->AddPreviewMenuHandleDragEnd(std::move(actionEnd));
182             break;
183         }
184     }
185 
186     void AddScrollEdgeEffect(const Axis& axis, RefPtr<ScrollEdgeEffect>& effect);
187     bool RemoveScrollEdgeEffect(const RefPtr<ScrollEdgeEffect>& effect);
188 
189     void CollectTouchTarget(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
190         const GetEventTargetImpl& getEventTargetImpl, TouchTestResult& result, const PointF& localPoint,
191         const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent,
192         ResponseLinkResult& responseLinkResult);
193 
194     void InitClickRecognizer(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl,
195         const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent,
196         const RefPtr<ScrollableEvent>& event, bool clickJudge);
197 
198 private:
199     void InitializeScrollable(RefPtr<ScrollableEvent> event);
200 
201     std::unordered_map<Axis, RefPtr<ScrollableEvent>> scrollableEvents_;
202     std::unordered_map<Axis, RefPtr<ScrollEdgeEffect>> scrollEffects_;
203     WeakPtr<GestureEventHub> gestureEventHub_;
204     RefPtr<ClickRecognizer> clickRecognizer_;
205 };
206 
207 } // namespace OHOS::Ace::NG
208 
209 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_SCROLLABLE_EVENT_HUB_H
210