• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #include "core/event/axis_event.h"
17 
18 #include "base/input_manager/input_manager.h"
19 #include "core/event/key_event.h"
20 
21 namespace OHOS::Ace {
CreateScaleEvent(float scale) const22 AxisEvent AxisEvent::CreateScaleEvent(float scale) const
23 {
24     if (NearZero(scale)) {
25         return { id, x, y, screenX, screenY, verticalAxis, horizontalAxis, pinchAxisScale, rotateAxisAngle,
26             isRotationEvent, action, time, deviceId, sourceType, sourceTool, pointerEvent, pressedCodes,
27             targetDisplayId, originalId, isInjected, scrollStep };
28     }
29     return { id, x / scale, y / scale, screenX / scale, screenY / scale, verticalAxis, horizontalAxis, pinchAxisScale,
30         rotateAxisAngle, isRotationEvent, action, time, deviceId, sourceType, sourceTool, pointerEvent, pressedCodes,
31         targetDisplayId, originalId, isInjected, scrollStep };
32 }
33 
GetOffset() const34 Offset AxisEvent::GetOffset() const
35 {
36     return Offset(x, y);
37 }
38 
GetScreenOffset() const39 Offset AxisEvent::GetScreenOffset() const
40 {
41     return Offset(screenX, screenY);
42 }
43 
GetDirection() const44 AxisDirection AxisEvent::GetDirection() const
45 {
46     uint32_t verticalFlag = 0;
47     uint32_t horizontalFlag = 0;
48     if (LessNotEqual(verticalAxis, 0.0)) {
49         verticalFlag = static_cast<uint32_t>(AxisDirection::UP);
50     } else if (GreatNotEqual(verticalAxis, 0.0)) {
51         verticalFlag = static_cast<uint32_t>(AxisDirection::DOWN);
52     }
53     if (LessNotEqual(horizontalAxis, 0.0)) {
54         horizontalFlag = static_cast<uint32_t>(AxisDirection::LEFT);
55     } else if (GreatNotEqual(horizontalAxis, 0.0)) {
56         horizontalFlag = static_cast<uint32_t>(AxisDirection::RIGHT);
57     }
58     return static_cast<AxisDirection>(verticalFlag | horizontalFlag);
59 }
IsDirectionUp(AxisDirection direction)60 bool AxisEvent::IsDirectionUp(AxisDirection direction)
61 {
62     return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::UP));
63 }
IsDirectionDown(AxisDirection direction)64 bool AxisEvent::IsDirectionDown(AxisDirection direction)
65 {
66     return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::DOWN));
67 }
IsDirectionLeft(AxisDirection direction)68 bool AxisEvent::IsDirectionLeft(AxisDirection direction)
69 {
70     return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::LEFT));
71 }
IsDirectionRight(AxisDirection direction)72 bool AxisEvent::IsDirectionRight(AxisDirection direction)
73 {
74     return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::RIGHT));
75 }
76 
ConvertToOffset(bool isShiftKeyPressed,bool hasDifferentDirectionGesture) const77 Offset AxisEvent::ConvertToOffset(bool isShiftKeyPressed, bool hasDifferentDirectionGesture) const
78 {
79     Offset result;
80     if (sourceTool == SourceTool::MOUSE) {
81         // Axis event is made by mouse.
82         if (isShiftKeyPressed) {
83             result = Offset(-verticalAxis, -horizontalAxis);
84         } else {
85             if (hasDifferentDirectionGesture) {
86                 result = Offset(-horizontalAxis, -verticalAxis);
87             } else {
88                 result = Offset(-verticalAxis, -verticalAxis);
89             }
90         }
91         return result * (LINE_HEIGHT_DESKTOP / MOUSE_WHEEL_DEGREES).ConvertToPx();
92     }
93     // Axis event is made by others. Include touch-pad.
94     result = Offset(-horizontalAxis, -verticalAxis);
95     return result;
96 }
97 
98 // MMI has the different direction, need to check truth direction.
ConvertToSummationAxisValue(const AxisEvent & event) const99 std::pair<float, float> AxisEvent::ConvertToSummationAxisValue(const AxisEvent& event) const
100 {
101     return std::make_pair(event.horizontalAxis - horizontalAxis, event.verticalAxis - verticalAxis);
102 }
103 
HasKey(KeyCode expectCode) const104 bool AxisEvent::HasKey(KeyCode expectCode) const
105 {
106     auto curPressedCode = pressedCodes.rbegin();
107     while (curPressedCode != pressedCodes.rend()) {
108         if (expectCode == *curPressedCode) {
109             return true;
110         }
111         ++curPressedCode;
112     }
113     return false;
114 }
115 
GetTargetDisplayId() const116 int32_t AxisEvent::GetTargetDisplayId() const
117 {
118     return targetDisplayId;
119 }
120 
AxisInfo(const AxisEvent & event,const Offset & localLocation,const EventTarget & target)121 AxisInfo::AxisInfo(const AxisEvent& event, const Offset& localLocation, const EventTarget& target)
122     : BaseEventInfo("onAxis")
123 {
124     action_ = event.action;
125     scrollStep_ = event.scrollStep;
126     verticalAxis_ = static_cast<float>(event.verticalAxis);
127     horizontalAxis_ = static_cast<float>(event.horizontalAxis);
128     pinchAxisScale_ = static_cast<float>(event.pinchAxisScale);
129     rotateAxisAngle_ = static_cast<float>(event.rotateAxisAngle);
130     isRotationEvent_ = event.isRotationEvent;
131     globalLocation_ = event.GetOffset();
132     localLocation_ = localLocation;
133     screenLocation_ = Offset();
134     SetPressedKeyCodes(event.pressedCodes);
135     SetTimeStamp(event.time);
136     SetDeviceId(event.deviceId);
137     SetSourceDevice(event.sourceType);
138     SetTarget(target);
139 }
140 
SetAction(AxisAction action)141 void AxisInfo::SetAction(AxisAction action)
142 {
143     action_ = action;
144 }
145 
GetAction() const146 AxisAction AxisInfo::GetAction() const
147 {
148     return action_;
149 }
150 
GetScrollStep() const151 int32_t AxisInfo::GetScrollStep() const
152 {
153     return scrollStep_;
154 }
155 
SetVerticalAxis(float axis)156 void AxisInfo::SetVerticalAxis(float axis)
157 {
158     verticalAxis_ = axis;
159 }
160 
GetVerticalAxis() const161 float AxisInfo::GetVerticalAxis() const
162 {
163     return verticalAxis_;
164 }
165 
SetHorizontalAxis(float axis)166 void AxisInfo::SetHorizontalAxis(float axis)
167 {
168     horizontalAxis_ = axis;
169 }
170 
GetHorizontalAxis() const171 float AxisInfo::GetHorizontalAxis() const
172 {
173     return horizontalAxis_;
174 }
175 
SetPinchAxisScale(float scale)176 void AxisInfo::SetPinchAxisScale(float scale)
177 {
178     pinchAxisScale_ = scale;
179 }
180 
GetPinchAxisScale() const181 float AxisInfo::GetPinchAxisScale() const
182 {
183     return pinchAxisScale_;
184 }
185 
SetRotateAxisAngle(float angle)186 void AxisInfo::SetRotateAxisAngle(float angle)
187 {
188     rotateAxisAngle_ = angle;
189 }
190 
GetRotateAxisAngle() const191 float AxisInfo::GetRotateAxisAngle() const
192 {
193     return rotateAxisAngle_;
194 }
195 
SetIsRotationEvent(bool rotationFlag)196 void AxisInfo::SetIsRotationEvent(bool rotationFlag)
197 {
198     isRotationEvent_ = rotationFlag;
199 }
200 
GetIsRotationEvent() const201 bool AxisInfo::GetIsRotationEvent() const
202 {
203     return isRotationEvent_;
204 }
205 
SetGlobalLocation(const Offset & globalLocation)206 AxisInfo& AxisInfo::SetGlobalLocation(const Offset& globalLocation)
207 {
208     globalLocation_ = globalLocation;
209     return *this;
210 }
SetLocalLocation(const Offset & localLocation)211 AxisInfo& AxisInfo::SetLocalLocation(const Offset& localLocation)
212 {
213     localLocation_ = localLocation;
214     return *this;
215 }
216 
SetScreenLocation(const Offset & screenLocation)217 AxisInfo& AxisInfo::SetScreenLocation(const Offset& screenLocation)
218 {
219     screenLocation_ = screenLocation;
220     return *this;
221 }
222 
GetScreenLocation() const223 const Offset& AxisInfo::GetScreenLocation() const
224 {
225     return screenLocation_;
226 }
227 
GetLocalLocation() const228 const Offset& AxisInfo::GetLocalLocation() const
229 {
230     return localLocation_;
231 }
GetGlobalLocation() const232 const Offset& AxisInfo::GetGlobalLocation() const
233 {
234     return globalLocation_;
235 }
236 
ConvertToAxisEvent() const237 AxisEvent AxisInfo::ConvertToAxisEvent() const
238 {
239     AxisEvent axisEvent;
240     axisEvent.x = static_cast<float>(globalLocation_.GetX());
241     axisEvent.y = static_cast<float>(globalLocation_.GetY());
242     axisEvent.screenX = static_cast<float>(screenLocation_.GetX());
243     axisEvent.screenY = static_cast<float>(screenLocation_.GetY());
244     axisEvent.scrollStep = scrollStep_;
245     axisEvent.horizontalAxis = horizontalAxis_;
246     axisEvent.verticalAxis = verticalAxis_;
247     axisEvent.pinchAxisScale = pinchAxisScale_;
248     axisEvent.action = action_;
249     axisEvent.rotateAxisAngle = rotateAxisAngle_;
250     axisEvent.time = timeStamp_;
251     axisEvent.localX = static_cast<float>(localLocation_.GetX());
252     axisEvent.localY = static_cast<float>(localLocation_.GetY());
253     axisEvent.sourceType = deviceType_;
254     axisEvent.sourceTool = sourceTool_;
255     const auto& targetLocalOffset = GetTarget().area.GetOffset();
256     const auto& targetOrigin = GetTarget().origin;
257     // width height x y globalx globaly
258     axisEvent.targetPositionX = targetLocalOffset.GetX().ConvertToPx();
259     axisEvent.targetPositionY = targetLocalOffset.GetY().ConvertToPx();
260     axisEvent.targetGlobalPositionX = targetOrigin.GetX().ConvertToPx() + targetLocalOffset.GetX().ConvertToPx();
261     axisEvent.targetGlobalPositionY = targetOrigin.GetY().ConvertToPx() + targetLocalOffset.GetY().ConvertToPx();
262     axisEvent.width = GetTarget().area.GetWidth().ConvertToPx();
263     axisEvent.height = GetTarget().area.GetHeight().ConvertToPx();
264     // deviceid
265     axisEvent.deviceId = GetDeviceId();
266     // modifierkeystates
267     axisEvent.modifierKeyState = CalculateModifierKeyState(GetPressedKeyCodes());
268     return axisEvent;
269 }
270 
SetOnAxisCallback(const OnAxisEventFunc & onAxisCallback)271 void AxisEventTarget::SetOnAxisCallback(const OnAxisEventFunc& onAxisCallback)
272 {
273     onAxisCallback_ = onAxisCallback;
274 }
275 
SetCoordinateOffset(const NG::OffsetF & coordinateOffset)276 void AxisEventTarget::SetCoordinateOffset(const NG::OffsetF& coordinateOffset)
277 {
278     coordinateOffset_ = coordinateOffset;
279 }
280 
SetGetEventTargetImpl(const GetEventTargetImpl & getEventTargetImpl)281 void AxisEventTarget::SetGetEventTargetImpl(const GetEventTargetImpl& getEventTargetImpl)
282 {
283     getEventTargetImpl_ = getEventTargetImpl;
284 }
285 
GetEventTarget() const286 std::optional<EventTarget> AxisEventTarget::GetEventTarget() const
287 {
288     if (getEventTargetImpl_) {
289         return getEventTargetImpl_();
290     }
291     return std::nullopt;
292 }
293 
SetFrameName(const std::string & frameName)294 void AxisEventTarget::SetFrameName(const std::string& frameName)
295 {
296     frameName_ = frameName;
297 }
298 
GetFrameName() const299 std::string AxisEventTarget::GetFrameName() const
300 {
301     return frameName_;
302 }
303 
HandleAxisEvent(const AxisEvent & event)304 bool AxisEventTarget::HandleAxisEvent(const AxisEvent& event)
305 {
306     if (!onAxisCallback_) {
307         return false;
308     }
309     Offset localLocation = Offset(
310         event.GetOffset().GetX() - coordinateOffset_.GetX(), event.GetOffset().GetY() - coordinateOffset_.GetY());
311     AxisInfo info = AxisInfo(event, localLocation, GetEventTarget().value_or(EventTarget()));
312     info.SetScreenLocation(Offset(event.screenX, event.screenY));
313     info.SetSourceTool(event.sourceTool);
314     info.SetStopPropagation(true);
315     onAxisCallback_(info);
316     return info.IsStopPropagation();
317 }
318 
IsAxisEventSequenceCorrect(const AxisEvent & event)319 bool AxisEventChecker::IsAxisEventSequenceCorrect(const AxisEvent& event)
320 {
321     if (event.sourceType == SourceType::MOUSE) { // wheel on mouse or touch pad
322         return IsGenericAxisEventSequenceCorrect(event);
323     }
324 
325     // no check for other axis event, for example the axis event generated by joystick
326     return true;
327 }
328 
GetPreAction() const329 AxisAction AxisEventChecker::GetPreAction() const
330 {
331     return preActionOld_;
332 }
333 
IsGenericAxisEventSequenceCorrect(const AxisEvent & event)334 bool AxisEventChecker::IsGenericAxisEventSequenceCorrect(const AxisEvent& event)
335 {
336     preActionOld_ = preActionNew_;
337     preActionNew_ = event.action;
338 
339     switch (event.action) {
340         case AxisAction::BEGIN:
341             // received begin but have not received end or cancel for pre event
342             return preActionOld_ == AxisAction::NONE;
343         case AxisAction::UPDATE:
344             // received update but have not received
345             return preActionOld_ == AxisAction::BEGIN || preActionOld_ == AxisAction::UPDATE;
346         case AxisAction::END:
347         case AxisAction::CANCEL:
348             // received end or cancel
349             preActionNew_ = AxisAction::NONE;
350             return preActionOld_ == AxisAction::BEGIN || preActionOld_ == AxisAction::UPDATE;
351         default:
352             return false;
353     }
354 }
355 
356 } // namespace OHOS::Ace