• 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>&)>;
38 using InBarRegionCallback = std::function<bool(const PointF&, SourceType source)>;
39 using GetAnimateVelocityCallback = std::function<double()>;
40 
41 class ScrollableEvent : public AceType {
DECLARE_ACE_TYPE(ScrollableEvent,AceType)42     DECLARE_ACE_TYPE(ScrollableEvent, AceType)
43 public:
44     explicit ScrollableEvent(Axis axis) : axis_(axis) {};
45     ~ScrollableEvent() override = default;
46 
GetAxis()47     Axis GetAxis() const
48     {
49         return axis_;
50     }
51 
SetAxis(Axis axis)52     void SetAxis(Axis axis)
53     {
54         axis_ = axis;
55         if (scrollable_) {
56             scrollable_->SetAxis(axis);
57         }
58     }
59 
SetScrollable(const RefPtr<Scrollable> & scrollable)60     void SetScrollable(const RefPtr<Scrollable>& scrollable)
61     {
62         scrollable_ = scrollable;
63     }
64 
GetScrollable()65     const RefPtr<Scrollable>& GetScrollable() const
66     {
67         return scrollable_;
68     }
69 
SetEnabled(bool enable)70     void SetEnabled(bool enable)
71     {
72         enable_ = enable;
73     }
74 
GetEnable()75     bool GetEnable() const
76     {
77         return enable_;
78     }
79 
Idle()80     bool Idle() const
81     {
82         if (scrollable_) {
83             return scrollable_->Idle();
84         }
85         return true;
86     }
87 
IsHitTestBlock()88     bool IsHitTestBlock() const
89     {
90         if (scrollable_ && !scrollable_->Idle()) {
91             return std::abs(
92                 scrollable_->GetCurrentVelocity()) > PipelineBase::Vp2PxWithCurrentDensity(HTMBLOCK_VELOCITY);
93         }
94         if (getAnimateVelocityCallback_) {
95             return std::abs(getAnimateVelocityCallback_()) > PipelineBase::Vp2PxWithCurrentDensity(HTMBLOCK_VELOCITY);
96         }
97         return false;
98     }
99 
SetBarCollectTouchTargetCallback(const BarCollectTouchTargetCallback && barCollectTouchTarget)100     void SetBarCollectTouchTargetCallback(const BarCollectTouchTargetCallback&& barCollectTouchTarget)
101     {
102         barCollectTouchTarget_ = std::move(barCollectTouchTarget);
103     }
104 
SetInBarRegionCallback(const InBarRegionCallback && inBarRegionCallback)105     void SetInBarRegionCallback(const InBarRegionCallback&& inBarRegionCallback)
106     {
107         inBarRegionCallback_ = std::move(inBarRegionCallback);
108     }
109 
InBarRegion(const PointF & localPoint,SourceType source)110     bool InBarRegion(const PointF& localPoint, SourceType source) const
111     {
112         return inBarRegionCallback_ && barCollectTouchTarget_ && inBarRegionCallback_(localPoint, source);
113     }
114 
BarCollectTouchTarget(const OffsetF & coordinateOffset,const GetEventTargetImpl & getEventTargetImpl,TouchTestResult & result,const RefPtr<FrameNode> & frameNode,const RefPtr<TargetComponent> & targetComponent)115     void BarCollectTouchTarget(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl,
116         TouchTestResult& result, const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent)
117     {
118         if (barCollectTouchTarget_) {
119             barCollectTouchTarget_(coordinateOffset, getEventTargetImpl, result, frameNode, targetComponent);
120         }
121     }
122 
SetAnimateVelocityCallback(const GetAnimateVelocityCallback && getAnimateVelocityCallback)123     void SetAnimateVelocityCallback(const GetAnimateVelocityCallback&& getAnimateVelocityCallback)
124     {
125         getAnimateVelocityCallback_ = std::move(getAnimateVelocityCallback);
126     }
127 
AddPreviewMenuHandleDragEnd(GestureEventFunc && actionEnd)128     void AddPreviewMenuHandleDragEnd(GestureEventFunc&& actionEnd)
129     {
130         if (scrollable_) {
131             scrollable_->AddPreviewMenuHandleDragEnd(std::move(actionEnd));
132         }
133     }
134 
135 private:
136     Axis axis_ = Axis::VERTICAL;
137     bool enable_ = true;
138     RefPtr<Scrollable> scrollable_;
139     BarCollectTouchTargetCallback barCollectTouchTarget_;
140     InBarRegionCallback inBarRegionCallback_;
141     GetAnimateVelocityCallback getAnimateVelocityCallback_;
142 };
143 
144 class ScrollableActuator : public GestureEventActuator {
145     DECLARE_ACE_TYPE(ScrollableActuator, GestureEventActuator)
146 public:
147     explicit ScrollableActuator(const WeakPtr<GestureEventHub>& gestureEventHub);
148     ~ScrollableActuator() override = default;
149 
AddScrollableEvent(const RefPtr<ScrollableEvent> & scrollableEvent)150     void AddScrollableEvent(const RefPtr<ScrollableEvent>& scrollableEvent)
151     {
152         scrollableEvents_[scrollableEvent->GetAxis()] = scrollableEvent;
153     }
154 
RemoveScrollableEvent(const RefPtr<ScrollableEvent> & scrollableEvent)155     void RemoveScrollableEvent(const RefPtr<ScrollableEvent>& scrollableEvent)
156     {
157         scrollableEvents_.erase(scrollableEvent->GetAxis());
158     }
159 
AddPreviewMenuHandleDragEnd(GestureEventFunc && actionEnd)160     void AddPreviewMenuHandleDragEnd(GestureEventFunc&& actionEnd)
161     {
162         for (auto it = scrollableEvents_.begin(); it != scrollableEvents_.end(); ++it) {
163             auto scrollableEvent = it->second;
164             if (!scrollableEvent) {
165                 continue;
166             }
167             scrollableEvent->AddPreviewMenuHandleDragEnd(std::move(actionEnd));
168             break;
169         }
170     }
171 
172     void AddScrollEdgeEffect(const Axis& axis, RefPtr<ScrollEdgeEffect>& effect);
173     bool RemoveScrollEdgeEffect(const RefPtr<ScrollEdgeEffect>& effect);
174 
175     void CollectTouchTarget(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
176         const GetEventTargetImpl& getEventTargetImpl, TouchTestResult& result, const PointF& localPoint,
177         const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent);
178 
179 private:
180     void InitializeScrollable(RefPtr<ScrollableEvent> event);
181 
182     std::unordered_map<Axis, RefPtr<ScrollableEvent>> scrollableEvents_;
183     std::unordered_map<Axis, RefPtr<ScrollEdgeEffect>> scrollEffects_;
184     WeakPtr<GestureEventHub> gestureEventHub_;
185     RefPtr<ClickRecognizer> clickRecognizer_;
186 };
187 
188 } // namespace OHOS::Ace::NG
189 
190 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_SCROLLABLE_EVENT_HUB_H
191