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