1 /* 2 * Copyright (c) 2021-2022 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_TOUCH_EVENT_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_TOUCH_EVENT_H 18 19 #include <list> 20 21 #include "base/geometry/offset.h" 22 #include "base/memory/ace_type.h" 23 #include "core/event/ace_events.h" 24 #include "core/event/axis_event.h" 25 26 namespace OHOS::Ace { 27 28 enum class TouchType : size_t { 29 DOWN = 0, 30 UP, 31 MOVE, 32 CANCEL, 33 UNKNOWN, 34 }; 35 36 struct TouchPoint final { 37 int32_t id = 0; 38 float x = 0.0f; 39 float y = 0.0f; 40 float screenX = 0.0f; 41 float screenY = 0.0f; 42 TimeStamp downTime; 43 double size = 0.0; 44 float force = 0.0f; 45 std::optional<float> tiltX; 46 std::optional<float> tiltY; 47 SourceTool sourceTool = SourceTool::UNKNOWN; 48 bool isPressed = false; 49 }; 50 51 /** 52 * @brief TouchEvent contains the active change point and a list of all touch points. 53 */ 54 struct TouchEvent final { 55 // the active changed point info 56 // The ID is used to identify the point of contact between the finger and the screen. Different fingers have 57 // different ids. 58 int32_t id = 0; 59 float x = 0.0f; 60 float y = 0.0f; 61 float screenX = 0.0f; 62 float screenY = 0.0f; 63 TouchType type = TouchType::UNKNOWN; 64 // nanosecond time stamp. 65 TimeStamp time; 66 double size = 0.0; 67 float force = 0.0f; 68 std::optional<float> tiltX; 69 std::optional<float> tiltY; 70 int64_t deviceId = 0; 71 SourceType sourceType = SourceType::NONE; 72 SourceTool sourceTool = SourceTool::UNKNOWN; 73 74 // all points on the touch screen. 75 std::vector<TouchPoint> pointers; 76 GetOffsetfinal77 Offset GetOffset() const 78 { 79 return Offset(x, y); 80 } 81 GetScreenOffsetfinal82 Offset GetScreenOffset() const 83 { 84 return Offset(screenX, screenY); 85 } 86 CreateScalePointfinal87 TouchEvent CreateScalePoint(float scale) const 88 { 89 if (NearZero(scale)) { 90 return { id, x, y, screenX, screenY, type, time, size, force, tiltX, tiltY, deviceId, sourceType, 91 sourceTool, pointers }; 92 } 93 auto temp = pointers; 94 std::for_each(temp.begin(), temp.end(), [scale](auto&& point) { 95 point.x = point.x / scale; 96 point.y = point.y / scale; 97 point.screenX = point.screenX / scale; 98 point.screenY = point.screenY / scale; 99 }); 100 return { id, x / scale, y / scale, screenX / scale, screenY / scale, type, time, size, force, tiltX, tiltY, 101 deviceId, sourceType, sourceTool, temp }; 102 } 103 UpdateScalePointfinal104 TouchEvent UpdateScalePoint(float scale, float offsetX, float offsetY, int32_t pointId) const 105 { 106 auto temp = pointers; 107 if (NearZero(scale)) { 108 std::for_each(temp.begin(), temp.end(), [offsetX, offsetY](auto&& point) { 109 point.x = point.x - offsetX; 110 point.y = point.y - offsetY; 111 point.screenX = point.screenX - offsetX; 112 point.screenY = point.screenY - offsetY; 113 }); 114 return { pointId, x - offsetX, y - offsetY, screenX - offsetX, screenY - offsetY, type, time, size, force, 115 tiltX, tiltY, deviceId, sourceType, sourceTool, temp }; 116 } 117 118 std::for_each(temp.begin(), temp.end(), [scale, offsetX, offsetY](auto&& point) { 119 point.x = (point.x - offsetX) / scale; 120 point.y = (point.y - offsetY) / scale; 121 point.screenX = (point.screenX - offsetX) / scale; 122 point.screenY = (point.screenY - offsetY) / scale; 123 }); 124 return { pointId, (x - offsetX) / scale, (y - offsetY) / scale, (screenX - offsetX) / scale, 125 (screenY - offsetY) / scale, type, time, size, force, tiltX, tiltY, deviceId, sourceType, sourceTool, 126 temp }; 127 } 128 UpdatePointersfinal129 TouchEvent UpdatePointers() const 130 { 131 TouchPoint point { .id = id, 132 .x = x, 133 .y = y, 134 .screenX = screenX, 135 .screenY = screenY, 136 .downTime = time, 137 .size = size, 138 .force = force, 139 .isPressed = (type == TouchType::DOWN) }; 140 TouchEvent event { .id = id, 141 .x = x, 142 .y = y, 143 .screenX = screenX, 144 .screenY = screenY, 145 .type = type, 146 .time = time, 147 .size = size, 148 .force = force, 149 .deviceId = deviceId, 150 .sourceType = sourceType }; 151 event.pointers.emplace_back(std::move(point)); 152 return event; 153 } 154 }; 155 156 struct TouchRestrict final { 157 static constexpr uint32_t NONE = 0x00000000; 158 static constexpr uint32_t CLICK = 0x00000001; 159 static constexpr uint32_t LONG_PRESS = 0x00000010; 160 static constexpr uint32_t SWIPE_LEFT = 0x00000100; 161 static constexpr uint32_t SWIPE_RIGHT = 0x00000200; 162 static constexpr uint32_t SWIPE_UP = 0x00000400; 163 static constexpr uint32_t SWIPE_DOWN = 0x00000800; 164 static constexpr uint32_t SWIPE = 0x00000F00; 165 static constexpr uint32_t SWIPE_VERTICAL = 0x0000C00; // Vertical 166 static constexpr uint32_t SWIPE_HORIZONTAL = 0x0000300; // Horizontal 167 static constexpr uint32_t TOUCH = 0xFFFFFFFF; 168 169 uint32_t forbiddenType = NONE; 170 UpdateForbiddenTypefinal171 void UpdateForbiddenType(uint32_t gestureType) 172 { 173 forbiddenType |= gestureType; 174 } 175 SourceType sourceType = SourceType::NONE; 176 177 SourceType hitTestType = SourceType::TOUCH; 178 179 TouchEvent touchEvent; 180 }; 181 182 class TouchCallBackInfo : public BaseEventInfo { 183 DECLARE_RELATIONSHIP_OF_CLASSES(TouchCallBackInfo, BaseEventInfo); 184 185 public: TouchCallBackInfo(TouchType type)186 explicit TouchCallBackInfo(TouchType type) : BaseEventInfo("onTouchEvent"), touchType_(type) {} 187 ~TouchCallBackInfo() override = default; 188 SetScreenX(float screenX)189 void SetScreenX(float screenX) 190 { 191 screenX_ = screenX; 192 } GetScreenX()193 float GetScreenX() const 194 { 195 return screenX_; 196 } SetScreenY(float screenY)197 void SetScreenY(float screenY) 198 { 199 screenY_ = screenY; 200 } GetScreenY()201 float GetScreenY() const 202 { 203 return screenY_; 204 } SetLocalX(float localX)205 void SetLocalX(float localX) 206 { 207 localX_ = localX; 208 } GetLocalX()209 float GetLocalX() const 210 { 211 return localX_; 212 } SetLocalY(float localY)213 void SetLocalY(float localY) 214 { 215 localY_ = localY; 216 } GetLocalY()217 float GetLocalY() const 218 { 219 return localY_; 220 } SetTouchType(TouchType type)221 void SetTouchType(TouchType type) 222 { 223 touchType_ = type; 224 } GetTouchType()225 TouchType GetTouchType() const 226 { 227 return touchType_; 228 } SetTimeStamp(const TimeStamp & time)229 void SetTimeStamp(const TimeStamp& time) 230 { 231 time_ = time; 232 } GetTimeStamp()233 TimeStamp GetTimeStamp() const 234 { 235 return time_; 236 } 237 238 private: 239 float screenX_ = 0.0f; 240 float screenY_ = 0.0f; 241 float localX_ = 0.0f; 242 float localY_ = 0.0f; 243 TouchType touchType_ = TouchType::UNKNOWN; 244 TimeStamp time_; 245 }; 246 247 class TouchLocationInfo : public BaseEventInfo { 248 DECLARE_RELATIONSHIP_OF_CLASSES(TouchLocationInfo, TypeInfoBase); 249 250 public: TouchLocationInfo(int32_t fingerId)251 explicit TouchLocationInfo(int32_t fingerId) : BaseEventInfo("default") 252 { 253 fingerId_ = fingerId; 254 } TouchLocationInfo(const std::string & type,int32_t fingerId)255 explicit TouchLocationInfo(const std::string& type, int32_t fingerId) : BaseEventInfo(type) 256 { 257 fingerId_ = fingerId; 258 } 259 ~TouchLocationInfo() override = default; 260 SetGlobalLocation(const Offset & globalLocation)261 TouchLocationInfo& SetGlobalLocation(const Offset& globalLocation) 262 { 263 globalLocation_ = globalLocation; 264 return *this; 265 } SetLocalLocation(const Offset & localLocation)266 TouchLocationInfo& SetLocalLocation(const Offset& localLocation) 267 { 268 localLocation_ = localLocation; 269 return *this; 270 } 271 SetScreenLocation(const Offset & screenLocation)272 TouchLocationInfo& SetScreenLocation(const Offset& screenLocation) 273 { 274 screenLocation_ = screenLocation; 275 return *this; 276 } 277 GetScreenLocation()278 const Offset& GetScreenLocation() const 279 { 280 return screenLocation_; 281 } 282 GetLocalLocation()283 const Offset& GetLocalLocation() const 284 { 285 return localLocation_; 286 } GetGlobalLocation()287 const Offset& GetGlobalLocation() const 288 { 289 return globalLocation_; 290 } GetFingerId()291 int32_t GetFingerId() const 292 { 293 return fingerId_; 294 } 295 SetSize(double size)296 void SetSize(double size) 297 { 298 size_ = size; 299 } 300 GetSize()301 double GetSize() const 302 { 303 return size_; 304 } 305 SetTouchDeviceId(int64_t deviceId)306 void SetTouchDeviceId(int64_t deviceId) 307 { 308 touchDeviceId_ = deviceId; 309 } 310 GetTouchDeviceId()311 int64_t GetTouchDeviceId() const 312 { 313 return touchDeviceId_; 314 } 315 GetTouchType()316 TouchType GetTouchType() const 317 { 318 return touchType_; 319 } SetTouchType(TouchType type)320 void SetTouchType(TouchType type) 321 { 322 touchType_ = type; 323 } 324 325 private: 326 // The finger id is used to identify the point of contact between the finger and the screen. Different fingers have 327 // different ids. 328 int32_t fingerId_ = -1; 329 330 // global position at which the touch point contacts the screen. 331 Offset globalLocation_; 332 // Different from global location, The local location refers to the location of the contact point relative to the 333 // current node which has the recognizer. 334 Offset localLocation_; 335 336 Offset screenLocation_; 337 338 // finger touch size 339 double size_ = 0.0; 340 341 // input device id 342 int64_t touchDeviceId_ = 0; 343 344 // touch type 345 TouchType touchType_ = TouchType::UNKNOWN; 346 }; 347 348 using GetEventTargetImpl = std::function<std::optional<EventTarget>()>; 349 350 class ACE_EXPORT TouchEventTarget : public virtual AceType { 351 DECLARE_ACE_TYPE(TouchEventTarget, AceType); 352 353 public: 354 TouchEventTarget() = default; TouchEventTarget(std::string nodeName,int32_t nodeId)355 TouchEventTarget(std::string nodeName, int32_t nodeId) : nodeName_(std::move(nodeName)), nodeId_(nodeId) {} 356 ~TouchEventTarget() override = default; 357 358 // if return false means need to stop event dispatch. 359 virtual bool DispatchEvent(const TouchEvent& point) = 0; 360 // if return false means need to stop event bubbling. 361 virtual bool HandleEvent(const TouchEvent& point) = 0; HandleEvent(const AxisEvent & event)362 virtual bool HandleEvent(const AxisEvent& event) 363 { 364 return true; 365 } OnFlushTouchEventsBegin()366 virtual void OnFlushTouchEventsBegin() {} OnFlushTouchEventsEnd()367 virtual void OnFlushTouchEventsEnd() {} 368 SetTouchRestrict(const TouchRestrict & touchRestrict)369 void SetTouchRestrict(const TouchRestrict& touchRestrict) 370 { 371 touchRestrict_ = touchRestrict; 372 } 373 SetGetEventTargetImpl(const GetEventTargetImpl & getEventTargetImpl)374 void SetGetEventTargetImpl(const GetEventTargetImpl& getEventTargetImpl) 375 { 376 getEventTargetImpl_ = getEventTargetImpl; 377 } 378 GetEventTarget()379 std::optional<EventTarget> GetEventTarget() const 380 { 381 if (getEventTargetImpl_) { 382 return getEventTargetImpl_(); 383 } 384 return std::nullopt; 385 } 386 387 // Coordinate offset is used to calculate the local location of the touch point in the render node. SetCoordinateOffset(const Offset & coordinateOffset)388 void SetCoordinateOffset(const Offset& coordinateOffset) 389 { 390 coordinateOffset_ = coordinateOffset; 391 } 392 393 // Gets the coordinate offset to calculate the local location of the touch point by manually. GetCoordinateOffset()394 const Offset& GetCoordinateOffset() const 395 { 396 return coordinateOffset_; 397 } 398 SetSubPipelineGlobalOffset(const Offset & subPipelineGlobalOffset,float viewScale)399 void SetSubPipelineGlobalOffset(const Offset& subPipelineGlobalOffset, float viewScale) 400 { 401 subPipelineGlobalOffset_ = subPipelineGlobalOffset; 402 viewScale_ = viewScale; 403 } 404 DispatchMultiContainerEvent(const TouchEvent & point)405 bool DispatchMultiContainerEvent(const TouchEvent& point) 406 { 407 #ifdef OHOS_STANDARD_SYSTEM 408 if (!subPipelineGlobalOffset_.IsZero()) { 409 auto multiContainerPoint = point.UpdateScalePoint( 410 viewScale_, subPipelineGlobalOffset_.GetX(), subPipelineGlobalOffset_.GetY(), point.id); 411 return DispatchEvent(multiContainerPoint); 412 } 413 #endif 414 return DispatchEvent(point); 415 } 416 HandleMultiContainerEvent(const TouchEvent & point)417 bool HandleMultiContainerEvent(const TouchEvent& point) 418 { 419 #ifdef OHOS_STANDARD_SYSTEM 420 if (!subPipelineGlobalOffset_.IsZero()) { 421 auto multiContainerPoint = point.UpdateScalePoint( 422 viewScale_, subPipelineGlobalOffset_.GetX(), subPipelineGlobalOffset_.GetY(), point.id); 423 return HandleEvent(multiContainerPoint); 424 } 425 #endif 426 return HandleEvent(point); 427 } 428 GetNodeName()429 std::string GetNodeName() const 430 { 431 return nodeName_; 432 } 433 GetNodeId()434 int32_t GetNodeId() const 435 { 436 return nodeId_; 437 } 438 439 protected: 440 Offset coordinateOffset_; 441 GetEventTargetImpl getEventTargetImpl_; 442 TouchRestrict touchRestrict_ { TouchRestrict::NONE }; 443 Offset subPipelineGlobalOffset_; 444 float viewScale_ = 1.0f; 445 std::string nodeName_ = "NULL"; 446 int32_t nodeId_ = -1; 447 }; 448 449 using TouchTestResult = std::list<RefPtr<TouchEventTarget>>; 450 451 class TouchEventInfo : public BaseEventInfo { 452 DECLARE_RELATIONSHIP_OF_CLASSES(TouchEventInfo, BaseEventInfo); 453 454 public: TouchEventInfo(const std::string & type)455 explicit TouchEventInfo(const std::string& type) : BaseEventInfo(type) {} 456 ~TouchEventInfo() override = default; 457 AddTouchLocationInfo(TouchLocationInfo && info)458 void AddTouchLocationInfo(TouchLocationInfo&& info) 459 { 460 touches_.emplace_back(info); 461 } AddChangedTouchLocationInfo(TouchLocationInfo && info)462 void AddChangedTouchLocationInfo(TouchLocationInfo&& info) 463 { 464 changedTouches_.emplace_back(info); 465 } 466 GetTouches()467 const std::list<TouchLocationInfo>& GetTouches() const 468 { 469 return touches_; 470 } GetChangedTouches()471 const std::list<TouchLocationInfo>& GetChangedTouches() const 472 { 473 return changedTouches_; 474 } 475 476 private: 477 std::list<TouchLocationInfo> touches_; 478 std::list<TouchLocationInfo> changedTouches_; 479 }; 480 481 using TouchEventFunc = std::function<void(TouchEventInfo&)>; 482 using OnTouchEventCallback = std::function<void(const TouchEventInfo&)>; 483 using CatchTouchEventCallback = std::function<void()>; 484 485 } // namespace OHOS::Ace 486 487 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_TOUCH_EVENT_H 488