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/touch_event.h" 23 #include "core/pipeline_ng/ui_task_scheduler.h" 24 25 namespace OHOS::MMI { 26 class PointerEvent; 27 } // namespace OHOS::MMI 28 29 namespace OHOS::Ace { 30 31 class MouseInfo; 32 constexpr int32_t MOUSE_PRESS_LEFT = 1; 33 static const int32_t MOUSE_BASE_ID = 1000; 34 35 using OnMouseEventFunc = std::function<void(MouseInfo& info)>; 36 37 enum class MouseAction : int32_t { 38 NONE = 0, 39 PRESS = 1, 40 RELEASE = 2, 41 MOVE = 3, 42 WINDOW_ENTER = 4, 43 WINDOW_LEAVE = 5, 44 HOVER, 45 HOVER_ENTER, 46 HOVER_MOVE, 47 HOVER_EXIT, 48 PULL_DOWN, 49 PULL_MOVE, 50 PULL_UP 51 }; 52 53 enum class MouseState : int32_t { 54 NONE = 0, 55 HOVER = 1, 56 }; 57 58 enum class MouseButton : int32_t { 59 NONE_BUTTON = 0, 60 LEFT_BUTTON = 1, 61 RIGHT_BUTTON = 2, 62 MIDDLE_BUTTON = 4, 63 BACK_BUTTON = 8, 64 FORWARD_BUTTON = 16, 65 SIDE_BUTTON = 32, 66 EXTRA_BUTTON = 64, 67 TASK_BUTTON = 128, 68 }; 69 70 enum class HoverEffectType : int32_t { 71 NONE, 72 OPACITY, 73 SCALE, 74 BOARD, 75 AUTO, 76 UNKNOWN, 77 }; 78 79 struct MouseEvent final { 80 int32_t id = 0; 81 float x = 0.0f; 82 float y = 0.0f; 83 float z = 0.0f; 84 float deltaX = 0.0f; 85 float deltaY = 0.0f; 86 float deltaZ = 0.0f; 87 float scrollX = 0.0f; 88 float scrollY = 0.0f; 89 float scrollZ = 0.0f; 90 float screenX = 0.0f; 91 float screenY = 0.0f; 92 MouseAction action = MouseAction::NONE; 93 MouseAction pullAction = MouseAction::NONE; 94 MouseButton button = MouseButton::NONE_BUTTON; 95 int32_t pressedButtons = 0; // combined by MouseButtons 96 TimeStamp time; 97 int64_t deviceId = 0; 98 int32_t targetDisplayId = 0; 99 SourceType sourceType = SourceType::NONE; 100 std::shared_ptr<MMI::PointerEvent> pointerEvent; 101 std::vector<uint8_t> enhanceData; 102 GetOffsetfinal103 Offset GetOffset() const 104 { 105 return Offset(x, y); 106 } 107 GetScreenOffsetfinal108 Offset GetScreenOffset() const 109 { 110 return Offset(screenX, screenY); 111 } 112 GetIdfinal113 int32_t GetId() const 114 { 115 if (pressedButtons > 0) { 116 return pressedButtons + MOUSE_BASE_ID; 117 } else { 118 return (int32_t)button + MOUSE_BASE_ID; 119 } 120 } 121 CreateScaleEventfinal122 MouseEvent CreateScaleEvent(float scale) const 123 { 124 if (NearZero(scale)) { 125 return { .x = x, 126 .y = y, 127 .z = z, 128 .deltaX = deltaX, 129 .deltaY = deltaY, 130 .deltaZ = deltaZ, 131 .scrollX = scrollX, 132 .scrollY = scrollY, 133 .scrollZ = scrollZ, 134 .screenX = screenX, 135 .screenY = screenY, 136 .action = action, 137 .pullAction = pullAction, 138 .button = button, 139 .pressedButtons = pressedButtons, 140 .time = time, 141 .deviceId = deviceId, 142 .targetDisplayId = targetDisplayId, 143 .sourceType = sourceType, 144 .pointerEvent = pointerEvent, 145 .enhanceData = enhanceData }; 146 } 147 148 return { .x = x / scale, 149 .y = y / scale, 150 .z = z / scale, 151 .deltaX = deltaX / scale, 152 .deltaY = deltaY / scale, 153 .deltaZ = deltaZ / scale, 154 .scrollX = scrollX / scale, 155 .scrollY = scrollY / scale, 156 .scrollZ = scrollZ / scale, 157 .screenX = screenX / scale, 158 .screenY = screenY / scale, 159 .action = action, 160 .pullAction = pullAction, 161 .button = button, 162 .pressedButtons = pressedButtons, 163 .time = time, 164 .deviceId = deviceId, 165 .targetDisplayId = targetDisplayId, 166 .sourceType = sourceType, 167 .pointerEvent = pointerEvent, 168 .enhanceData = enhanceData }; 169 } 170 CreateTouchPointfinal171 TouchEvent CreateTouchPoint() const 172 { 173 TouchType type = TouchType::UNKNOWN; 174 if (action == MouseAction::PRESS) { 175 type = TouchType::DOWN; 176 } else if (action == MouseAction::RELEASE) { 177 type = TouchType::UP; 178 } else if (action == MouseAction::MOVE) { 179 type = TouchType::MOVE; 180 } else { 181 type = TouchType::UNKNOWN; 182 } 183 int32_t pointId = id; 184 if (sourceType == SourceType::MOUSE) { 185 pointId = GetId(); 186 } 187 TouchPoint point { .id = pointId, 188 .x = x, 189 .y = y, 190 .screenX = screenX, 191 .screenY = screenY, 192 .downTime = time, 193 .size = 0.0, 194 .isPressed = (type == TouchType::DOWN) }; 195 TouchEvent event { .id = pointId, 196 .x = x, 197 .y = y, 198 .screenX = screenX, 199 .screenY = screenY, 200 .type = type, 201 .time = time, 202 .size = 0.0, 203 .deviceId = deviceId, 204 .targetDisplayId = targetDisplayId, 205 .sourceType = sourceType, 206 .pointerEvent = pointerEvent, 207 .enhanceData = enhanceData }; 208 event.pointers.emplace_back(std::move(point)); 209 return event; 210 } 211 212 MouseEvent operator-(const Offset& offset) const 213 { 214 return { .x = x - offset.GetX(), 215 .y = y - offset.GetY(), 216 .z = z, 217 .deltaX = deltaX, 218 .deltaY = deltaY, 219 .deltaZ = deltaZ, 220 .scrollX = scrollX, 221 .scrollY = scrollY, 222 .scrollZ = scrollZ, 223 .screenX = screenX - offset.GetX(), 224 .screenY = screenY - offset.GetY(), 225 .action = action, 226 .button = button, 227 .pressedButtons = pressedButtons, 228 .time = time, 229 .deviceId = deviceId, 230 .targetDisplayId = targetDisplayId, 231 .sourceType = sourceType, 232 .pointerEvent = pointerEvent, 233 .enhanceData = enhanceData }; 234 } 235 }; 236 237 class MouseInfo : public BaseEventInfo { 238 DECLARE_RELATIONSHIP_OF_CLASSES(MouseInfo, BaseEventInfo); 239 240 public: MouseInfo()241 MouseInfo() : BaseEventInfo("onMouse") {} 242 ~MouseInfo() override = default; 243 SetButton(MouseButton button)244 void SetButton(MouseButton button) 245 { 246 button_ = button; 247 } 248 GetButton()249 MouseButton GetButton() const 250 { 251 return button_; 252 } 253 SetAction(MouseAction action)254 void SetAction(MouseAction action) 255 { 256 action_ = action; 257 } 258 GetAction()259 MouseAction GetAction() const 260 { 261 return action_; 262 } 263 SetGlobalLocation(const Offset & globalLocation)264 MouseInfo& SetGlobalLocation(const Offset& globalLocation) 265 { 266 globalLocation_ = globalLocation; 267 return *this; 268 } SetLocalLocation(const Offset & localLocation)269 MouseInfo& SetLocalLocation(const Offset& localLocation) 270 { 271 localLocation_ = localLocation; 272 return *this; 273 } 274 SetScreenLocation(const Offset & screenLocation)275 MouseInfo& SetScreenLocation(const Offset& screenLocation) 276 { 277 screenLocation_ = screenLocation; 278 return *this; 279 } 280 GetScreenLocation()281 const Offset& GetScreenLocation() const 282 { 283 return screenLocation_; 284 } 285 GetLocalLocation()286 const Offset& GetLocalLocation() const 287 { 288 return localLocation_; 289 } GetGlobalLocation()290 const Offset& GetGlobalLocation() const 291 { 292 return globalLocation_; 293 } 294 SetPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)295 void SetPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) 296 { 297 pointerEvent_ = pointerEvent; 298 } GetPointerEvent()299 const std::shared_ptr<MMI::PointerEvent> GetPointerEvent() const 300 { 301 return pointerEvent_; 302 } 303 304 private: 305 std::shared_ptr<MMI::PointerEvent> pointerEvent_; 306 MouseButton button_ = MouseButton::NONE_BUTTON; 307 MouseAction action_ = MouseAction::NONE; 308 // global position at which the touch point contacts the screen. 309 Offset globalLocation_; 310 // Different from global location, The local location refers to the location of the contact point relative to the 311 // current node which has the recognizer. 312 Offset localLocation_; 313 Offset screenLocation_; 314 }; 315 316 using HoverEffectFunc = std::function<void(bool)>; 317 318 class HoverInfo; 319 class HoverInfo : public BaseEventInfo { 320 DECLARE_RELATIONSHIP_OF_CLASSES(HoverInfo, BaseEventInfo); 321 322 public: HoverInfo()323 HoverInfo() : BaseEventInfo("onHover") {} 324 ~HoverInfo() override = default; 325 }; 326 327 using OnHoverFunc = std::function<void(bool, HoverInfo& info)>; 328 using OnHoverEventFunc = std::function<void(bool)>; 329 330 class MouseEventTarget : public virtual TouchEventTarget { 331 DECLARE_ACE_TYPE(MouseEventTarget, TouchEventTarget); 332 333 public: MouseEventTarget(const std::string & nodeName,int32_t nodeId)334 MouseEventTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {} 335 ~MouseEventTarget() override = default; 336 SetCallback(const OnMouseEventFunc & onMouseCallback)337 void SetCallback(const OnMouseEventFunc& onMouseCallback) 338 { 339 onMouseCallback_ = onMouseCallback; 340 } 341 HandleMouseEvent(const MouseEvent & event)342 bool HandleMouseEvent(const MouseEvent& event) 343 { 344 if (!onMouseCallback_) { 345 return false; 346 } 347 MouseInfo info; 348 info.SetPointerEvent(event.pointerEvent); 349 info.SetButton(event.button); 350 info.SetAction(event.action); 351 info.SetGlobalLocation(event.GetOffset()); 352 Offset localLocation = Offset( 353 event.GetOffset().GetX() - coordinateOffset_.GetX(), event.GetOffset().GetY() - coordinateOffset_.GetY()); 354 info.SetLocalLocation(localLocation); 355 info.SetScreenLocation(event.GetScreenOffset()); 356 info.SetTimeStamp(event.time); 357 info.SetDeviceId(event.deviceId); 358 info.SetTargetDisplayId(event.targetDisplayId); 359 info.SetSourceDevice(event.sourceType); 360 info.SetTarget(GetEventTarget().value_or(EventTarget())); 361 onMouseCallback_(info); 362 return info.IsStopPropagation(); 363 } 364 DispatchEvent(const TouchEvent & point)365 bool DispatchEvent(const TouchEvent& point) override 366 { 367 return false; 368 } 369 // if return false means need to stop event bubbling. HandleEvent(const TouchEvent & point)370 bool HandleEvent(const TouchEvent& point) override 371 { 372 return false; 373 } 374 375 private: 376 OnMouseEventFunc onMouseCallback_; 377 }; 378 379 class HoverEventTarget : public virtual TouchEventTarget { 380 DECLARE_ACE_TYPE(HoverEventTarget, TouchEventTarget); 381 382 public: HoverEventTarget(const std::string & nodeName,int32_t nodeId)383 HoverEventTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {} 384 ~HoverEventTarget() override = default; 385 SetCallback(const OnHoverEventFunc & onHoverCallback)386 void SetCallback(const OnHoverEventFunc& onHoverCallback) 387 { 388 onHoverCallback_ = onHoverCallback; 389 } SetCallback(const OnHoverFunc & onHoverEventCallback)390 void SetCallback(const OnHoverFunc& onHoverEventCallback) 391 { 392 onHoverEventCallback_ = onHoverEventCallback; 393 } 394 HandleHoverEvent(bool isHovered,const MouseEvent & event)395 bool HandleHoverEvent(bool isHovered, const MouseEvent& event) 396 { 397 if (!onHoverEventCallback_) { 398 return false; 399 } 400 HoverInfo hoverInfo; 401 hoverInfo.SetTimeStamp(event.time); 402 hoverInfo.SetDeviceId(event.deviceId); 403 hoverInfo.SetSourceDevice(event.sourceType); 404 onHoverEventCallback_(isHovered, hoverInfo); 405 if (hoverInfo.IsStopPropagation()) { 406 return false; 407 } 408 return true; 409 } 410 HandleHoverEvent(bool isHovered)411 bool HandleHoverEvent(bool isHovered) 412 { 413 if (!onHoverCallback_) { 414 return false; 415 } 416 onHoverCallback_(isHovered); 417 return true; 418 } 419 DispatchEvent(const TouchEvent & point)420 bool DispatchEvent(const TouchEvent& point) override 421 { 422 return false; 423 } HandleEvent(const TouchEvent & point)424 bool HandleEvent(const TouchEvent& point) override 425 { 426 return false; 427 } 428 429 private: 430 OnHoverEventFunc onHoverCallback_; 431 OnHoverFunc onHoverEventCallback_; 432 }; 433 434 class HoverEffectTarget : public virtual TouchEventTarget { 435 DECLARE_ACE_TYPE(HoverEffectTarget, TouchEventTarget); 436 437 public: HoverEffectTarget(const std::string & nodeName,int32_t nodeId)438 HoverEffectTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {} 439 ~HoverEffectTarget() override = default; 440 SetHoverNode(const WeakPtr<NG::FrameNode> & node)441 void SetHoverNode(const WeakPtr<NG::FrameNode>& node) 442 { 443 hoverNode_ = node; 444 } GetHoverNode()445 WeakPtr<NG::FrameNode> GetHoverNode() const 446 { 447 return hoverNode_; 448 } 449 DispatchEvent(const TouchEvent & point)450 bool DispatchEvent(const TouchEvent& point) override 451 { 452 return false; 453 } 454 // if return false means need to stop event bubbling. HandleEvent(const TouchEvent & point)455 bool HandleEvent(const TouchEvent& point) override 456 { 457 return false; 458 } 459 460 private: 461 WeakPtr<NG::FrameNode> hoverNode_; 462 }; 463 464 using MouseTestResult = std::list<RefPtr<MouseEventTarget>>; 465 using HoverTestResult = std::list<RefPtr<HoverEventTarget>>; 466 467 } // namespace OHOS::Ace 468 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_MOUSE_EVENT_H 469