1 /* 2 * Copyright (c) 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_AXIS_EVENT_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_AXIS_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 25 namespace OHOS::MMI { 26 class PointerEvent; 27 } // namespace OHOS::MMI 28 29 namespace OHOS::Ace { 30 31 constexpr double MOUSE_WHEEL_DEGREES = 15.0; 32 constexpr double DP_PER_LINE_DESKTOP = 40.0; 33 constexpr Dimension LINE_HEIGHT_DESKTOP = 21.0_vp; 34 constexpr int32_t LINE_NUMBER_DESKTOP = 3; 35 constexpr int32_t DP_PER_LINE_PHONE = 64; 36 constexpr int32_t LINE_NUMBER_PHONE = 1; 37 38 enum class AxisDirection : int32_t { 39 NONE = 0, 40 UP = 1, 41 DOWN = 2, 42 LEFT = 4, 43 RIGHT = 8, 44 UP_LEFT = 5, 45 UP_RIGHT = 9, 46 DOWN_LEFT = 6, 47 DOWN_RIGHT = 10, 48 }; 49 50 enum class AxisAction : int32_t { 51 NONE = 0, 52 BEGIN, 53 UPDATE, 54 END, 55 CANCEL, 56 }; 57 58 struct AxisEvent final { 59 int32_t id = 0; 60 float x = 0.0; 61 float y = 0.0; 62 float screenX = 0.0; 63 float screenY = 0.0; 64 double verticalAxis = 0.0; 65 double horizontalAxis = 0.0; 66 double pinchAxisScale = 0.0; 67 AxisAction action; 68 TimeStamp time; 69 int64_t deviceId = 0; 70 SourceType sourceType = SourceType::NONE; 71 SourceTool sourceTool = SourceTool::UNKNOWN; 72 std::shared_ptr<MMI::PointerEvent> pointerEvent; 73 CreateScaleEventfinal74 AxisEvent CreateScaleEvent(float scale) const 75 { 76 if (NearZero(scale)) { 77 return { .id = id, 78 .x = x, 79 .y = y, 80 .screenX = screenX, 81 .screenY = screenY, 82 .verticalAxis = verticalAxis, 83 .horizontalAxis = horizontalAxis, 84 .pinchAxisScale = pinchAxisScale, 85 .action = action, 86 .time = time, 87 .deviceId = deviceId, 88 .sourceType = sourceType, 89 .sourceTool = sourceTool, 90 .pointerEvent = pointerEvent }; 91 } 92 return { .id = id, 93 .x = x / scale, 94 .y = y / scale, 95 .screenX = screenX / scale, 96 .screenY = screenY / scale, 97 .verticalAxis = verticalAxis, 98 .horizontalAxis = horizontalAxis, 99 .pinchAxisScale = pinchAxisScale, 100 .action = action, 101 .time = time, 102 .deviceId = deviceId, 103 .sourceType = sourceType, 104 .sourceTool = sourceTool, 105 .pointerEvent = pointerEvent }; 106 } 107 GetOffsetfinal108 Offset GetOffset() const 109 { 110 return Offset(x, y); 111 } 112 GetScreenOffsetfinal113 Offset GetScreenOffset() const 114 { 115 return Offset(screenX, screenY); 116 } 117 GetDirectionfinal118 AxisDirection GetDirection() const 119 { 120 uint32_t verticalFlag = 0; 121 uint32_t horizontalFlag = 0; 122 if (LessNotEqual(verticalAxis, 0.0)) { 123 verticalFlag = static_cast<uint32_t>(AxisDirection::UP); 124 } else if (GreatNotEqual(verticalAxis, 0.0)) { 125 verticalFlag = static_cast<uint32_t>(AxisDirection::DOWN); 126 } 127 if (LessNotEqual(horizontalAxis, 0.0)) { 128 horizontalFlag = static_cast<uint32_t>(AxisDirection::LEFT); 129 } else if (GreatNotEqual(horizontalAxis, 0.0)) { 130 horizontalFlag = static_cast<uint32_t>(AxisDirection::RIGHT); 131 } 132 return static_cast<AxisDirection>(verticalFlag | horizontalFlag); 133 } IsDirectionUpfinal134 static bool IsDirectionUp(AxisDirection direction) 135 { 136 return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::UP)); 137 } IsDirectionDownfinal138 static bool IsDirectionDown(AxisDirection direction) 139 { 140 return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::DOWN)); 141 } IsDirectionLeftfinal142 static bool IsDirectionLeft(AxisDirection direction) 143 { 144 return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::LEFT)); 145 } IsDirectionRightfinal146 static bool IsDirectionRight(AxisDirection direction) 147 { 148 return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::RIGHT)); 149 } 150 151 Offset ConvertToOffset(bool isShiftKeyPressed = false, bool hasDifferentDirectionGesture = false) const 152 { 153 Offset result; 154 if (sourceTool == SourceTool::MOUSE) { 155 // Axis event is made by mouse. 156 if (isShiftKeyPressed) { 157 result = Offset(-verticalAxis, -horizontalAxis); 158 } else { 159 if (hasDifferentDirectionGesture) { 160 result = Offset(-horizontalAxis, -verticalAxis); 161 } else { 162 result = Offset(-verticalAxis, -verticalAxis); 163 } 164 } 165 } else { 166 // Axis event is made by others. Include touch-pad. 167 result = Offset(-horizontalAxis, -verticalAxis); 168 } 169 return result * (LINE_HEIGHT_DESKTOP * LINE_NUMBER_DESKTOP / MOUSE_WHEEL_DEGREES).ConvertToPx(); 170 } 171 }; 172 173 class AxisInfo : public BaseEventInfo { 174 DECLARE_RELATIONSHIP_OF_CLASSES(AxisInfo, BaseEventInfo); 175 176 public: AxisInfo()177 AxisInfo() : BaseEventInfo("onAxis") {} AxisInfo(const AxisEvent & event,const Offset & localLocation,const EventTarget & target)178 AxisInfo(const AxisEvent& event, const Offset& localLocation, const EventTarget& target) : BaseEventInfo("onAxis") 179 { 180 action_ = event.action; 181 verticalAxis_ = static_cast<float>(event.verticalAxis); 182 horizontalAxis_ = static_cast<float>(event.horizontalAxis); 183 pinchAxisScale_ = static_cast<float>(event.pinchAxisScale); 184 globalLocation_ = event.GetOffset(); 185 localLocation_ = localLocation; 186 screenLocation_ = Offset(); 187 SetTimeStamp(event.time); 188 SetDeviceId(event.deviceId); 189 SetSourceDevice(event.sourceType); 190 SetTarget(target); 191 } 192 ~AxisInfo() override = default; 193 SetAction(AxisAction action)194 void SetAction(AxisAction action) 195 { 196 action_ = action; 197 } 198 GetAction()199 AxisAction GetAction() const 200 { 201 return action_; 202 } 203 SetVerticalAxis(float axis)204 void SetVerticalAxis(float axis) 205 { 206 verticalAxis_ = axis; 207 } 208 GetVerticalAxis()209 float GetVerticalAxis() const 210 { 211 return verticalAxis_; 212 } 213 SetHorizontalAxis(float axis)214 void SetHorizontalAxis(float axis) 215 { 216 horizontalAxis_ = axis; 217 } 218 GetHorizontalAxis()219 float GetHorizontalAxis() const 220 { 221 return horizontalAxis_; 222 } 223 SetPinchAxisScale(float scale)224 void SetPinchAxisScale(float scale) 225 { 226 pinchAxisScale_ = scale; 227 } 228 GetPinchAxisScale()229 float GetPinchAxisScale() const 230 { 231 return pinchAxisScale_; 232 } 233 SetGlobalLocation(const Offset & globalLocation)234 AxisInfo& SetGlobalLocation(const Offset& globalLocation) 235 { 236 globalLocation_ = globalLocation; 237 return *this; 238 } SetLocalLocation(const Offset & localLocation)239 AxisInfo& SetLocalLocation(const Offset& localLocation) 240 { 241 localLocation_ = localLocation; 242 return *this; 243 } 244 SetScreenLocation(const Offset & screenLocation)245 AxisInfo& SetScreenLocation(const Offset& screenLocation) 246 { 247 screenLocation_ = screenLocation; 248 return *this; 249 } 250 GetScreenLocation()251 const Offset& GetScreenLocation() const 252 { 253 return screenLocation_; 254 } 255 GetLocalLocation()256 const Offset& GetLocalLocation() const 257 { 258 return localLocation_; 259 } GetGlobalLocation()260 const Offset& GetGlobalLocation() const 261 { 262 return globalLocation_; 263 } 264 265 private: 266 AxisAction action_ = AxisAction::NONE; 267 float verticalAxis_ = 0.0; 268 float horizontalAxis_ = 0.0; 269 float pinchAxisScale_ = 0.0; 270 // global position at which the touch point contacts the screen. 271 Offset globalLocation_; 272 // Different from global location, The local location refers to the location of the contact point relative to the 273 // current node which has the recognizer. 274 Offset localLocation_; 275 Offset screenLocation_; 276 }; 277 278 using OnAxisEventFunc = std::function<void(AxisInfo&)>; 279 using GetEventTargetImpl = std::function<std::optional<EventTarget>()>; 280 281 class AxisEventTarget : public virtual AceType { 282 DECLARE_ACE_TYPE(AxisEventTarget, AceType); 283 284 public: 285 AxisEventTarget() = default; AxisEventTarget(std::string frameName)286 AxisEventTarget(std::string frameName) : frameName_(std::move(frameName)) {} 287 ~AxisEventTarget() override = default; 288 SetOnAxisCallback(const OnAxisEventFunc & onAxisCallback)289 void SetOnAxisCallback(const OnAxisEventFunc& onAxisCallback) 290 { 291 onAxisCallback_ = onAxisCallback; 292 } 293 SetCoordinateOffset(const NG::OffsetF & coordinateOffset)294 void SetCoordinateOffset(const NG::OffsetF& coordinateOffset) 295 { 296 coordinateOffset_ = coordinateOffset; 297 } 298 SetGetEventTargetImpl(const GetEventTargetImpl & getEventTargetImpl)299 void SetGetEventTargetImpl(const GetEventTargetImpl& getEventTargetImpl) 300 { 301 getEventTargetImpl_ = getEventTargetImpl; 302 } 303 GetEventTarget()304 std::optional<EventTarget> GetEventTarget() const 305 { 306 if (getEventTargetImpl_) { 307 return getEventTargetImpl_(); 308 } 309 return std::nullopt; 310 } 311 SetFrameName(const std::string & frameName)312 void SetFrameName(const std::string& frameName) 313 { 314 frameName_ = frameName; 315 } 316 GetFrameName()317 std::string GetFrameName() const 318 { 319 return frameName_; 320 } 321 HandleAxisEvent(const AxisEvent & event)322 bool HandleAxisEvent(const AxisEvent& event) 323 { 324 if (!onAxisCallback_) { 325 return false; 326 } 327 Offset localLocation = Offset( 328 event.GetOffset().GetX() - coordinateOffset_.GetX(), event.GetOffset().GetY() - coordinateOffset_.GetY()); 329 AxisInfo info = AxisInfo(event, localLocation, GetEventTarget().value_or(EventTarget())); 330 onAxisCallback_(info); 331 return true; 332 } 333 HandleEvent(const AxisEvent & event)334 virtual void HandleEvent(const AxisEvent& event) {} 335 336 private: 337 OnAxisEventFunc onAxisCallback_; 338 NG::OffsetF coordinateOffset_; 339 GetEventTargetImpl getEventTargetImpl_; 340 std::string frameName_ = "Unknown"; 341 }; 342 343 using AxisTestResult = std::list<RefPtr<AxisEventTarget>>; 344 345 } // namespace OHOS::Ace 346 347 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_AXIS_EVENT_H