• 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, globalDisplayX, globalDisplayY, verticalAxis, horizontalAxis,
26             pinchAxisScale, rotateAxisAngle, isRotationEvent, action, time, deviceId, sourceType, sourceTool,
27             pointerEvent, pressedCodes, targetDisplayId, originalId, isInjected, scrollStep };
28     }
29     return { id, x / scale, y / scale, screenX / scale, screenY / scale, globalDisplayX / scale, globalDisplayY / scale,
30         verticalAxis, horizontalAxis, pinchAxisScale, rotateAxisAngle, isRotationEvent, action, time, deviceId,
31         sourceType, sourceTool, pointerEvent, pressedCodes, 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 
GetGlobalDisplayOffset() const44 Offset AxisEvent::GetGlobalDisplayOffset() const
45 {
46     return Offset(globalDisplayX, globalDisplayY);
47 }
48 
GetDirection() const49 AxisDirection AxisEvent::GetDirection() const
50 {
51     uint32_t verticalFlag = 0;
52     uint32_t horizontalFlag = 0;
53     if (LessNotEqual(verticalAxis, 0.0)) {
54         verticalFlag = static_cast<uint32_t>(AxisDirection::UP);
55     } else if (GreatNotEqual(verticalAxis, 0.0)) {
56         verticalFlag = static_cast<uint32_t>(AxisDirection::DOWN);
57     }
58     if (LessNotEqual(horizontalAxis, 0.0)) {
59         horizontalFlag = static_cast<uint32_t>(AxisDirection::LEFT);
60     } else if (GreatNotEqual(horizontalAxis, 0.0)) {
61         horizontalFlag = static_cast<uint32_t>(AxisDirection::RIGHT);
62     }
63     return static_cast<AxisDirection>(verticalFlag | horizontalFlag);
64 }
IsDirectionUp(AxisDirection direction)65 bool AxisEvent::IsDirectionUp(AxisDirection direction)
66 {
67     return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::UP));
68 }
IsDirectionDown(AxisDirection direction)69 bool AxisEvent::IsDirectionDown(AxisDirection direction)
70 {
71     return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::DOWN));
72 }
IsDirectionLeft(AxisDirection direction)73 bool AxisEvent::IsDirectionLeft(AxisDirection direction)
74 {
75     return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::LEFT));
76 }
IsDirectionRight(AxisDirection direction)77 bool AxisEvent::IsDirectionRight(AxisDirection direction)
78 {
79     return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::RIGHT));
80 }
81 
ConvertToOffset(bool isShiftKeyPressed,bool hasDifferentDirectionGesture) const82 Offset AxisEvent::ConvertToOffset(bool isShiftKeyPressed, bool hasDifferentDirectionGesture) const
83 {
84     Offset result;
85     if (sourceTool == SourceTool::MOUSE) {
86         // Axis event is made by mouse.
87         if (isShiftKeyPressed) {
88             result = Offset(-verticalAxis, -horizontalAxis);
89         } else {
90             if (hasDifferentDirectionGesture) {
91                 result = Offset(-horizontalAxis, -verticalAxis);
92             } else {
93                 result = Offset(-verticalAxis, -verticalAxis);
94             }
95         }
96         return result * (LINE_HEIGHT_DESKTOP / MOUSE_WHEEL_DEGREES).ConvertToPx();
97     }
98     // Axis event is made by others. Include touch-pad.
99     result = Offset(-horizontalAxis, -verticalAxis);
100     return result;
101 }
102 
103 // MMI has the different direction, need to check truth direction.
ConvertToSummationAxisValue(const AxisEvent & event) const104 std::pair<float, float> AxisEvent::ConvertToSummationAxisValue(const AxisEvent& event) const
105 {
106     return std::make_pair(event.horizontalAxis - horizontalAxis, event.verticalAxis - verticalAxis);
107 }
108 
HasKey(KeyCode expectCode) const109 bool AxisEvent::HasKey(KeyCode expectCode) const
110 {
111     auto curPressedCode = pressedCodes.rbegin();
112     while (curPressedCode != pressedCodes.rend()) {
113         if (expectCode == *curPressedCode) {
114             return true;
115         }
116         ++curPressedCode;
117     }
118     return false;
119 }
120 
GetTargetDisplayId() const121 int32_t AxisEvent::GetTargetDisplayId() const
122 {
123     return targetDisplayId;
124 }
125 
AxisInfo(const AxisEvent & event,const Offset & localLocation,const EventTarget & target)126 AxisInfo::AxisInfo(const AxisEvent& event, const Offset& localLocation, const EventTarget& target)
127     : BaseEventInfo("onAxis")
128 {
129     action_ = event.action;
130     scrollStep_ = event.scrollStep;
131     verticalAxis_ = static_cast<float>(event.verticalAxis);
132     horizontalAxis_ = static_cast<float>(event.horizontalAxis);
133     pinchAxisScale_ = static_cast<float>(event.pinchAxisScale);
134     rotateAxisAngle_ = static_cast<float>(event.rotateAxisAngle);
135     isRotationEvent_ = event.isRotationEvent;
136     globalLocation_ = event.GetOffset();
137     localLocation_ = localLocation;
138     screenLocation_ = Offset();
139     SetPressedKeyCodes(event.pressedCodes);
140     SetTimeStamp(event.time);
141     SetDeviceId(event.deviceId);
142     SetSourceDevice(event.sourceType);
143     SetTarget(target);
144     SetTargetDisplayId(event.targetDisplayId);
145 }
146 
SetAction(AxisAction action)147 void AxisInfo::SetAction(AxisAction action)
148 {
149     action_ = action;
150 }
151 
GetAction() const152 AxisAction AxisInfo::GetAction() const
153 {
154     return action_;
155 }
156 
GetScrollStep() const157 int32_t AxisInfo::GetScrollStep() const
158 {
159     return scrollStep_;
160 }
161 
SetPinchAxisScale(float scale)162 void AxisInfo::SetPinchAxisScale(float scale)
163 {
164     pinchAxisScale_ = scale;
165 }
166 
GetPinchAxisScale() const167 float AxisInfo::GetPinchAxisScale() const
168 {
169     return pinchAxisScale_;
170 }
171 
SetRotateAxisAngle(float angle)172 void AxisInfo::SetRotateAxisAngle(float angle)
173 {
174     rotateAxisAngle_ = angle;
175 }
176 
GetRotateAxisAngle() const177 float AxisInfo::GetRotateAxisAngle() const
178 {
179     return rotateAxisAngle_;
180 }
181 
SetIsRotationEvent(bool rotationFlag)182 void AxisInfo::SetIsRotationEvent(bool rotationFlag)
183 {
184     isRotationEvent_ = rotationFlag;
185 }
186 
GetIsRotationEvent() const187 bool AxisInfo::GetIsRotationEvent() const
188 {
189     return isRotationEvent_;
190 }
191 
SetGlobalLocation(const Offset & globalLocation)192 AxisInfo& AxisInfo::SetGlobalLocation(const Offset& globalLocation)
193 {
194     globalLocation_ = globalLocation;
195     return *this;
196 }
SetLocalLocation(const Offset & localLocation)197 AxisInfo& AxisInfo::SetLocalLocation(const Offset& localLocation)
198 {
199     localLocation_ = localLocation;
200     return *this;
201 }
202 
SetScreenLocation(const Offset & screenLocation)203 AxisInfo& AxisInfo::SetScreenLocation(const Offset& screenLocation)
204 {
205     screenLocation_ = screenLocation;
206     return *this;
207 }
208 
GetScreenLocation() const209 const Offset& AxisInfo::GetScreenLocation() const
210 {
211     return screenLocation_;
212 }
213 
GetLocalLocation() const214 const Offset& AxisInfo::GetLocalLocation() const
215 {
216     return localLocation_;
217 }
GetGlobalLocation() const218 const Offset& AxisInfo::GetGlobalLocation() const
219 {
220     return globalLocation_;
221 }
222 
SetGlobalDisplayLocation(const Offset & globalDisplayLocation)223 AxisInfo& AxisInfo::SetGlobalDisplayLocation(const Offset& globalDisplayLocation)
224 {
225     globalDisplayLocation_ = globalDisplayLocation;
226     return *this;
227 }
GetGlobalDisplayLocation() const228 const Offset& AxisInfo::GetGlobalDisplayLocation() const
229 {
230     return globalDisplayLocation_;
231 }
232 
ConvertToAxisEvent() const233 AxisEvent AxisInfo::ConvertToAxisEvent() const
234 {
235     AxisEvent axisEvent;
236     axisEvent.x = static_cast<float>(globalLocation_.GetX());
237     axisEvent.y = static_cast<float>(globalLocation_.GetY());
238     axisEvent.screenX = static_cast<float>(screenLocation_.GetX());
239     axisEvent.screenY = static_cast<float>(screenLocation_.GetY());
240     axisEvent.globalDisplayX = static_cast<float>(globalDisplayLocation_.GetX());
241     axisEvent.globalDisplayY = static_cast<float>(globalDisplayLocation_.GetY());
242     axisEvent.scrollStep = scrollStep_;
243     axisEvent.horizontalAxis = horizontalAxis_;
244     axisEvent.verticalAxis = verticalAxis_;
245     axisEvent.pinchAxisScale = pinchAxisScale_;
246     axisEvent.action = action_;
247     axisEvent.rotateAxisAngle = rotateAxisAngle_;
248     axisEvent.time = timeStamp_;
249     axisEvent.localX = static_cast<float>(localLocation_.GetX());
250     axisEvent.localY = static_cast<float>(localLocation_.GetY());
251     axisEvent.sourceType = deviceType_;
252     axisEvent.sourceTool = sourceTool_;
253     const auto& targetLocalOffset = GetTarget().area.GetOffset();
254     const auto& targetOrigin = GetTarget().origin;
255     // width height x y globalx globaly
256     axisEvent.targetPositionX = targetLocalOffset.GetX().ConvertToPx();
257     axisEvent.targetPositionY = targetLocalOffset.GetY().ConvertToPx();
258     axisEvent.targetGlobalPositionX = targetOrigin.GetX().ConvertToPx() + targetLocalOffset.GetX().ConvertToPx();
259     axisEvent.targetGlobalPositionY = targetOrigin.GetY().ConvertToPx() + targetLocalOffset.GetY().ConvertToPx();
260     axisEvent.width = GetTarget().area.GetWidth().ConvertToPx();
261     axisEvent.height = GetTarget().area.GetHeight().ConvertToPx();
262     // deviceid
263     axisEvent.deviceId = GetDeviceId();
264     // modifierkeystates
265     axisEvent.modifierKeyState = CalculateModifierKeyState(GetPressedKeyCodes());
266     axisEvent.targetDisplayId = GetTargetDisplayId();
267     return axisEvent;
268 }
269 
SetOnAxisCallback(const OnAxisEventFunc & onAxisCallback)270 void AxisEventTarget::SetOnAxisCallback(const OnAxisEventFunc& onAxisCallback)
271 {
272     onAxisCallback_ = onAxisCallback;
273 }
274 
SetCoordinateOffset(const NG::OffsetF & coordinateOffset)275 void AxisEventTarget::SetCoordinateOffset(const NG::OffsetF& coordinateOffset)
276 {
277     coordinateOffset_ = coordinateOffset;
278 }
279 
SetGetEventTargetImpl(const GetEventTargetImpl & getEventTargetImpl)280 void AxisEventTarget::SetGetEventTargetImpl(const GetEventTargetImpl& getEventTargetImpl)
281 {
282     getEventTargetImpl_ = getEventTargetImpl;
283 }
284 
GetEventTarget() const285 std::optional<EventTarget> AxisEventTarget::GetEventTarget() const
286 {
287     if (getEventTargetImpl_) {
288         return getEventTargetImpl_();
289     }
290     return std::nullopt;
291 }
292 
SetFrameName(const std::string & frameName)293 void AxisEventTarget::SetFrameName(const std::string& frameName)
294 {
295     frameName_ = frameName;
296 }
297 
GetFrameName() const298 std::string AxisEventTarget::GetFrameName() const
299 {
300     return frameName_;
301 }
302 
HandleAxisEvent(const AxisEvent & event)303 bool AxisEventTarget::HandleAxisEvent(const AxisEvent& event)
304 {
305     if (!onAxisCallback_) {
306         return false;
307     }
308     Offset localLocation = Offset(
309         event.GetOffset().GetX() - coordinateOffset_.GetX(), event.GetOffset().GetY() - coordinateOffset_.GetY());
310     AxisInfo info = AxisInfo(event, localLocation, GetEventTarget().value_or(EventTarget()));
311     info.SetScreenLocation(Offset(event.screenX, event.screenY));
312     info.SetGlobalDisplayLocation(Offset(event.globalDisplayX, event.globalDisplayY));
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