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