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/scroll/scrollable.h" 25 #include "core/components_ng/event/gesture_event_actuator.h" 26 #include "core/components_ng/pattern/scroll/scroll_edge_effect.h" 27 28 namespace OHOS::Ace::NG { 29 namespace { 30 constexpr float HTMBLOCK_VELOCITY = 200; 31 } 32 33 class GestureEventHub; 34 35 using BarCollectTouchTargetCallback = std::function<void(const OffsetF&, const GetEventTargetImpl&, TouchTestResult&)>; 36 using InBarRegionCallback = std::function<bool(const PointF&, SourceType source)>; 37 using GetAnimateVelocityCallback = std::function<double()>; 38 39 class ScrollableEvent : public AceType { DECLARE_ACE_TYPE(ScrollableEvent,AceType)40 DECLARE_ACE_TYPE(ScrollableEvent, AceType) 41 public: 42 explicit ScrollableEvent(Axis axis) : axis_(axis) {}; 43 ~ScrollableEvent() override = default; 44 GetAxis()45 Axis GetAxis() const 46 { 47 return axis_; 48 } 49 SetAxis(Axis axis)50 void SetAxis(Axis axis) 51 { 52 axis_ = axis; 53 if (scrollable_) { 54 scrollable_->SetAxis(axis); 55 } 56 } 57 SetScrollable(const RefPtr<Scrollable> & scrollable)58 void SetScrollable(const RefPtr<Scrollable>& scrollable) 59 { 60 scrollable_ = scrollable; 61 } 62 GetScrollable()63 const RefPtr<Scrollable>& GetScrollable() const 64 { 65 return scrollable_; 66 } 67 SetEnabled(bool enable)68 void SetEnabled(bool enable) 69 { 70 enable_ = enable; 71 } 72 GetEnable()73 bool GetEnable() const 74 { 75 return enable_; 76 } 77 Idle()78 bool Idle() const 79 { 80 if (scrollable_) { 81 return scrollable_->Idle(); 82 } 83 return true; 84 } 85 IsHitTestBlock()86 bool IsHitTestBlock() const 87 { 88 if (scrollable_ && !scrollable_->Idle()) { 89 return std::abs(scrollable_->GetCurrentVelocity()) > SystemProperties::Vp2Px(HTMBLOCK_VELOCITY); 90 } 91 if (getAnimateVelocityCallback_) { 92 return std::abs(getAnimateVelocityCallback_()) > SystemProperties::Vp2Px(HTMBLOCK_VELOCITY); 93 } 94 return false; 95 } 96 SetBarCollectTouchTargetCallback(const BarCollectTouchTargetCallback && barCollectTouchTarget)97 void SetBarCollectTouchTargetCallback(const BarCollectTouchTargetCallback&& barCollectTouchTarget) 98 { 99 barCollectTouchTarget_ = std::move(barCollectTouchTarget); 100 } 101 SetInBarRegionCallback(const InBarRegionCallback && inBarRegionCallback)102 void SetInBarRegionCallback(const InBarRegionCallback&& inBarRegionCallback) 103 { 104 inBarRegionCallback_ = std::move(inBarRegionCallback); 105 } 106 InBarRegion(const PointF & localPoint,SourceType source)107 bool InBarRegion(const PointF& localPoint, SourceType source) const 108 { 109 return inBarRegionCallback_ && barCollectTouchTarget_ && inBarRegionCallback_(localPoint, source); 110 } 111 BarCollectTouchTarget(const OffsetF & coordinateOffset,const GetEventTargetImpl & getEventTargetImpl,TouchTestResult & result)112 void BarCollectTouchTarget(const OffsetF& coordinateOffset, 113 const GetEventTargetImpl& getEventTargetImpl, TouchTestResult& result) 114 { 115 if (barCollectTouchTarget_) { 116 barCollectTouchTarget_(coordinateOffset, getEventTargetImpl, result); 117 } 118 } 119 SetAnimateVelocityCallback(const GetAnimateVelocityCallback && getAnimateVelocityCallback)120 void SetAnimateVelocityCallback(const GetAnimateVelocityCallback&& getAnimateVelocityCallback) 121 { 122 getAnimateVelocityCallback_ = std::move(getAnimateVelocityCallback); 123 } 124 125 private: 126 Axis axis_ = Axis::VERTICAL; 127 bool enable_ = true; 128 RefPtr<Scrollable> scrollable_; 129 BarCollectTouchTargetCallback barCollectTouchTarget_; 130 InBarRegionCallback inBarRegionCallback_; 131 GetAnimateVelocityCallback getAnimateVelocityCallback_; 132 }; 133 134 class ScrollableActuator : public GestureEventActuator { 135 DECLARE_ACE_TYPE(ScrollableActuator, GestureEventActuator) 136 public: 137 explicit ScrollableActuator(const WeakPtr<GestureEventHub>& gestureEventHub); 138 ~ScrollableActuator() override = default; 139 AddScrollableEvent(const RefPtr<ScrollableEvent> & scrollableEvent)140 void AddScrollableEvent(const RefPtr<ScrollableEvent>& scrollableEvent) 141 { 142 scrollableEvents_[scrollableEvent->GetAxis()] = scrollableEvent; 143 } 144 RemoveScrollableEvent(const RefPtr<ScrollableEvent> & scrollableEvent)145 void RemoveScrollableEvent(const RefPtr<ScrollableEvent>& scrollableEvent) 146 { 147 scrollableEvents_.erase(scrollableEvent->GetAxis()); 148 } 149 150 void AddScrollEdgeEffect(const Axis& axis, RefPtr<ScrollEdgeEffect>& effect); 151 bool RemoveScrollEdgeEffect(const RefPtr<ScrollEdgeEffect>& effect); 152 153 void CollectTouchTarget(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict, 154 const GetEventTargetImpl& getEventTargetImpl, TouchTestResult& result, const PointF& localPoint); 155 156 private: 157 void InitializeScrollable(RefPtr<ScrollableEvent> event); 158 159 std::unordered_map<Axis, RefPtr<ScrollableEvent>> scrollableEvents_; 160 std::unordered_map<Axis, RefPtr<ScrollEdgeEffect>> scrollEffects_; 161 WeakPtr<GestureEventHub> gestureEventHub_; 162 RefPtr<ClickRecognizer> clickRecognizer_; 163 }; 164 165 } // namespace OHOS::Ace::NG 166 167 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_SCROLLABLE_EVENT_HUB_H 168