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