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 GetOffsetfinal102 Offset GetOffset() const 103 { 104 return Offset(x, y); 105 } 106 GetScreenOffsetfinal107 Offset GetScreenOffset() const 108 { 109 return Offset(screenX, screenY); 110 } 111 GetIdfinal112 int32_t GetId() const 113 { 114 if (pressedButtons > 0) { 115 return pressedButtons + MOUSE_BASE_ID; 116 } else { 117 return (int32_t)button + MOUSE_BASE_ID; 118 } 119 } 120 CreateScaleEventfinal121 MouseEvent CreateScaleEvent(float scale) const 122 { 123 if (NearZero(scale)) { 124 return { .x = x, 125 .y = y, 126 .z = z, 127 .deltaX = deltaX, 128 .deltaY = deltaY, 129 .deltaZ = deltaZ, 130 .scrollX = scrollX, 131 .scrollY = scrollY, 132 .scrollZ = scrollZ, 133 .screenX = screenX, 134 .screenY = screenY, 135 .action = action, 136 .pullAction = pullAction, 137 .button = button, 138 .pressedButtons = pressedButtons, 139 .time = time, 140 .deviceId = deviceId, 141 .targetDisplayId = targetDisplayId, 142 .sourceType = sourceType, 143 .pointerEvent = pointerEvent }; 144 } 145 146 return { .x = x / scale, 147 .y = y / scale, 148 .z = z / scale, 149 .deltaX = deltaX / scale, 150 .deltaY = deltaY / scale, 151 .deltaZ = deltaZ / scale, 152 .scrollX = scrollX / scale, 153 .scrollY = scrollY / scale, 154 .scrollZ = scrollZ / scale, 155 .screenX = screenX / scale, 156 .screenY = screenY / scale, 157 .action = action, 158 .pullAction = pullAction, 159 .button = button, 160 .pressedButtons = pressedButtons, 161 .time = time, 162 .deviceId = deviceId, 163 .targetDisplayId = targetDisplayId, 164 .sourceType = sourceType, 165 .pointerEvent = pointerEvent }; 166 } 167 CreateTouchPointfinal168 TouchEvent CreateTouchPoint() const 169 { 170 TouchType type = TouchType::UNKNOWN; 171 if (action == MouseAction::PRESS) { 172 type = TouchType::DOWN; 173 } else if (action == MouseAction::RELEASE) { 174 type = TouchType::UP; 175 } else if (action == MouseAction::MOVE) { 176 type = TouchType::MOVE; 177 } else { 178 type = TouchType::UNKNOWN; 179 } 180 int32_t pointId = id; 181 if (sourceType == SourceType::MOUSE) { 182 pointId = GetId(); 183 } 184 TouchPoint point { .id = pointId, 185 .x = x, 186 .y = y, 187 .screenX = screenX, 188 .screenY = screenY, 189 .downTime = time, 190 .size = 0.0, 191 .isPressed = (type == TouchType::DOWN) }; 192 TouchEvent event { .id = pointId, 193 .x = x, 194 .y = y, 195 .screenX = screenX, 196 .screenY = screenY, 197 .type = type, 198 .time = time, 199 .size = 0.0, 200 .deviceId = deviceId, 201 .targetDisplayId = targetDisplayId, 202 .sourceType = sourceType, 203 .pointerEvent = pointerEvent }; 204 event.pointers.emplace_back(std::move(point)); 205 return event; 206 } 207 208 MouseEvent operator-(const Offset& offset) const 209 { 210 return { .x = x - offset.GetX(), 211 .y = y - offset.GetY(), 212 .z = z, 213 .deltaX = deltaX, 214 .deltaY = deltaY, 215 .deltaZ = deltaZ, 216 .scrollX = scrollX, 217 .scrollY = scrollY, 218 .scrollZ = scrollZ, 219 .screenX = screenX - offset.GetX(), 220 .screenY = screenY - offset.GetY(), 221 .action = action, 222 .button = button, 223 .pressedButtons = pressedButtons, 224 .time = time, 225 .deviceId = deviceId, 226 .targetDisplayId = targetDisplayId, 227 .sourceType = sourceType, 228 .pointerEvent = pointerEvent }; 229 } 230 }; 231 232 class MouseInfo : public BaseEventInfo { 233 DECLARE_RELATIONSHIP_OF_CLASSES(MouseInfo, BaseEventInfo); 234 235 public: MouseInfo()236 MouseInfo() : BaseEventInfo("onMouse") {} 237 ~MouseInfo() override = default; 238 SetButton(MouseButton button)239 void SetButton(MouseButton button) 240 { 241 button_ = button; 242 } 243 GetButton()244 MouseButton GetButton() const 245 { 246 return button_; 247 } 248 SetAction(MouseAction action)249 void SetAction(MouseAction action) 250 { 251 action_ = action; 252 } 253 GetAction()254 MouseAction GetAction() const 255 { 256 return action_; 257 } 258 SetGlobalLocation(const Offset & globalLocation)259 MouseInfo& SetGlobalLocation(const Offset& globalLocation) 260 { 261 globalLocation_ = globalLocation; 262 return *this; 263 } SetLocalLocation(const Offset & localLocation)264 MouseInfo& SetLocalLocation(const Offset& localLocation) 265 { 266 localLocation_ = localLocation; 267 return *this; 268 } 269 SetScreenLocation(const Offset & screenLocation)270 MouseInfo& SetScreenLocation(const Offset& screenLocation) 271 { 272 screenLocation_ = screenLocation; 273 return *this; 274 } 275 GetScreenLocation()276 const Offset& GetScreenLocation() const 277 { 278 return screenLocation_; 279 } 280 GetLocalLocation()281 const Offset& GetLocalLocation() const 282 { 283 return localLocation_; 284 } GetGlobalLocation()285 const Offset& GetGlobalLocation() const 286 { 287 return globalLocation_; 288 } 289 SetPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)290 void SetPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) 291 { 292 pointerEvent_ = pointerEvent; 293 } GetPointerEvent()294 const std::shared_ptr<MMI::PointerEvent> GetPointerEvent() const 295 { 296 return pointerEvent_; 297 } 298 299 private: 300 std::shared_ptr<MMI::PointerEvent> pointerEvent_; 301 MouseButton button_ = MouseButton::NONE_BUTTON; 302 MouseAction action_ = MouseAction::NONE; 303 // global position at which the touch point contacts the screen. 304 Offset globalLocation_; 305 // Different from global location, The local location refers to the location of the contact point relative to the 306 // current node which has the recognizer. 307 Offset localLocation_; 308 Offset screenLocation_; 309 }; 310 311 using HoverEffectFunc = std::function<void(bool)>; 312 313 class HoverInfo; 314 class HoverInfo : public BaseEventInfo { 315 DECLARE_RELATIONSHIP_OF_CLASSES(HoverInfo, BaseEventInfo); 316 317 public: HoverInfo()318 HoverInfo() : BaseEventInfo("onHover") {} 319 ~HoverInfo() override = default; 320 }; 321 322 using OnHoverFunc = std::function<void(bool, HoverInfo& info)>; 323 using OnHoverEventFunc = std::function<void(bool)>; 324 325 class MouseEventTarget : public virtual TouchEventTarget { 326 DECLARE_ACE_TYPE(MouseEventTarget, TouchEventTarget); 327 328 public: MouseEventTarget(const std::string & nodeName,int32_t nodeId)329 MouseEventTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {} 330 ~MouseEventTarget() override = default; 331 SetCallback(const OnMouseEventFunc & onMouseCallback)332 void SetCallback(const OnMouseEventFunc& onMouseCallback) 333 { 334 onMouseCallback_ = onMouseCallback; 335 } 336 HandleMouseEvent(const MouseEvent & event)337 bool HandleMouseEvent(const MouseEvent& event) 338 { 339 if (!onMouseCallback_) { 340 return false; 341 } 342 MouseInfo info; 343 info.SetPointerEvent(event.pointerEvent); 344 info.SetButton(event.button); 345 info.SetAction(event.action); 346 info.SetGlobalLocation(event.GetOffset()); 347 Offset localLocation = Offset( 348 event.GetOffset().GetX() - coordinateOffset_.GetX(), event.GetOffset().GetY() - coordinateOffset_.GetY()); 349 info.SetLocalLocation(localLocation); 350 info.SetScreenLocation(event.GetScreenOffset()); 351 info.SetTimeStamp(event.time); 352 info.SetDeviceId(event.deviceId); 353 info.SetTargetDisplayId(event.targetDisplayId); 354 info.SetSourceDevice(event.sourceType); 355 info.SetTarget(GetEventTarget().value_or(EventTarget())); 356 onMouseCallback_(info); 357 return info.IsStopPropagation(); 358 } 359 DispatchEvent(const TouchEvent & point)360 bool DispatchEvent(const TouchEvent& point) override 361 { 362 return false; 363 } 364 // if return false means need to stop event bubbling. HandleEvent(const TouchEvent & point)365 bool HandleEvent(const TouchEvent& point) override 366 { 367 return false; 368 } 369 370 private: 371 OnMouseEventFunc onMouseCallback_; 372 }; 373 374 class HoverEventTarget : public virtual TouchEventTarget { 375 DECLARE_ACE_TYPE(HoverEventTarget, TouchEventTarget); 376 377 public: HoverEventTarget(const std::string & nodeName,int32_t nodeId)378 HoverEventTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {} 379 ~HoverEventTarget() override = default; 380 SetCallback(const OnHoverEventFunc & onHoverCallback)381 void SetCallback(const OnHoverEventFunc& onHoverCallback) 382 { 383 onHoverCallback_ = onHoverCallback; 384 } SetCallback(const OnHoverFunc & onHoverEventCallback)385 void SetCallback(const OnHoverFunc& onHoverEventCallback) 386 { 387 onHoverEventCallback_ = onHoverEventCallback; 388 } 389 390 bool HandleHoverEvent(bool isHovered, const MouseEvent& event); 391 HandleHoverEvent(bool isHovered)392 bool HandleHoverEvent(bool isHovered) 393 { 394 if (!onHoverCallback_) { 395 return false; 396 } 397 onHoverCallback_(isHovered); 398 return true; 399 } 400 DispatchEvent(const TouchEvent & point)401 bool DispatchEvent(const TouchEvent& point) override 402 { 403 return false; 404 } HandleEvent(const TouchEvent & point)405 bool HandleEvent(const TouchEvent& point) override 406 { 407 return false; 408 } 409 410 private: 411 OnHoverEventFunc onHoverCallback_; 412 OnHoverFunc onHoverEventCallback_; 413 }; 414 415 class HoverEffectTarget : public virtual TouchEventTarget { 416 DECLARE_ACE_TYPE(HoverEffectTarget, TouchEventTarget); 417 418 public: HoverEffectTarget(const std::string & nodeName,int32_t nodeId)419 HoverEffectTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {} 420 ~HoverEffectTarget() override = default; 421 SetHoverNode(const WeakPtr<NG::FrameNode> & node)422 void SetHoverNode(const WeakPtr<NG::FrameNode>& node) 423 { 424 hoverNode_ = node; 425 } GetHoverNode()426 WeakPtr<NG::FrameNode> GetHoverNode() const 427 { 428 return hoverNode_; 429 } 430 DispatchEvent(const TouchEvent & point)431 bool DispatchEvent(const TouchEvent& point) override 432 { 433 return false; 434 } 435 // if return false means need to stop event bubbling. HandleEvent(const TouchEvent & point)436 bool HandleEvent(const TouchEvent& point) override 437 { 438 return false; 439 } 440 441 private: 442 WeakPtr<NG::FrameNode> hoverNode_; 443 }; 444 445 using MouseTestResult = std::list<RefPtr<MouseEventTarget>>; 446 using HoverTestResult = std::list<RefPtr<HoverEventTarget>>; 447 448 } // namespace OHOS::Ace 449 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_MOUSE_EVENT_H 450