1 /*
2 * Copyright (c) 2021-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 #include "core/gestures/swipe_recognizer.h"
17
18 namespace OHOS::Ace {
19 namespace {
20
GetSwipeDirection(const TouchEvent & firstPoint,const TouchEvent & lastPoint)21 SwipeEventInfo::SwipeDirection GetSwipeDirection(const TouchEvent& firstPoint, const TouchEvent& lastPoint)
22 {
23 static const double duration = 15.0;
24 auto xOffset = lastPoint.x - firstPoint.x;
25 auto yOffset = lastPoint.y - firstPoint.y;
26 if (std::abs(xOffset) > std::abs(yOffset)) {
27 if (std::abs(xOffset) < duration) {
28 return SwipeEventInfo::SwipeDirection::NONE;
29 }
30 return xOffset > 0.0 ? SwipeEventInfo::SwipeDirection::RIGHT : SwipeEventInfo::SwipeDirection::LEFT;
31 } else {
32 if (std::abs(yOffset) < duration) {
33 return SwipeEventInfo::SwipeDirection::NONE;
34 }
35 return yOffset > 0.0 ? SwipeEventInfo::SwipeDirection::DOWN : SwipeEventInfo::SwipeDirection::UP;
36 }
37 }
38
GetSwipeDistance(SwipeEventInfo::SwipeDirection direction,const TouchEvent & firstPoint,const TouchEvent & lastPoint)39 float GetSwipeDistance(
40 SwipeEventInfo::SwipeDirection direction, const TouchEvent& firstPoint, const TouchEvent& lastPoint)
41 {
42 if (direction == SwipeEventInfo::SwipeDirection::RIGHT) {
43 return (lastPoint.x - firstPoint.x);
44 } else if (direction == SwipeEventInfo::SwipeDirection::LEFT) {
45 return (firstPoint.x - lastPoint.x);
46 } else if (direction == SwipeEventInfo::SwipeDirection::UP) {
47 return (firstPoint.y - lastPoint.y);
48 } else if (direction == SwipeEventInfo::SwipeDirection::DOWN) {
49 return (lastPoint.y - firstPoint.y);
50 } else {
51 return 0;
52 }
53 }
54
55 } // namespace
56
ToJsonParamInfo() const57 std::string SwipeEventInfo::ToJsonParamInfo() const
58 {
59 static std::unordered_map<SwipeEventInfo::SwipeDirection, std::string> conventMap {
60 { SwipeEventInfo::SwipeDirection::RIGHT, "right" },
61 { SwipeEventInfo::SwipeDirection::LEFT, "left" },
62 { SwipeEventInfo::SwipeDirection::UP, "up" },
63 { SwipeEventInfo::SwipeDirection::DOWN, "down" },
64 };
65 auto jsonValue = JsonUtil::Create(true);
66 jsonValue->Put("type", GetType().c_str());
67 jsonValue->Put("timestamp", static_cast<double>(GetTimeStamp().time_since_epoch().count()));
68 jsonValue->Put("direction", conventMap[swipeDirection_].c_str());
69 jsonValue->Put("distance", distance_);
70 return jsonValue->ToString();
71 }
72
HandleSwipeEvent(const TouchEvent & point,uint32_t stage)73 bool SwipeRecognizer::HandleSwipeEvent(const TouchEvent& point, uint32_t stage)
74 {
75 switch (point.type) {
76 case TouchType::DOWN: {
77 // reset the recognizer status.
78 auto& status = statusMap_[point.id];
79 status.first = point;
80 status.second = false;
81 break;
82 }
83 case TouchType::UP: {
84 auto callback = swipeCallback_[stage];
85 auto callbackCatch = swipeCatchCallback_[stage];
86 auto& status = statusMap_[point.id];
87
88 if (status.second && callbackCatch) {
89 auto direction = GetSwipeDirection(status.first, point);
90 if (direction == SwipeEventInfo::SwipeDirection::NONE) {
91 return true;
92 }
93 callbackCatch(SwipeEventInfo(direction, GetSwipeDistance(direction, status.first, point)));
94 return false;
95 }
96
97 if (status.second && callback) {
98 auto direction = GetSwipeDirection(status.first, point);
99 if (direction == SwipeEventInfo::SwipeDirection::NONE) {
100 return true;
101 }
102 callback(SwipeEventInfo(direction, GetSwipeDistance(direction, status.first, point)));
103 }
104 break;
105 }
106 case TouchType::MOVE: {
107 auto& status = statusMap_[point.id];
108 status.second = true;
109 break;
110 }
111 case TouchType::CANCEL: {
112 auto& status = statusMap_[point.id];
113 status.second = false;
114 break;
115 }
116 default:
117 LOGW("unknown type point type.");
118 }
119 return true;
120 }
121
HandleEvent(const TouchEvent & point)122 bool SwipeRecognizer::HandleEvent(const TouchEvent& point)
123 {
124 return HandleSwipeEvent(point, EventStage::BUBBLE);
125 }
126
DispatchEvent(const TouchEvent & point)127 bool SwipeRecognizer::DispatchEvent(const TouchEvent& point)
128 {
129 HandleSwipeEvent(point, EventStage::CAPTURE);
130
131 auto& status = statusMap_[point.id];
132 if (status.second) {
133 auto direction = GetSwipeDirection(status.first, point);
134 if (direction == SwipeEventInfo::SwipeDirection::NONE) {
135 return true;
136 }
137 auto catchCallback = swipeCatchCallback_[EventStage::CAPTURE];
138 if (catchCallback) {
139 catchCallback(SwipeEventInfo(direction, GetSwipeDistance(direction, status.first, point)));
140 return false;
141 }
142 }
143 return true;
144 }
145
146 } // namespace OHOS::Ace
147