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