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_(info); 467 return info.IsStopPropagation(); 468 } 469 DispatchEvent(const TouchEvent & point)470 bool DispatchEvent(const TouchEvent& point) override 471 { 472 return false; 473 } 474 // if return false means need to stop event bubbling. HandleEvent(const TouchEvent & point)475 bool HandleEvent(const TouchEvent& point) override 476 { 477 return false; 478 } 479 480 private: 481 OnMouseEventFunc onMouseCallback_; 482 }; 483 484 class HoverEventTarget : public virtual TouchEventTarget { 485 DECLARE_ACE_TYPE(HoverEventTarget, TouchEventTarget); 486 487 public: HoverEventTarget(const std::string & nodeName,int32_t nodeId)488 HoverEventTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {} 489 ~HoverEventTarget() override = default; 490 SetCallback(const OnHoverEventFunc & onHoverCallback)491 void SetCallback(const OnHoverEventFunc& onHoverCallback) 492 { 493 onHoverCallback_ = onHoverCallback; 494 } SetCallback(const OnHoverFunc & onHoverEventCallback)495 void SetCallback(const OnHoverFunc& onHoverEventCallback) 496 { 497 onHoverEventCallback_ = onHoverEventCallback; 498 } 499 SetAccessibilityHoverCallback(const OnAccessibilityHoverFunc & onAccessibilityHoverCallback)500 void SetAccessibilityHoverCallback(const OnAccessibilityHoverFunc& onAccessibilityHoverCallback) 501 { 502 onAccessibilityHoverCallback_ = onAccessibilityHoverCallback; 503 } 504 SetPenHoverCallback(const OnHoverFunc & onPenHoverEventCallback)505 void SetPenHoverCallback(const OnHoverFunc& onPenHoverEventCallback) 506 { 507 onPenHoverEventCallback_ = onPenHoverEventCallback; 508 } 509 510 bool HandleHoverEvent(bool isHovered, const MouseEvent& event); 511 512 void HandleAccessibilityHoverEvent(bool isHovered, const TouchEvent& event); 513 514 bool HandlePenHoverEvent(bool isHovered, const TouchEvent& event); 515 IsAccessibilityHoverTarget()516 bool IsAccessibilityHoverTarget() 517 { 518 return onAccessibilityHoverCallback_ != nullptr; 519 } 520 IsPenHoverTarget()521 bool IsPenHoverTarget() const 522 { 523 return onPenHoverEventCallback_ != nullptr; 524 } 525 HandleHoverEvent(bool isHovered)526 bool HandleHoverEvent(bool isHovered) 527 { 528 if (!onHoverCallback_) { 529 return false; 530 } 531 onHoverCallback_(isHovered); 532 return true; 533 } 534 DispatchEvent(const TouchEvent & point)535 bool DispatchEvent(const TouchEvent& point) override 536 { 537 return false; 538 } HandleEvent(const TouchEvent & point)539 bool HandleEvent(const TouchEvent& point) override 540 { 541 return false; 542 } 543 544 AccessibilityHoverAction ConvertAccessibilityHoverAction(TouchType type); 545 546 private: 547 OnHoverEventFunc onHoverCallback_; 548 OnHoverFunc onHoverEventCallback_; 549 OnAccessibilityHoverFunc onAccessibilityHoverCallback_; 550 OnHoverFunc onPenHoverEventCallback_; 551 }; 552 553 class HoverEffectTarget : public virtual TouchEventTarget { 554 DECLARE_ACE_TYPE(HoverEffectTarget, TouchEventTarget); 555 556 public: HoverEffectTarget(const std::string & nodeName,int32_t nodeId)557 HoverEffectTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {} 558 ~HoverEffectTarget() override = default; 559 SetHoverNode(const WeakPtr<NG::FrameNode> & node)560 void SetHoverNode(const WeakPtr<NG::FrameNode>& node) 561 { 562 hoverNode_ = node; 563 } GetHoverNode()564 WeakPtr<NG::FrameNode> GetHoverNode() const 565 { 566 return hoverNode_; 567 } 568 DispatchEvent(const TouchEvent & point)569 bool DispatchEvent(const TouchEvent& point) override 570 { 571 return false; 572 } 573 // if return false means need to stop event bubbling. HandleEvent(const TouchEvent & point)574 bool HandleEvent(const TouchEvent& point) override 575 { 576 return false; 577 } 578 579 private: 580 WeakPtr<NG::FrameNode> hoverNode_; 581 }; 582 583 using MouseTestResult = std::list<RefPtr<MouseEventTarget>>; 584 using HoverTestResult = std::list<RefPtr<HoverEventTarget>>; 585 586 } // namespace OHOS::Ace 587 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_MOUSE_EVENT_H 588