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