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 152 class AxisInfo : public BaseEventInfo { 153 DECLARE_RELATIONSHIP_OF_CLASSES(AxisInfo, BaseEventInfo); 154 155 public: AxisInfo()156 AxisInfo() : BaseEventInfo("onAxis") {} AxisInfo(const AxisEvent & event,const Offset & localLocation,const EventTarget & target)157 AxisInfo(const AxisEvent& event, const Offset& localLocation, const EventTarget& target) : BaseEventInfo("onAxis") 158 { 159 action_ = event.action; 160 verticalAxis_ = static_cast<float>(event.verticalAxis); 161 horizontalAxis_ = static_cast<float>(event.horizontalAxis); 162 pinchAxisScale_ = static_cast<float>(event.pinchAxisScale); 163 globalLocation_ = event.GetOffset(); 164 localLocation_ = localLocation; 165 screenLocation_ = Offset(); 166 SetTimeStamp(event.time); 167 SetDeviceId(event.deviceId); 168 SetSourceDevice(event.sourceType); 169 SetTarget(target); 170 } 171 ~AxisInfo() override = default; 172 SetAction(AxisAction action)173 void SetAction(AxisAction action) 174 { 175 action_ = action; 176 } 177 GetAction()178 AxisAction GetAction() const 179 { 180 return action_; 181 } 182 SetVerticalAxis(float axis)183 void SetVerticalAxis(float axis) 184 { 185 verticalAxis_ = axis; 186 } 187 GetVerticalAxis()188 float GetVerticalAxis() const 189 { 190 return verticalAxis_; 191 } 192 SetHorizontalAxis(float axis)193 void SetHorizontalAxis(float axis) 194 { 195 horizontalAxis_ = axis; 196 } 197 GetHorizontalAxis()198 float GetHorizontalAxis() const 199 { 200 return horizontalAxis_; 201 } 202 SetPinchAxisScale(float scale)203 void SetPinchAxisScale(float scale) 204 { 205 pinchAxisScale_ = scale; 206 } 207 GetPinchAxisScale()208 float GetPinchAxisScale() const 209 { 210 return pinchAxisScale_; 211 } 212 SetGlobalLocation(const Offset & globalLocation)213 AxisInfo& SetGlobalLocation(const Offset& globalLocation) 214 { 215 globalLocation_ = globalLocation; 216 return *this; 217 } SetLocalLocation(const Offset & localLocation)218 AxisInfo& SetLocalLocation(const Offset& localLocation) 219 { 220 localLocation_ = localLocation; 221 return *this; 222 } 223 SetScreenLocation(const Offset & screenLocation)224 AxisInfo& SetScreenLocation(const Offset& screenLocation) 225 { 226 screenLocation_ = screenLocation; 227 return *this; 228 } 229 GetScreenLocation()230 const Offset& GetScreenLocation() const 231 { 232 return screenLocation_; 233 } 234 GetLocalLocation()235 const Offset& GetLocalLocation() const 236 { 237 return localLocation_; 238 } GetGlobalLocation()239 const Offset& GetGlobalLocation() const 240 { 241 return globalLocation_; 242 } 243 244 private: 245 AxisAction action_ = AxisAction::NONE; 246 float verticalAxis_ = 0.0; 247 float horizontalAxis_ = 0.0; 248 float pinchAxisScale_ = 0.0; 249 // global position at which the touch point contacts the screen. 250 Offset globalLocation_; 251 // Different from global location, The local location refers to the location of the contact point relative to the 252 // current node which has the recognizer. 253 Offset localLocation_; 254 Offset screenLocation_; 255 }; 256 257 using OnAxisEventFunc = std::function<void(AxisInfo&)>; 258 using GetEventTargetImpl = std::function<std::optional<EventTarget>()>; 259 260 class AxisEventTarget : public virtual AceType { 261 DECLARE_ACE_TYPE(AxisEventTarget, AceType); 262 263 public: 264 AxisEventTarget() = default; AxisEventTarget(std::string frameName)265 AxisEventTarget(std::string frameName) : frameName_(std::move(frameName)) {} 266 ~AxisEventTarget() override = default; 267 SetOnAxisCallback(const OnAxisEventFunc & onAxisCallback)268 void SetOnAxisCallback(const OnAxisEventFunc& onAxisCallback) 269 { 270 onAxisCallback_ = onAxisCallback; 271 } 272 SetCoordinateOffset(const NG::OffsetF & coordinateOffset)273 void SetCoordinateOffset(const NG::OffsetF& coordinateOffset) 274 { 275 coordinateOffset_ = coordinateOffset; 276 } 277 SetGetEventTargetImpl(const GetEventTargetImpl & getEventTargetImpl)278 void SetGetEventTargetImpl(const GetEventTargetImpl& getEventTargetImpl) 279 { 280 getEventTargetImpl_ = getEventTargetImpl; 281 } 282 GetEventTarget()283 std::optional<EventTarget> GetEventTarget() const 284 { 285 if (getEventTargetImpl_) { 286 return getEventTargetImpl_(); 287 } 288 return std::nullopt; 289 } 290 SetFrameName(const std::string & frameName)291 void SetFrameName(const std::string& frameName) 292 { 293 frameName_ = frameName; 294 } 295 GetFrameName()296 std::string GetFrameName() const 297 { 298 return frameName_; 299 } 300 HandleAxisEvent(const AxisEvent & event)301 bool HandleAxisEvent(const AxisEvent& event) 302 { 303 if (!onAxisCallback_) { 304 return false; 305 } 306 Offset localLocation = Offset( 307 event.GetOffset().GetX() - coordinateOffset_.GetX(), event.GetOffset().GetY() - coordinateOffset_.GetY()); 308 AxisInfo info = AxisInfo(event, localLocation, GetEventTarget().value_or(EventTarget())); 309 LOGD("HandleAxisEvent: Node: %{public}s, Action: %{public}d, HorizontalAxis: %{public}f, VeriticalAxis: " 310 "%{public}f, PinchAxis: %{public}f", 311 frameName_.c_str(), info.GetAction(), info.GetHorizontalAxis(), info.GetVerticalAxis(), 312 info.GetPinchAxisScale()); 313 onAxisCallback_(info); 314 return true; 315 } 316 HandleEvent(const AxisEvent & event)317 virtual void HandleEvent(const AxisEvent& event) {} 318 319 private: 320 OnAxisEventFunc onAxisCallback_; 321 NG::OffsetF coordinateOffset_; 322 GetEventTargetImpl getEventTargetImpl_; 323 std::string frameName_ = "Unknown"; 324 }; 325 326 using AxisTestResult = std::list<RefPtr<AxisEventTarget>>; 327 328 } // namespace OHOS::Ace 329 330 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_AXIS_EVENT_H