1 /* 2 * Copyright (c) 2022-2023 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_GESTURE_EVENT_HUB_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_GESTURE_EVENT_HUB_H 18 19 #include <list> 20 #include <vector> 21 22 #include "base/geometry/ng/point_t.h" 23 #include "base/memory/referenced.h" 24 #include "core/components/common/layout/constants.h" 25 #include "core/components_ng/event/click_event.h" 26 #include "core/components_ng/event/drag_event.h" 27 #include "core/components_ng/event/long_press_event.h" 28 #include "core/components_ng/event/pan_event.h" 29 #include "core/components_ng/event/scrollable_event.h" 30 #include "core/components_ng/event/touch_event.h" 31 #include "core/components_ng/gestures/gesture_info.h" 32 #include "core/components_ng/gestures/recognizers/exclusive_recognizer.h" 33 #include "core/components_ng/gestures/recognizers/parallel_recognizer.h" 34 #include "core/components_ng/manager/drag_drop/drag_drop_proxy.h" 35 36 #ifdef ENABLE_DRAG_FRAMEWORK 37 namespace OHOS::Msdp::DeviceStatus { 38 struct DragNotifyMsg; 39 } 40 namespace OHOS::Ace { 41 class UnifiedData; 42 } 43 #endif 44 namespace OHOS::Ace::NG { 45 46 enum class HitTestMode { 47 /** 48 * Both self and children respond to the hit test for touch events, 49 * but block hit test of the other nodes which is masked by this node. 50 */ 51 HTMDEFAULT = 0, 52 53 /** 54 * Self respond to the hit test for touch events, 55 * but block hit test of children and other nodes which is masked by this node. 56 */ 57 HTMBLOCK, 58 59 /** 60 * Self and child respond to the hit test for touch events, 61 * and allow hit test of other nodes which is masked by this node. 62 */ 63 HTMTRANSPARENT, 64 65 /** 66 * Self not respond to the hit test for touch events, 67 * but children respond to the hit test for touch events. 68 */ 69 HTMNONE, 70 71 /** 72 * Self and child respond to the hit test for touch events, 73 * when self consumed allow hit test of other nodes which is masked by this node, 74 * when child consumed block hit test of other nodes. 75 */ 76 HTMTRANSPARENT_SELF, 77 }; 78 79 enum class HitTestResult { 80 // The touch point is located outside the current component area; 81 OUT_OF_REGION, 82 // node consumption events and prevent bubbling; 83 STOP_BUBBLING, 84 // node process events and bubble; 85 BUBBLING, 86 // node process events and bubble; 87 SELF_TRANSPARENT, 88 }; 89 90 struct DragDropBaseInfo { 91 RefPtr<AceType> node; 92 RefPtr<PixelMap> pixelMap; 93 std::string extraInfo; 94 }; 95 96 using OnDragStartFunc = std::function<DragDropBaseInfo(const RefPtr<OHOS::Ace::DragEvent>&, const std::string&)>; 97 using OnDragDropFunc = std::function<void(const RefPtr<OHOS::Ace::DragEvent>&, const std::string&)>; 98 99 struct DragDropInfo { 100 RefPtr<UINode> customNode; 101 RefPtr<PixelMap> pixelMap; 102 std::string extraInfo; 103 }; 104 105 #ifdef ENABLE_DRAG_FRAMEWORK 106 using DragNotifyMsg = Msdp::DeviceStatus::DragNotifyMsg; 107 using OnDragCallback = std::function<void(const DragNotifyMsg&)>; 108 constexpr float PIXELMAP_WIDTH_RATE = -0.5f; 109 constexpr float PIXELMAP_HEIGHT_RATE = -0.2f; 110 constexpr float PIXELMAP_DEFALUT_LIMIT_SCALE = 0.5f; 111 constexpr float PIXELMAP_DRAG_WGR_TEXT_SCALE = 2.0f; 112 constexpr float PIXELMAP_DRAG_WGR_SCALE = 3.0f; 113 constexpr float PIXELMAP_DRAG_DEFAULT_HEIGHT = -28.0f; 114 #endif 115 class EventHub; 116 117 // The gesture event hub is mainly used to handle common gesture events. 118 class ACE_FORCE_EXPORT GestureEventHub : public Referenced { 119 public: 120 explicit GestureEventHub(const WeakPtr<EventHub>& eventHub); 121 ~GestureEventHub() override = default; 122 AddGesture(const RefPtr<NG::Gesture> & gesture)123 void AddGesture(const RefPtr<NG::Gesture>& gesture) 124 { 125 if (!recreateGesture_) { 126 gestures_.clear(); 127 } 128 gestures_.emplace_back(gesture); 129 recreateGesture_ = true; 130 } 131 AddScrollableEvent(const RefPtr<ScrollableEvent> & scrollableEvent)132 void AddScrollableEvent(const RefPtr<ScrollableEvent>& scrollableEvent) 133 { 134 if (!scrollableActuator_) { 135 scrollableActuator_ = MakeRefPtr<ScrollableActuator>(WeakClaim(this)); 136 } 137 scrollableActuator_->AddScrollableEvent(scrollableEvent); 138 } 139 RemoveScrollableEvent(const RefPtr<ScrollableEvent> & scrollableEvent)140 void RemoveScrollableEvent(const RefPtr<ScrollableEvent>& scrollableEvent) 141 { 142 if (!scrollableActuator_) { 143 return; 144 } 145 scrollableActuator_->RemoveScrollableEvent(scrollableEvent); 146 } 147 AddScrollEdgeEffect(const Axis & axis,RefPtr<ScrollEdgeEffect> & scrollEffect)148 void AddScrollEdgeEffect(const Axis& axis, RefPtr<ScrollEdgeEffect>& scrollEffect) 149 { 150 if (!scrollableActuator_) { 151 scrollableActuator_ = MakeRefPtr<ScrollableActuator>(WeakClaim(this)); 152 } 153 scrollableActuator_->AddScrollEdgeEffect(axis, scrollEffect); 154 } 155 RemoveScrollEdgeEffect(const RefPtr<ScrollEdgeEffect> & scrollEffect)156 void RemoveScrollEdgeEffect(const RefPtr<ScrollEdgeEffect>& scrollEffect) 157 { 158 if (!scrollableActuator_) { 159 return; 160 } 161 scrollableActuator_->RemoveScrollEdgeEffect(scrollEffect); 162 } 163 164 // Set by user define, which will replace old one. SetTouchEvent(TouchEventFunc && touchEventFunc)165 void SetTouchEvent(TouchEventFunc&& touchEventFunc) 166 { 167 if (!touchEventActuator_) { 168 touchEventActuator_ = MakeRefPtr<TouchEventActuator>(); 169 } 170 touchEventActuator_->ReplaceTouchEvent(std::move(touchEventFunc)); 171 } 172 AddTouchEvent(const RefPtr<TouchEventImpl> & touchEvent)173 void AddTouchEvent(const RefPtr<TouchEventImpl>& touchEvent) 174 { 175 if (!touchEventActuator_) { 176 touchEventActuator_ = MakeRefPtr<TouchEventActuator>(); 177 } 178 touchEventActuator_->AddTouchEvent(touchEvent); 179 } 180 RemoveTouchEvent(const RefPtr<TouchEventImpl> & touchEvent)181 void RemoveTouchEvent(const RefPtr<TouchEventImpl>& touchEvent) 182 { 183 if (!touchEventActuator_) { 184 return; 185 } 186 touchEventActuator_->RemoveTouchEvent(touchEvent); 187 } 188 189 void SetFocusClickEvent(GestureEventFunc&& clickEvent); 190 IsClickable()191 bool IsClickable() const 192 { 193 return clickEventActuator_ != nullptr; 194 } 195 196 bool IsAccessibilityClickable(); 197 bool IsAccessibilityLongClickable(); 198 199 bool ActClick(); 200 201 void CheckClickActuator(); 202 // Set by user define, which will replace old one. 203 void SetUserOnClick(GestureEventFunc&& clickEvent); 204 205 // When the event param is undefined, it will clear the callback. 206 void ClearUserOnClick(); 207 void ClearUserOnTouch(); 208 209 void AddClickEvent(const RefPtr<ClickEvent>& clickEvent); 210 RemoveClickEvent(const RefPtr<ClickEvent> & clickEvent)211 void RemoveClickEvent(const RefPtr<ClickEvent>& clickEvent) 212 { 213 if (!clickEventActuator_) { 214 return; 215 } 216 clickEventActuator_->RemoveClickEvent(clickEvent); 217 } 218 IsClickEventsEmpty()219 bool IsClickEventsEmpty() const 220 { 221 if (!clickEventActuator_) { 222 return true; 223 } 224 return clickEventActuator_->IsClickEventsEmpty(); 225 } 226 227 void BindMenu(GestureEventFunc&& showMenu); 228 IsLongClickable()229 bool IsLongClickable() const 230 { 231 return longPressEventActuator_ != nullptr; 232 } 233 234 bool ActLongClick(); 235 236 void SetLongPressEvent(const RefPtr<LongPressEvent>& event, bool isForDrag = false, bool isDisableMouseLeft = false, 237 int32_t duration = 500) 238 { 239 if (!longPressEventActuator_) { 240 longPressEventActuator_ = MakeRefPtr<LongPressEventActuator>(WeakClaim(this)); 241 longPressEventActuator_->SetOnAccessibility(GetOnAccessibilityEventFunc()); 242 } 243 longPressEventActuator_->SetLongPressEvent(event, isForDrag, isDisableMouseLeft); 244 longPressEventActuator_->SetDuration(duration); 245 } 246 247 // Set by user define, which will replace old one. SetPanEvent(const RefPtr<PanEvent> & panEvent,PanDirection direction,int32_t fingers,Dimension distance)248 void SetPanEvent(const RefPtr<PanEvent>& panEvent, PanDirection direction, int32_t fingers, Dimension distance) 249 { 250 if (!panEventActuator_) { 251 panEventActuator_ = 252 MakeRefPtr<PanEventActuator>(WeakClaim(this), direction, fingers, distance.ConvertToPx()); 253 } 254 panEventActuator_->ReplacePanEvent(panEvent); 255 } 256 AddPanEvent(const RefPtr<PanEvent> & panEvent,PanDirection direction,int32_t fingers,Dimension distance)257 void AddPanEvent(const RefPtr<PanEvent>& panEvent, PanDirection direction, int32_t fingers, Dimension distance) 258 { 259 if (!panEventActuator_ || direction.type != panEventActuator_->GetDirection().type) { 260 panEventActuator_ = 261 MakeRefPtr<PanEventActuator>(WeakClaim(this), direction, fingers, distance.ConvertToPx()); 262 } 263 panEventActuator_->AddPanEvent(panEvent); 264 } 265 RemovePanEvent(const RefPtr<PanEvent> & panEvent)266 void RemovePanEvent(const RefPtr<PanEvent>& panEvent) 267 { 268 if (!panEventActuator_) { 269 return; 270 } 271 panEventActuator_->RemovePanEvent(panEvent); 272 } 273 274 // Set by user define, which will replace old one. SetDragEvent(const RefPtr<DragEvent> & dragEvent,PanDirection direction,int32_t fingers,Dimension distance)275 void SetDragEvent(const RefPtr<DragEvent>& dragEvent, PanDirection direction, int32_t fingers, Dimension distance) 276 { 277 if (!dragEventActuator_) { 278 dragEventActuator_ = 279 MakeRefPtr<DragEventActuator>(WeakClaim(this), direction, fingers, distance.ConvertToPx()); 280 } 281 dragEventActuator_->ReplaceDragEvent(dragEvent); 282 } 283 SetCustomDragEvent(const RefPtr<DragEvent> & dragEvent,PanDirection direction,int32_t fingers,Dimension distance)284 void SetCustomDragEvent( 285 const RefPtr<DragEvent>& dragEvent, PanDirection direction, int32_t fingers, Dimension distance) 286 { 287 if (!dragEventActuator_) { 288 dragEventActuator_ = 289 MakeRefPtr<DragEventActuator>(WeakClaim(this), direction, fingers, distance.ConvertToPx()); 290 } 291 dragEventActuator_->SetCustomDragEvent(dragEvent); 292 } 293 294 // the return value means prevents event bubbling. 295 bool ProcessTouchTestHit(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict, 296 TouchTestResult& innerTargets, TouchTestResult& finalResult, int32_t touchId, const PointF& localPoint); 297 298 RefPtr<FrameNode> GetFrameNode() const; 299 OnContextAttached()300 void OnContextAttached() {} 301 302 std::string GetHitTestModeStr() const; 303 GetHitTestMode()304 HitTestMode GetHitTestMode() const 305 { 306 return hitTestMode_; 307 } 308 SetHitTestMode(HitTestMode hitTestMode)309 void SetHitTestMode(HitTestMode hitTestMode) 310 { 311 hitTestMode_ = hitTestMode; 312 } 313 RemoveDragEvent()314 void RemoveDragEvent() 315 { 316 if (!dragEventActuator_) { 317 return; 318 } 319 dragEventActuator_->ClearDragEvent(); 320 } 321 322 void CombineIntoExclusiveRecognizer( 323 const PointF& globalPoint, const PointF& localPoint, TouchTestResult& result, int32_t touchId); 324 IsResponseRegion()325 bool IsResponseRegion() const 326 { 327 return isResponseRegion_; 328 } MarkResponseRegion(bool isResponseRegion)329 void MarkResponseRegion(bool isResponseRegion) 330 { 331 isResponseRegion_ = isResponseRegion; 332 } 333 GetResponseRegion()334 const std::vector<DimensionRect>& GetResponseRegion() const 335 { 336 return responseRegion_; 337 } 338 GetMouseResponseRegion()339 const std::vector<DimensionRect>& GetMouseResponseRegion() const 340 { 341 return mouseResponseRegion_; 342 } 343 SetResponseRegion(const std::vector<DimensionRect> & responseRegion)344 void SetResponseRegion(const std::vector<DimensionRect>& responseRegion) 345 { 346 responseRegion_ = responseRegion; 347 if (!responseRegion_.empty()) { 348 isResponseRegion_ = true; 349 } 350 } 351 SetMouseResponseRegion(const std::vector<DimensionRect> & mouseResponseRegion)352 void SetMouseResponseRegion(const std::vector<DimensionRect>& mouseResponseRegion) 353 { 354 mouseResponseRegion_ = mouseResponseRegion; 355 if (!mouseResponseRegion_.empty()) { 356 isResponseRegion_ = true; 357 } 358 } 359 AddResponseRect(const DimensionRect & responseRect)360 void AddResponseRect(const DimensionRect& responseRect) 361 { 362 responseRegion_.emplace_back(responseRect); 363 isResponseRegion_ = true; 364 } 365 RemoveLastResponseRect()366 void RemoveLastResponseRect() 367 { 368 if (responseRegion_.empty()) { 369 isResponseRegion_ = false; 370 return; 371 } 372 responseRegion_.pop_back(); 373 if (responseRegion_.empty()) { 374 isResponseRegion_ = false; 375 } 376 } 377 GetTouchable()378 bool GetTouchable() const 379 { 380 return touchable_; 381 } 382 SetTouchable(bool touchable)383 void SetTouchable(bool touchable) 384 { 385 touchable_ = touchable; 386 } 387 388 #ifdef ENABLE_DRAG_FRAMEWORK SetThumbnailCallback(std::function<void (Offset)> && callback)389 void SetThumbnailCallback(std::function<void(Offset)>&& callback) 390 { 391 if (dragEventActuator_) { 392 dragEventActuator_->SetThumbnailCallback(std::move(callback)); 393 } 394 } 395 GetTextDraggable()396 bool GetTextDraggable() const 397 { 398 return textDraggable_; 399 } 400 SetTextDraggable(bool draggable)401 void SetTextDraggable(bool draggable) 402 { 403 textDraggable_ = draggable; 404 } 405 SetIsTextDraggable(bool isTextDraggable)406 void SetIsTextDraggable(bool isTextDraggable) 407 { 408 isTextDraggable_ = isTextDraggable; 409 } 410 GetIsTextDraggable()411 bool GetIsTextDraggable() 412 { 413 return isTextDraggable_; 414 } 415 #endif // ENABLE_DRAG_FRAMEWORK 416 SetPixelMap(RefPtr<PixelMap> pixelMap)417 void SetPixelMap(RefPtr<PixelMap> pixelMap) 418 { 419 pixelMap_ = pixelMap; 420 } 421 GetPixelMap()422 RefPtr<PixelMap> GetPixelMap() 423 { 424 return pixelMap_; 425 } 426 GetLongPressRecognizer()427 RefPtr<LongPressRecognizer> GetLongPressRecognizer() const 428 { 429 CHECK_NULL_RETURN(longPressEventActuator_, nullptr); 430 return longPressEventActuator_->GetLongPressRecognizer(); 431 } 432 433 #ifdef ENABLE_DRAG_FRAMEWORK 434 int32_t SetDragData(const RefPtr<UnifiedData>& unifiedData, std::string& udKey); 435 OnDragCallback GetDragCallback(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub); 436 SetThumbnailPixelMapCallback(std::function<void ()> && callback)437 void SetThumbnailPixelMapCallback(std::function<void()>&& callback) 438 { 439 callback_ = std::move(callback); 440 } 441 HasThumbnailCallback()442 bool HasThumbnailCallback() const 443 { 444 return static_cast<bool>(callback_); 445 } 446 447 OffsetF GetPixelMapOffset(const GestureEvent& info, const SizeF& size, const float scale = 1.0f) const; 448 float GetPixelMapScale(const int32_t height, const int32_t width) const; 449 #endif // ENABLE_DRAG_FRAMEWORK 450 void InitDragDropEvent(); 451 void HandleOnDragStart(const GestureEvent& info); 452 void HandleOnDragUpdate(const GestureEvent& info); 453 void HandleOnDragEnd(const GestureEvent& info); 454 void HandleOnDragCancel(); 455 456 void StartLongPressActionForWeb(); 457 void CancelDragForWeb(); 458 void StartDragTaskForWeb(); 459 void ResetDragActionForWeb(); 460 461 void OnModifyDone(); 462 bool KeyBoardShortCutClick(const KeyEvent& event, const WeakPtr<NG::FrameNode>& node); 463 bool IsAllowedDrag(RefPtr<EventHub> eventHub); 464 void HandleNotallowDrag(const GestureEvent& info); 465 466 private: 467 void ProcessTouchTestHierarchy(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict, 468 std::list<RefPtr<NGGestureRecognizer>>& innerRecognizers, TouchTestResult& finalResult, int32_t touchId); 469 470 void UpdateGestureHierarchy(); 471 472 // old path. 473 void UpdateExternalNGGestureRecognizer(); 474 475 OnAccessibilityEventFunc GetOnAccessibilityEventFunc(); 476 477 void OnDragStart(const GestureEvent& info, const RefPtr<PipelineBase>& context, const RefPtr<FrameNode> frameNode, 478 const DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent); 479 480 WeakPtr<EventHub> eventHub_; 481 RefPtr<ScrollableActuator> scrollableActuator_; 482 RefPtr<TouchEventActuator> touchEventActuator_; 483 RefPtr<ClickEventActuator> clickEventActuator_; 484 RefPtr<LongPressEventActuator> longPressEventActuator_; 485 RefPtr<PanEventActuator> panEventActuator_; 486 RefPtr<DragEventActuator> dragEventActuator_; 487 RefPtr<ExclusiveRecognizer> innerExclusiveRecognizer_; 488 RefPtr<ExclusiveRecognizer> nodeExclusiveRecognizer_; 489 RefPtr<ParallelRecognizer> nodeParallelRecognizer_; 490 std::vector<RefPtr<ExclusiveRecognizer>> externalExclusiveRecognizer_; 491 std::vector<RefPtr<ParallelRecognizer>> externalParallelRecognizer_; 492 RefPtr<DragDropProxy> dragDropProxy_; 493 494 // Set by use gesture, priorityGesture and parallelGesture attribute function. 495 std::list<RefPtr<NG::Gesture>> gestures_; 496 std::list<RefPtr<NGGestureRecognizer>> gestureHierarchy_; 497 498 // used in bindMenu, need to delete the old callback when bindMenu runs again 499 RefPtr<ClickEvent> showMenu_; 500 501 HitTestMode hitTestMode_ = HitTestMode::HTMDEFAULT; 502 bool recreateGesture_ = true; 503 bool isResponseRegion_ = false; 504 std::vector<DimensionRect> responseRegion_; 505 std::vector<DimensionRect> mouseResponseRegion_; 506 bool touchable_ = true; 507 RefPtr<PixelMap> pixelMap_; 508 OffsetF frameNodeOffset_; 509 GestureEvent gestureInfoForWeb_; 510 bool isReceivedDragGestureInfo_ = false; 511 512 #ifdef ENABLE_DRAG_FRAMEWORK 513 bool textDraggable_ = false; 514 bool isTextDraggable_ = false; 515 std::function<void()> callback_; 516 #endif 517 }; 518 519 } // namespace OHOS::Ace::NG 520 521 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_GESTURE_EVENT_HUB_H 522