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(const PointF & localPoint,SourceType source)89 bool IsHitTestBlock(const PointF& localPoint, SourceType source) const 90 { 91 if (source == SourceType::MOUSE && InBarRectRegion(localPoint, source)) { 92 return false; 93 } 94 if (scrollable_ && !scrollable_->Idle() && 95 std::abs(scrollable_->GetCurrentVelocity()) > PipelineBase::Vp2PxWithCurrentDensity(HTMBLOCK_VELOCITY)) { 96 return true; 97 } 98 if (getAnimateVelocityCallback_) { 99 return std::abs(getAnimateVelocityCallback_()) > PipelineBase::Vp2PxWithCurrentDensity(HTMBLOCK_VELOCITY); 100 } 101 return false; 102 } 103 SetBarCollectTouchTargetCallback(const BarCollectTouchTargetCallback && barCollectTouchTarget)104 void SetBarCollectTouchTargetCallback(const BarCollectTouchTargetCallback&& barCollectTouchTarget) 105 { 106 barCollectTouchTarget_ = std::move(barCollectTouchTarget); 107 } 108 SetInBarRegionCallback(const InBarRegionCallback && inBarRegionCallback)109 void SetInBarRegionCallback(const InBarRegionCallback&& inBarRegionCallback) 110 { 111 inBarRegionCallback_ = std::move(inBarRegionCallback); 112 } 113 InBarRegion(const PointF & localPoint,SourceType source)114 bool InBarRegion(const PointF& localPoint, SourceType source) const 115 { 116 return inBarRegionCallback_ && barCollectTouchTarget_ && inBarRegionCallback_(localPoint, source); 117 } 118 BarCollectTouchTarget(const OffsetF & coordinateOffset,const GetEventTargetImpl & getEventTargetImpl,TouchTestResult & result,const RefPtr<FrameNode> & frameNode,const RefPtr<TargetComponent> & targetComponent,ResponseLinkResult & responseLinkResult)119 void BarCollectTouchTarget(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl, 120 TouchTestResult& result, const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent, 121 ResponseLinkResult& responseLinkResult) 122 { 123 if (barCollectTouchTarget_) { 124 barCollectTouchTarget_( 125 coordinateOffset, getEventTargetImpl, result, frameNode, targetComponent, responseLinkResult); 126 } 127 } 128 SetAnimateVelocityCallback(const GetAnimateVelocityCallback && getAnimateVelocityCallback)129 void SetAnimateVelocityCallback(const GetAnimateVelocityCallback&& getAnimateVelocityCallback) 130 { 131 getAnimateVelocityCallback_ = std::move(getAnimateVelocityCallback); 132 } 133 AddPreviewMenuHandleDragEnd(GestureEventFunc && actionEnd)134 void AddPreviewMenuHandleDragEnd(GestureEventFunc&& actionEnd) 135 { 136 if (scrollable_) { 137 scrollable_->AddPreviewMenuHandleDragEnd(std::move(actionEnd)); 138 } 139 } 140 SetBarCollectClickAndLongPressTargetCallback(const BarCollectTouchTargetCallback && barCollectLongPressTarget)141 void SetBarCollectClickAndLongPressTargetCallback(const BarCollectTouchTargetCallback&& barCollectLongPressTarget) 142 { 143 barCollectLongPressTarget_ = std::move(barCollectLongPressTarget); 144 } 145 SetInBarRectRegionCallback(const InBarRegionCallback && inBarRectRegionCallback)146 void SetInBarRectRegionCallback(const InBarRegionCallback&& inBarRectRegionCallback) 147 { 148 inBarRectRegionCallback_ = std::move(inBarRectRegionCallback); 149 } 150 InBarRectRegion(const PointF & localPoint,SourceType source)151 bool InBarRectRegion(const PointF& localPoint, SourceType source) const 152 { 153 CHECK_NULL_RETURN(inBarRectRegionCallback_, false); 154 return inBarRectRegionCallback_ && barCollectLongPressTarget_ && inBarRectRegionCallback_(localPoint, source); 155 } 156 BarCollectLongPressTarget(const OffsetF & coordinateOffset,const GetEventTargetImpl & getEventTargetImpl,TouchTestResult & result,const RefPtr<FrameNode> & frameNode,const RefPtr<TargetComponent> & targetComponent,ResponseLinkResult & responseLinkResult)157 void BarCollectLongPressTarget(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl, 158 TouchTestResult& result, const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent, 159 ResponseLinkResult& responseLinkResult) 160 { 161 if (barCollectLongPressTarget_) { 162 barCollectLongPressTarget_( 163 coordinateOffset, getEventTargetImpl, result, frameNode, targetComponent, responseLinkResult); 164 } 165 } 166 ClickJudge(const PointF & localPoint)167 bool ClickJudge(const PointF& localPoint) const 168 { 169 return clickJudgeCallback_ && clickJudgeCallback_(localPoint); 170 } 171 SetClickJudgeCallback(const ClickJudgeCallback && clickJudgeCallback)172 void SetClickJudgeCallback(const ClickJudgeCallback&& clickJudgeCallback) 173 { 174 clickJudgeCallback_ = std::move(clickJudgeCallback); 175 } 176 177 void CollectScrollableTouchTarget(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl, 178 TouchTestResult& result, const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent, 179 ResponseLinkResult& responseLinkResult); 180 181 private: 182 Axis axis_ = Axis::VERTICAL; 183 bool enabled_ = true; 184 RefPtr<Scrollable> scrollable_; 185 BarCollectTouchTargetCallback barCollectTouchTarget_; 186 BarCollectTouchTargetCallback barCollectLongPressTarget_; 187 InBarRegionCallback inBarRegionCallback_; 188 InBarRegionCallback inBarRectRegionCallback_; 189 GetAnimateVelocityCallback getAnimateVelocityCallback_; 190 ClickJudgeCallback clickJudgeCallback_; 191 }; 192 193 class ScrollableActuator : public GestureEventActuator { 194 DECLARE_ACE_TYPE(ScrollableActuator, GestureEventActuator) 195 public: 196 explicit ScrollableActuator(const WeakPtr<GestureEventHub>& gestureEventHub); 197 ~ScrollableActuator() override = default; 198 AddScrollableEvent(const RefPtr<ScrollableEvent> & scrollableEvent)199 void AddScrollableEvent(const RefPtr<ScrollableEvent>& scrollableEvent) 200 { 201 scrollableEvents_[scrollableEvent->GetAxis()] = scrollableEvent; 202 } 203 RemoveScrollableEvent(const RefPtr<ScrollableEvent> & scrollableEvent)204 void RemoveScrollableEvent(const RefPtr<ScrollableEvent>& scrollableEvent) 205 { 206 scrollableEvents_.erase(scrollableEvent->GetAxis()); 207 } 208 AddPreviewMenuHandleDragEnd(GestureEventFunc && actionEnd)209 void AddPreviewMenuHandleDragEnd(GestureEventFunc&& actionEnd) 210 { 211 for (auto it = scrollableEvents_.begin(); it != scrollableEvents_.end(); ++it) { 212 auto scrollableEvent = it->second; 213 if (!scrollableEvent) { 214 continue; 215 } 216 scrollableEvent->AddPreviewMenuHandleDragEnd(std::move(actionEnd)); 217 break; 218 } 219 } 220 221 void AddScrollEdgeEffect(const Axis& axis, RefPtr<ScrollEdgeEffect>& effect); 222 bool RemoveScrollEdgeEffect(const RefPtr<ScrollEdgeEffect>& effect); 223 224 void CollectTouchTarget(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict, 225 const GetEventTargetImpl& getEventTargetImpl, TouchTestResult& result, const PointF& localPoint, 226 const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent, 227 ResponseLinkResult& responseLinkResult); 228 229 void InitClickRecognizer(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl, 230 const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent, 231 const RefPtr<ScrollableEvent>& event, bool clickJudge, 232 const PointF& localPoint, SourceType source); 233 234 private: 235 void InitializeScrollable(RefPtr<ScrollableEvent> event); 236 237 std::unordered_map<Axis, RefPtr<ScrollableEvent>> scrollableEvents_; 238 std::unordered_map<Axis, RefPtr<ScrollEdgeEffect>> scrollEffects_; 239 WeakPtr<GestureEventHub> gestureEventHub_; 240 RefPtr<ClickRecognizer> clickRecognizer_; 241 }; 242 243 } // namespace OHOS::Ace::NG 244 245 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_SCROLLABLE_EVENT_HUB_H 246