• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "gesture_handler.h"
17 
18 #include "mmi_log.h"
19 
20 #undef MMI_LOG_DOMAIN
21 #define MMI_LOG_DOMAIN MMI_LOG_HANDLER
22 #undef MMI_LOG_TAG
23 #define MMI_LOG_TAG "GestureHandler"
24 
25 namespace OHOS {
26 namespace MMI {
27 namespace {
28 constexpr int32_t FIRST_FINGER { 0 };
29 constexpr int32_t SECOND_FINGER { 1 };
30 constexpr int32_t TWO_FINGERS { 2 };
31 constexpr double EFFECT_ANGLE { 5.0 };
32 constexpr double FLAT_ANGLE { 180.0 };
33 } // namespace
34 
GestureHandler()35 GestureHandler::GestureHandler() {}
36 
~GestureHandler()37 GestureHandler::~GestureHandler() {}
38 
InitRotateGesture()39 void GestureHandler::InitRotateGesture()
40 {
41     isReady_ = false;
42     isStartRotate_ = false;
43     fingerDownPosition_.clear();
44     fingerCurrentPosition_.clear();
45     initialAngle_ = 0.0;
46     lastAngle_ = 0.0;
47     rotateAngle_ = 0.0;
48     numberOfTouchPadFingerDown_ = -1;
49 }
50 
GestureIdentify(int32_t originType,int32_t seatSlot,double logicalX,double logicalY)51 int32_t GestureHandler::GestureIdentify(int32_t originType, int32_t seatSlot, double logicalX, double logicalY)
52 {
53     int32_t gestureType = PointerEvent::POINTER_ACTION_UNKNOWN;
54     switch (originType) {
55         case LIBINPUT_EVENT_TOUCHPAD_DOWN: {
56             numberOfTouchPadFingerDown_++;
57             gestureType = HandleTouchPadDownEvent(seatSlot, logicalX, logicalY);
58             break;
59         }
60         case LIBINPUT_EVENT_TOUCHPAD_MOTION: {
61             gestureType = HandleTouchPadMoveEvent(seatSlot, logicalX, logicalY);
62             break;
63         }
64         case LIBINPUT_EVENT_TOUCHPAD_UP: {
65             gestureType = HandleTouchPadUpEvent(seatSlot);
66             break;
67         }
68         default: {
69             MMI_HILOGE("originType is invalid");
70             break;
71         }
72     }
73 
74     return gestureType;
75 }
76 
HandleTouchPadDownEvent(int32_t seatSlot,double logicalX,double logicalY)77 int32_t GestureHandler::HandleTouchPadDownEvent(int32_t seatSlot, double logicalX, double logicalY)
78 {
79     if (seatSlot < FIRST_FINGER || seatSlot > SECOND_FINGER) {
80         if (isStartRotate_) {
81             MMI_HILOGI("Exceed two fingers, rotate is end");
82             return PointerEvent::POINTER_ACTION_ROTATE_END;
83         }
84         if (isReady_) {
85             InitRotateGesture();
86         }
87         MMI_HILOGD("seatSlot is invalid");
88         return PointerEvent::POINTER_ACTION_UNKNOWN;
89     }
90 
91     struct Position position;
92     position.x = logicalX;
93     position.y = logicalY;
94     fingerDownPosition_[seatSlot] = position;
95     if (fingerDownPosition_.size() == TWO_FINGERS) {
96         isReady_ = true;
97         initialAngle_ = CalculateAngle(fingerDownPosition_);
98         fingerCurrentPosition_ = fingerDownPosition_;
99     }
100     return PointerEvent::POINTER_ACTION_UNKNOWN;
101 }
102 
HandleTouchPadMoveEvent(int32_t seatSlot,double logicalX,double logicalY)103 int32_t GestureHandler::HandleTouchPadMoveEvent(int32_t seatSlot, double logicalX, double logicalY)
104 {
105     if (!isReady_) {
106         MMI_HILOGD("Gesture event is not identified");
107         return PointerEvent::POINTER_ACTION_UNKNOWN;
108     }
109     if (numberOfTouchPadFingerDown_ < FIRST_FINGER || numberOfTouchPadFingerDown_ > SECOND_FINGER) {
110         if (isStartRotate_) {
111             MMI_HILOGD("Exceed two fingers, rotate is end");
112             return PointerEvent::POINTER_ACTION_UNKNOWN;
113         }
114         if (isReady_) {
115             InitRotateGesture();
116         }
117         MMI_HILOGD("seatSlot is invalid");
118         return PointerEvent::POINTER_ACTION_UNKNOWN;
119     }
120 
121     struct Position position;
122     position.x = logicalX;
123     position.y = logicalY;
124     fingerCurrentPosition_[seatSlot] = position;
125     double currentAngle = CalculateAngle(fingerCurrentPosition_);
126     if (!isStartRotate_ && fabs(currentAngle - initialAngle_) >= EFFECT_ANGLE) {
127         initialAngle_ = currentAngle;
128         lastAngle_ = currentAngle;
129         isStartRotate_ = true;
130         MMI_HILOGI("Begin to rotate");
131         return PointerEvent::POINTER_ACTION_ROTATE_BEGIN;
132     }
133 
134     if (isStartRotate_) {
135         rotateAngle_ += AdjustRotateAngle(currentAngle);
136         lastAngle_ = currentAngle;
137         return PointerEvent::POINTER_ACTION_ROTATE_UPDATE;
138     }
139     return PointerEvent::POINTER_ACTION_UNKNOWN;
140 }
141 
HandleTouchPadUpEvent(int32_t seatSlot)142 int32_t GestureHandler::HandleTouchPadUpEvent(int32_t seatSlot)
143 {
144     if (isStartRotate_) {
145         isReady_ = false;
146         isStartRotate_ = false;
147         fingerDownPosition_.erase(seatSlot);
148         fingerCurrentPosition_.erase(seatSlot);
149         MMI_HILOGI("Rotate is end");
150         return PointerEvent::POINTER_ACTION_ROTATE_END;
151     }
152     InitRotateGesture();
153     return PointerEvent::POINTER_ACTION_UNKNOWN;
154 }
155 
CalculateAngle(std::map<int32_t,struct Position> fingerPosition)156 double GestureHandler::CalculateAngle(std::map<int32_t, struct Position> fingerPosition)
157 {
158     double firstX = fingerPosition[FIRST_FINGER].x;
159     double firstY = fingerPosition[FIRST_FINGER].y;
160     double secondX = fingerPosition[SECOND_FINGER].x;
161     double secondY = fingerPosition[SECOND_FINGER].y;
162     double angle = atan2(firstY - secondY, firstX - secondX) * 180.0 / M_PI;
163     return angle;
164 }
165 
AdjustRotateAngle(double currentAngle)166 double GestureHandler::AdjustRotateAngle(double currentAngle)
167 {
168     double angleIncrement = 0;
169     if (currentAngle - lastAngle_ >= FLAT_ANGLE) {
170         angleIncrement = (currentAngle - FLAT_ANGLE) - (lastAngle_ + FLAT_ANGLE);
171     } else if (lastAngle_ - currentAngle >= FLAT_ANGLE) {
172         angleIncrement = (currentAngle + FLAT_ANGLE) + (FLAT_ANGLE - lastAngle_);
173     } else {
174         angleIncrement = currentAngle - lastAngle_;
175     }
176     return angleIncrement;
177 }
178 
GetRotateAngle()179 double GestureHandler::GetRotateAngle()
180 {
181     return rotateAngle_;
182 }
183 
GetRotateStatus()184 bool GestureHandler::GetRotateStatus()
185 {
186     return isStartRotate_;
187 }
188 } // namespace MMI
189 } // namespace OHOS