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 #include <utility> 21 22 #include "base/geometry/offset.h" 23 #include "base/memory/ace_type.h" 24 #include "core/components_ng/event/event_constants.h" 25 #include "core/event/ace_events.h" 26 27 namespace OHOS::MMI { 28 class PointerEvent; 29 } // namespace OHOS::MMI 30 31 namespace OHOS::Ace { 32 struct UIInputEvent { 33 virtual ~UIInputEvent() = default; 34 TimeStamp time; 35 UIInputEventType eventType = UIInputEventType::NONE; 36 }; 37 38 struct PointerEvent : public UIInputEvent { 39 virtual ~PointerEvent() = default; 40 explicit PointerEvent(float x = {}, float y = {}, float screenX = {}, 41 float screenY = {}, TimeStamp time = {}) xPointerEvent42 :x(x), y(y), screenX(screenX), screenY(screenY) 43 { 44 this->time = time; 45 } 46 float x = {}; 47 float y = {}; 48 float screenX = {}; 49 float screenY = {}; 50 }; 51 52 struct AxisEvent final : public PointerEvent { 53 ~AxisEvent() = default; 54 int32_t id = 0; 55 56 double verticalAxis = 0.0; 57 double horizontalAxis = 0.0; 58 double pinchAxisScale = 0.0; 59 double rotateAxisAngle = 0.0; 60 bool isRotationEvent = false; 61 AxisAction action = AxisAction::NONE; 62 int64_t deviceId = 0; 63 SourceType sourceType = SourceType::NONE; 64 SourceTool sourceTool = SourceTool::UNKNOWN; 65 std::shared_ptr<const MMI::PointerEvent> pointerEvent; 66 int32_t touchEventId = 0; 67 std::vector<KeyCode> pressedCodes; 68 69 // Coordinates relative to the upper-left corner of the current component 70 float localX = 0.0; 71 float localY = 0.0; 72 73 int32_t targetDisplayId = 0; 74 int32_t originalId = 0; 75 bool isInjected = false; 76 float targetPositionX = 0.0; 77 float targetPositionY = 0.0; 78 float targetGlobalPositionX = 0.0; 79 float targetGlobalPositionY = 0.0; 80 float width = 0.0; 81 float height = 0.0; 82 uint64_t modifierKeyState = 0; 83 84 int32_t scrollStep = 0; 85 AxisEventfinal86 AxisEvent() 87 { 88 eventType = UIInputEventType::AXIS; 89 } 90 AxisEventfinal91 AxisEvent(int32_t id, float x, float y, float screenX, float screenY, double verticalAxis, double horizontalAxis, 92 double pinchAxisScale, double rotateAxisAngle, bool isRotationEvent, AxisAction action, TimeStamp timestamp, 93 int64_t deviceId, SourceType sourceType, SourceTool sourceTool, 94 std::shared_ptr<const MMI::PointerEvent> pointerEvent, std::vector<KeyCode> pressedCodes, 95 int32_t targetDisplayId, int32_t originalId, bool isInjected, int32_t scrollStep) 96 : PointerEvent(x, y, screenX, screenY, timestamp), id(id), verticalAxis(verticalAxis), 97 horizontalAxis(horizontalAxis), pinchAxisScale(pinchAxisScale), rotateAxisAngle(rotateAxisAngle), 98 isRotationEvent(isRotationEvent), action(action), deviceId(deviceId), sourceType(sourceType), 99 sourceTool(sourceTool), pointerEvent(std::move(pointerEvent)), pressedCodes(pressedCodes), 100 targetDisplayId(targetDisplayId), originalId(originalId), isInjected(isInjected), scrollStep(scrollStep) 101 { 102 eventType = UIInputEventType::AXIS; 103 } 104 105 AxisEvent CreateScaleEvent(float scale) const; 106 Offset GetOffset() const; 107 Offset GetScreenOffset() const; 108 int32_t GetTargetDisplayId() const; 109 AxisDirection GetDirection() const; 110 static bool IsDirectionUp(AxisDirection direction); 111 static bool IsDirectionDown(AxisDirection direction); 112 static bool IsDirectionLeft(AxisDirection direction); 113 static bool IsDirectionRight(AxisDirection direction); 114 Offset ConvertToOffset(bool isShiftKeyPressed = false, bool hasDifferentDirectionGesture = false) const; 115 // MMI has the different direction, need to check truth direction. 116 std::pair<float, float> ConvertToSummationAxisValue(const AxisEvent& event) const; 117 bool HasKey(KeyCode expectCode) const; 118 }; 119 120 class AxisInfo : public BaseEventInfo { 121 DECLARE_RELATIONSHIP_OF_CLASSES(AxisInfo, BaseEventInfo); 122 123 public: AxisInfo()124 AxisInfo() : BaseEventInfo("onAxis") {} 125 AxisInfo(const AxisEvent& event, const Offset& localLocation, const EventTarget& target); 126 ~AxisInfo() override = default; 127 void SetAction(AxisAction action); 128 AxisAction GetAction() const; 129 int32_t GetScrollStep() const; 130 void SetVerticalAxis(float axis); 131 float GetVerticalAxis() const; 132 void SetHorizontalAxis(float axis); 133 float GetHorizontalAxis() const; 134 void SetPinchAxisScale(float scale); 135 float GetPinchAxisScale() const; 136 void SetRotateAxisAngle(float angle); 137 float GetRotateAxisAngle() const; 138 void SetIsRotationEvent(bool rotationFlag); 139 bool GetIsRotationEvent() const; 140 AxisInfo& SetGlobalLocation(const Offset& globalLocation); 141 AxisInfo& SetLocalLocation(const Offset& localLocation); 142 AxisInfo& SetScreenLocation(const Offset& screenLocation); 143 const Offset& GetScreenLocation() const; 144 const Offset& GetLocalLocation() const; 145 const Offset& GetGlobalLocation() const; 146 AxisEvent ConvertToAxisEvent() const; 147 148 private: 149 AxisAction action_ = AxisAction::NONE; 150 int32_t scrollStep_ = 0; 151 float verticalAxis_ = 0.0; 152 float horizontalAxis_ = 0.0; 153 float pinchAxisScale_ = 0.0; 154 float rotateAxisAngle_ = 0.0; 155 bool isRotationEvent_ = false; 156 // global position at which the touch point contacts the screen. 157 Offset globalLocation_; 158 // Different from global location, The local location refers to the location of the contact point relative to the 159 // current node which has the recognizer. 160 Offset localLocation_; 161 Offset screenLocation_; 162 }; 163 164 using OnAxisEventFunc = std::function<void(AxisInfo&)>; 165 using GetEventTargetImpl = std::function<std::optional<EventTarget>()>; 166 167 class AxisEventTarget : public virtual AceType { 168 DECLARE_ACE_TYPE(AxisEventTarget, AceType); 169 170 public: 171 AxisEventTarget() = default; AxisEventTarget(std::string frameName)172 AxisEventTarget(std::string frameName) : frameName_(std::move(frameName)) {} 173 ~AxisEventTarget() override = default; 174 void SetOnAxisCallback(const OnAxisEventFunc& onAxisCallback); 175 void SetCoordinateOffset(const NG::OffsetF& coordinateOffset); 176 void SetGetEventTargetImpl(const GetEventTargetImpl& getEventTargetImpl); 177 std::optional<EventTarget> GetEventTarget() const; 178 void SetFrameName(const std::string& frameName); 179 std::string GetFrameName() const; 180 bool HandleAxisEvent(const AxisEvent& event); HandleEvent(const AxisEvent & event)181 virtual void HandleEvent(const AxisEvent& event) {} 182 183 private: 184 OnAxisEventFunc onAxisCallback_; 185 NG::OffsetF coordinateOffset_; 186 GetEventTargetImpl getEventTargetImpl_; 187 std::string frameName_ = "Unknown"; 188 }; 189 190 class AxisEventChecker final { 191 public: 192 // check if we are receiving axis event in correct sequence 193 // for generic axis event, the correct sequence is begin/update.../end 194 // for other axis event, just update, so no need to check 195 // return true for no error, false for wrong sequence situation 196 bool IsAxisEventSequenceCorrect(const AxisEvent& event); 197 AxisAction GetPreAction() const; 198 private: 199 bool IsGenericAxisEventSequenceCorrect(const AxisEvent& event); 200 AxisAction preActionOld_ = AxisAction::NONE; 201 AxisAction preActionNew_ = AxisAction::NONE; 202 }; 203 204 using AxisTestResult = std::list<RefPtr<AxisEventTarget>>; 205 206 } // namespace OHOS::Ace 207 208 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_AXIS_EVENT_H