1 /* 2 * Copyright (c) 2021-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_EVENT_MOUSE_EVENT_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_MOUSE_EVENT_H 18 19 #include "base/geometry/ng/offset_t.h" 20 #include "base/geometry/offset.h" 21 #include "base/mousestyle/mouse_style.h" 22 #include "core/event/key_event.h" 23 #include "core/event/touch_event.h" 24 #include "core/pipeline_ng/ui_task_scheduler.h" 25 26 namespace OHOS::MMI { 27 class PointerEvent; 28 } // namespace OHOS::MMI 29 30 namespace OHOS::Ace { 31 32 class MouseInfo; 33 constexpr int32_t MOUSE_PRESS_LEFT = 1; 34 static const int32_t MOUSE_BASE_ID = 1000; 35 36 using OnMouseEventFunc = std::function<void(MouseInfo& info)>; 37 38 enum class MouseAction : int32_t { 39 NONE = 0, 40 PRESS = 1, 41 RELEASE = 2, 42 MOVE = 3, 43 WINDOW_ENTER = 4, 44 WINDOW_LEAVE = 5, 45 HOVER, 46 HOVER_ENTER, 47 HOVER_MOVE, 48 HOVER_EXIT, 49 PULL_DOWN, 50 PULL_MOVE, 51 PULL_UP, 52 CANCEL 53 }; 54 55 enum class AccessibilityHoverAction : int32_t { 56 UNKNOWN = -1, 57 HOVER_ENTER, 58 HOVER_MOVE, 59 HOVER_EXIT, 60 HOVER_CANCEL 61 }; 62 63 enum class MouseState : int32_t { 64 NONE = 0, 65 HOVER = 1, 66 }; 67 68 enum class MouseButton : int32_t { 69 NONE_BUTTON = 0, 70 LEFT_BUTTON = 1, 71 RIGHT_BUTTON = 2, 72 MIDDLE_BUTTON = 4, 73 BACK_BUTTON = 8, 74 FORWARD_BUTTON = 16, 75 SIDE_BUTTON = 32, 76 EXTRA_BUTTON = 64, 77 TASK_BUTTON = 128, 78 }; 79 80 enum class HoverEffectType : int32_t { 81 NONE, 82 OPACITY, 83 SCALE, 84 BOARD, 85 AUTO, 86 UNKNOWN, 87 }; 88 89 struct MouseEvent final { 90 int32_t id = 0; 91 float x = 0.0f; 92 float y = 0.0f; 93 float z = 0.0f; 94 float deltaX = 0.0f; 95 float deltaY = 0.0f; 96 float deltaZ = 0.0f; 97 float scrollX = 0.0f; 98 float scrollY = 0.0f; 99 float scrollZ = 0.0f; 100 float screenX = 0.0f; 101 float screenY = 0.0f; 102 MouseAction action = MouseAction::NONE; 103 MouseAction pullAction = MouseAction::NONE; 104 MouseButton button = MouseButton::NONE_BUTTON; 105 int32_t pressedButtons = 0; // combined by MouseButtons 106 TimeStamp time; 107 int64_t deviceId = 0; 108 int32_t targetDisplayId = 0; 109 SourceType sourceType = SourceType::NONE; 110 SourceTool sourceTool = SourceTool::UNKNOWN; 111 std::shared_ptr<MMI::PointerEvent> pointerEvent; 112 int32_t touchEventId = 0; 113 int32_t originalId = 0; 114 std::vector<KeyCode> pressedKeyCodes_; 115 bool isInjected = false; 116 bool isPrivacyMode = false; 117 GetOffsetfinal118 Offset GetOffset() const 119 { 120 return Offset(x, y); 121 } 122 GetScreenOffsetfinal123 Offset GetScreenOffset() const 124 { 125 return Offset(screenX, screenY); 126 } 127 GetIdfinal128 int32_t GetId() const 129 { 130 if (pressedButtons > 0) { 131 return pressedButtons + MOUSE_BASE_ID; 132 } else { 133 return (int32_t)button + MOUSE_BASE_ID; 134 } 135 } 136 GetPointerIdfinal137 int32_t GetPointerId(int32_t pointerId) const 138 { 139 if (pressedButtons > 0) { 140 return pressedButtons + MOUSE_BASE_ID + pointerId; 141 } 142 return static_cast<int32_t>(button) + MOUSE_BASE_ID + pointerId; 143 } 144 CloneWithfinal145 MouseEvent CloneWith(float scale) const 146 { 147 return { .x = x / scale, 148 .y = y / scale, 149 .z = z / scale, 150 .deltaX = deltaX / scale, 151 .deltaY = deltaY / scale, 152 .deltaZ = deltaZ / scale, 153 .scrollX = scrollX / scale, 154 .scrollY = scrollY / scale, 155 .scrollZ = scrollZ / scale, 156 .screenX = screenX / scale, 157 .screenY = screenY / scale, 158 .action = action, 159 .pullAction = pullAction, 160 .button = button, 161 .pressedButtons = pressedButtons, 162 .time = time, 163 .deviceId = deviceId, 164 .targetDisplayId = targetDisplayId, 165 .sourceType = sourceType, 166 .sourceTool = sourceTool, 167 .pointerEvent = pointerEvent, 168 .originalId = originalId, 169 .pressedKeyCodes_ = pressedKeyCodes_, 170 .isInjected = isInjected, 171 .isPrivacyMode = isPrivacyMode 172 }; 173 } 174 CreateScaleEventfinal175 MouseEvent CreateScaleEvent(float scale) const 176 { 177 if (NearZero(scale)) { 178 return CloneWith(1); 179 } 180 return CloneWith(scale); 181 } 182 CreateTouchPointfinal183 TouchEvent CreateTouchPoint() const 184 { 185 TouchType type = TouchType::UNKNOWN; 186 if (action == MouseAction::PRESS) { 187 type = TouchType::DOWN; 188 } else if (action == MouseAction::RELEASE) { 189 type = TouchType::UP; 190 } else if (action == MouseAction::MOVE) { 191 type = TouchType::MOVE; 192 } else if (action == MouseAction::CANCEL) { 193 type = TouchType::CANCEL; 194 } else { 195 type = TouchType::UNKNOWN; 196 } 197 int32_t pointId = id; 198 if (sourceType == SourceType::MOUSE) { 199 pointId = GetPointerId(pointId); 200 } 201 auto pointOriginalId = sourceType == SourceType::MOUSE ? GetId() : originalId; 202 TouchPoint point { .id = pointId, 203 .x = x, 204 .y = y, 205 .screenX = screenX, 206 .screenY = screenY, 207 .downTime = time, 208 .size = 0.0, 209 .isPressed = (type == TouchType::DOWN), 210 .originalId = pointOriginalId }; 211 TouchEvent event; 212 event.SetId(pointId) 213 .SetX(x) 214 .SetY(y) 215 .SetScreenX(screenX) 216 .SetScreenY(screenY) 217 .SetType(type) 218 .SetTime(time) 219 .SetSize(0.0) 220 .SetDeviceId(deviceId) 221 .SetTargetDisplayId(targetDisplayId) 222 .SetSourceType(sourceType) 223 .SetSourceTool(sourceTool) 224 .SetPointerEvent(pointerEvent) 225 .SetTouchEventId(touchEventId) 226 .SetOriginalId(pointOriginalId) 227 .SetIsInjected(isInjected); 228 event.isPrivacyMode = isPrivacyMode; 229 event.pointers.emplace_back(std::move(point)); 230 event.pressedKeyCodes_ = pressedKeyCodes_; 231 return event; 232 } 233 234 MouseEvent operator-(const Offset& offset) const 235 { 236 return { .x = x - offset.GetX(), 237 .y = y - offset.GetY(), 238 .z = z, 239 .deltaX = deltaX, 240 .deltaY = deltaY, 241 .deltaZ = deltaZ, 242 .scrollX = scrollX, 243 .scrollY = scrollY, 244 .scrollZ = scrollZ, 245 .screenX = screenX - offset.GetX(), 246 .screenY = screenY - offset.GetY(), 247 .action = action, 248 .button = button, 249 .pressedButtons = pressedButtons, 250 .time = time, 251 .deviceId = deviceId, 252 .targetDisplayId = targetDisplayId, 253 .sourceType = sourceType, 254 .sourceTool = sourceTool, 255 .pointerEvent = pointerEvent, 256 .originalId = originalId, 257 .pressedKeyCodes_ = pressedKeyCodes_, 258 .isInjected = isInjected, 259 .isPrivacyMode = isPrivacyMode 260 }; 261 } 262 }; 263 264 class MouseInfo : public BaseEventInfo { 265 DECLARE_RELATIONSHIP_OF_CLASSES(MouseInfo, BaseEventInfo); 266 267 public: MouseInfo()268 MouseInfo() : BaseEventInfo("onMouse") {} 269 ~MouseInfo() override = default; 270 SetButton(MouseButton button)271 void SetButton(MouseButton button) 272 { 273 button_ = button; 274 } 275 GetButton()276 MouseButton GetButton() const 277 { 278 return button_; 279 } 280 SetAction(MouseAction action)281 void SetAction(MouseAction action) 282 { 283 action_ = action; 284 } 285 GetAction()286 MouseAction GetAction() const 287 { 288 return action_; 289 } 290 SetPullAction(MouseAction pullAction)291 void SetPullAction(MouseAction pullAction) 292 { 293 pullAction_ = pullAction; 294 } 295 GetPullAction()296 MouseAction GetPullAction() const 297 { 298 return pullAction_; 299 } 300 SetGlobalLocation(const Offset & globalLocation)301 MouseInfo& SetGlobalLocation(const Offset& globalLocation) 302 { 303 globalLocation_ = globalLocation; 304 return *this; 305 } SetLocalLocation(const Offset & localLocation)306 MouseInfo& SetLocalLocation(const Offset& localLocation) 307 { 308 localLocation_ = localLocation; 309 return *this; 310 } 311 SetScreenLocation(const Offset & screenLocation)312 MouseInfo& SetScreenLocation(const Offset& screenLocation) 313 { 314 screenLocation_ = screenLocation; 315 return *this; 316 } 317 GetScreenLocation()318 const Offset& GetScreenLocation() const 319 { 320 return screenLocation_; 321 } 322 GetLocalLocation()323 const Offset& GetLocalLocation() const 324 { 325 return localLocation_; 326 } GetGlobalLocation()327 const Offset& GetGlobalLocation() const 328 { 329 return globalLocation_; 330 } 331 SetPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)332 void SetPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) 333 { 334 pointerEvent_ = pointerEvent; 335 } GetPointerEvent()336 const std::shared_ptr<MMI::PointerEvent> GetPointerEvent() const 337 { 338 return pointerEvent_; 339 } 340 341 private: 342 std::shared_ptr<MMI::PointerEvent> pointerEvent_; 343 MouseButton button_ = MouseButton::NONE_BUTTON; 344 MouseAction action_ = MouseAction::NONE; 345 MouseAction pullAction_ = MouseAction::NONE; 346 // global position at which the touch point contacts the screen. 347 Offset globalLocation_; 348 // Different from global location, The local location refers to the location of the contact point relative to the 349 // current node which has the recognizer. 350 Offset localLocation_; 351 Offset screenLocation_; 352 }; 353 354 using HoverEffectFunc = std::function<void(bool)>; 355 356 class HoverInfo; 357 class HoverInfo : public BaseEventInfo { 358 DECLARE_RELATIONSHIP_OF_CLASSES(HoverInfo, BaseEventInfo); 359 360 public: HoverInfo()361 HoverInfo() : BaseEventInfo("onHover") {} 362 ~HoverInfo() override = default; 363 }; 364 365 class AccessibilityHoverInfo : public BaseEventInfo { 366 DECLARE_RELATIONSHIP_OF_CLASSES(AccessibilityHoverInfo, BaseEventInfo); 367 368 public: AccessibilityHoverInfo()369 AccessibilityHoverInfo() : BaseEventInfo("onAccessibilityHover") {} 370 ~AccessibilityHoverInfo() override = default; 371 SetGlobalLocation(const Offset & globalLocation)372 AccessibilityHoverInfo& SetGlobalLocation(const Offset& globalLocation) 373 { 374 globalLocation_ = globalLocation; 375 return *this; 376 } SetLocalLocation(const Offset & localLocation)377 AccessibilityHoverInfo& SetLocalLocation(const Offset& localLocation) 378 { 379 localLocation_ = localLocation; 380 return *this; 381 } 382 SetScreenLocation(const Offset & screenLocation)383 AccessibilityHoverInfo& SetScreenLocation(const Offset& screenLocation) 384 { 385 screenLocation_ = screenLocation; 386 return *this; 387 } 388 GetScreenLocation()389 const Offset& GetScreenLocation() const 390 { 391 return screenLocation_; 392 } 393 GetLocalLocation()394 const Offset& GetLocalLocation() const 395 { 396 return localLocation_; 397 } 398 GetGlobalLocation()399 const Offset& GetGlobalLocation() const 400 { 401 return globalLocation_; 402 } 403 GetActionType()404 AccessibilityHoverAction GetActionType() const 405 { 406 return actionType_; 407 } 408 SetActionType(AccessibilityHoverAction type)409 void SetActionType(AccessibilityHoverAction type) 410 { 411 actionType_ = type; 412 } 413 414 private: 415 // global position at which the touch point contacts the screen. 416 Offset globalLocation_; 417 // Different from global location, The local location refers to the location of the contact point relative to the 418 // current node which has the recognizer. 419 Offset localLocation_; 420 421 Offset screenLocation_; 422 423 // touch type 424 AccessibilityHoverAction actionType_ = AccessibilityHoverAction::UNKNOWN; 425 }; 426 427 using OnHoverFunc = std::function<void(bool, HoverInfo& info)>; 428 using OnHoverEventFunc = std::function<void(bool)>; 429 430 using OnAccessibilityHoverFunc = std::function<void(bool, AccessibilityHoverInfo& info)>; 431 432 class MouseEventTarget : public virtual TouchEventTarget { 433 DECLARE_ACE_TYPE(MouseEventTarget, TouchEventTarget); 434 435 public: MouseEventTarget(const std::string & nodeName,int32_t nodeId)436 MouseEventTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {} 437 ~MouseEventTarget() override = default; 438 SetCallback(const OnMouseEventFunc & onMouseCallback)439 void SetCallback(const OnMouseEventFunc& onMouseCallback) 440 { 441 onMouseCallback_ = onMouseCallback; 442 } 443 HandleMouseEvent(const MouseEvent & event)444 bool HandleMouseEvent(const MouseEvent& event) 445 { 446 if (!onMouseCallback_) { 447 return false; 448 } 449 MouseInfo info; 450 info.SetPointerEvent(event.pointerEvent); 451 info.SetButton(event.button); 452 info.SetAction(event.action); 453 info.SetPullAction(event.pullAction); 454 info.SetGlobalLocation(event.GetOffset()); 455 Offset localLocation = Offset( 456 event.GetOffset().GetX() - coordinateOffset_.GetX(), event.GetOffset().GetY() - coordinateOffset_.GetY()); 457 info.SetLocalLocation(localLocation); 458 info.SetScreenLocation(event.GetScreenOffset()); 459 info.SetTimeStamp(event.time); 460 info.SetDeviceId(event.deviceId); 461 info.SetTargetDisplayId(event.targetDisplayId); 462 info.SetSourceDevice(event.sourceType); 463 info.SetSourceTool(event.sourceTool); 464 info.SetTarget(GetEventTarget().value_or(EventTarget())); 465 info.SetPressedKeyCodes(event.pressedKeyCodes_); 466 // onMouseCallback_ may be overwritten in its invoke so we copy it first 467 auto onMouseCallback = onMouseCallback_; 468 onMouseCallback(info); 469 return info.IsStopPropagation(); 470 } 471 DispatchEvent(const TouchEvent & point)472 bool DispatchEvent(const TouchEvent& point) override 473 { 474 return false; 475 } 476 // if return false means need to stop event bubbling. HandleEvent(const TouchEvent & point)477 bool HandleEvent(const TouchEvent& point) override 478 { 479 return false; 480 } 481 482 private: 483 OnMouseEventFunc onMouseCallback_; 484 }; 485 486 class HoverEventTarget : public virtual TouchEventTarget { 487 DECLARE_ACE_TYPE(HoverEventTarget, TouchEventTarget); 488 489 public: HoverEventTarget(const std::string & nodeName,int32_t nodeId)490 HoverEventTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {} 491 ~HoverEventTarget() override = default; 492 SetCallback(const OnHoverEventFunc & onHoverCallback)493 void SetCallback(const OnHoverEventFunc& onHoverCallback) 494 { 495 onHoverCallback_ = onHoverCallback; 496 } SetCallback(const OnHoverFunc & onHoverEventCallback)497 void SetCallback(const OnHoverFunc& onHoverEventCallback) 498 { 499 onHoverEventCallback_ = onHoverEventCallback; 500 } 501 SetAccessibilityHoverCallback(const OnAccessibilityHoverFunc & onAccessibilityHoverCallback)502 void SetAccessibilityHoverCallback(const OnAccessibilityHoverFunc& onAccessibilityHoverCallback) 503 { 504 onAccessibilityHoverCallback_ = onAccessibilityHoverCallback; 505 } 506 SetPenHoverCallback(const OnHoverFunc & onPenHoverEventCallback)507 void SetPenHoverCallback(const OnHoverFunc& onPenHoverEventCallback) 508 { 509 onPenHoverEventCallback_ = onPenHoverEventCallback; 510 } 511 512 bool HandleHoverEvent(bool isHovered, const MouseEvent& event); 513 514 void HandleAccessibilityHoverEvent(bool isHovered, const TouchEvent& event); 515 516 bool HandlePenHoverEvent(bool isHovered, const TouchEvent& event); 517 IsHoverTarget()518 bool IsHoverTarget() const 519 { 520 return onHoverCallback_ != nullptr || onHoverEventCallback_ != nullptr; 521 } 522 IsAccessibilityHoverTarget()523 bool IsAccessibilityHoverTarget() 524 { 525 return onAccessibilityHoverCallback_ != nullptr; 526 } 527 IsPenHoverTarget()528 bool IsPenHoverTarget() const 529 { 530 return onPenHoverEventCallback_ != nullptr; 531 } 532 HandleHoverEvent(bool isHovered)533 bool HandleHoverEvent(bool isHovered) 534 { 535 if (!onHoverCallback_) { 536 return false; 537 } 538 onHoverCallback_(isHovered); 539 return true; 540 } 541 DispatchEvent(const TouchEvent & point)542 bool DispatchEvent(const TouchEvent& point) override 543 { 544 return false; 545 } HandleEvent(const TouchEvent & point)546 bool HandleEvent(const TouchEvent& point) override 547 { 548 return false; 549 } 550 551 AccessibilityHoverAction ConvertAccessibilityHoverAction(TouchType type); 552 553 private: 554 OnHoverEventFunc onHoverCallback_; 555 OnHoverFunc onHoverEventCallback_; 556 OnAccessibilityHoverFunc onAccessibilityHoverCallback_; 557 OnHoverFunc onPenHoverEventCallback_; 558 }; 559 560 class HoverEffectTarget : public virtual TouchEventTarget { 561 DECLARE_ACE_TYPE(HoverEffectTarget, TouchEventTarget); 562 563 public: HoverEffectTarget(const std::string & nodeName,int32_t nodeId)564 HoverEffectTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {} 565 ~HoverEffectTarget() override = default; 566 SetHoverNode(const WeakPtr<NG::FrameNode> & node)567 void SetHoverNode(const WeakPtr<NG::FrameNode>& node) 568 { 569 hoverNode_ = node; 570 } GetHoverNode()571 WeakPtr<NG::FrameNode> GetHoverNode() const 572 { 573 return hoverNode_; 574 } 575 DispatchEvent(const TouchEvent & point)576 bool DispatchEvent(const TouchEvent& point) override 577 { 578 return false; 579 } 580 // if return false means need to stop event bubbling. HandleEvent(const TouchEvent & point)581 bool HandleEvent(const TouchEvent& point) override 582 { 583 return false; 584 } 585 586 private: 587 WeakPtr<NG::FrameNode> hoverNode_; 588 }; 589 590 using MouseTestResult = std::list<RefPtr<MouseEventTarget>>; 591 using HoverTestResult = std::list<RefPtr<HoverEventTarget>>; 592 593 } // namespace OHOS::Ace 594 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_MOUSE_EVENT_H 595