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/raw_recognizer.h"
17 
18 namespace OHOS::Ace {
19 namespace {
20 
21 const char ON_TOUCH_DOWN_EVENT[] = "onTouchDown";
22 const char ON_TOUCH_MOVE_EVENT[] = "onTouchMove";
23 const char ON_TOUCH_UP_EVENT[] = "onTouchUp";
24 const char ON_TOUCH_CANCEL_EVENT[] = "onTouchCancel";
25 
26 } // namespace
27 
HandleRawEvent(const TouchEvent & point,uint32_t stage)28 void RawRecognizer::HandleRawEvent(const TouchEvent& point, uint32_t stage)
29 {
30     switch (point.type) {
31         case TouchType::MOVE: {
32             auto callback = onEventCallbacks_[stage][EventType::TOUCH_MOVE];
33             if (callback) {
34                 callback(CreateTouchEventInfo(ON_TOUCH_MOVE_EVENT, point));
35             }
36             break;
37         }
38         case TouchType::DOWN: {
39             auto callback = onEventCallbacks_[stage][EventType::TOUCH_DOWN];
40             if (callback) {
41                 callback(CreateTouchEventInfo(ON_TOUCH_DOWN_EVENT, point));
42             }
43             break;
44         }
45         case TouchType::UP: {
46             auto callback = onEventCallbacks_[stage][EventType::TOUCH_UP];
47             if (callback) {
48                 lastPoint_ = point;
49                 callback(CreateTouchEventInfo(ON_TOUCH_UP_EVENT, point, true));
50             }
51             break;
52         }
53         case TouchType::CANCEL: {
54             auto callback = onEventCallbacks_[stage][EventType::TOUCH_CANCEL];
55             if (callback) {
56                 lastPoint_ = point;
57                 callback(CreateTouchEventInfo(ON_TOUCH_CANCEL_EVENT, point, true));
58             }
59             break;
60         }
61         default:
62             LOGW("unknown touch type");
63             break;
64     }
65     isFirstTrack_ = point.type == TouchType::DOWN;
66     lastPoint_ = point;
67 }
68 
DispatchEvent(const TouchEvent & point)69 bool RawRecognizer::DispatchEvent(const TouchEvent& point)
70 {
71     HandleRawEvent(point, EventStage::CAPTURE);
72     CatchTouchEventCallback catchCallback;
73     if (point.type == TouchType::DOWN) {
74         catchCallback = catcheventCallbacks_[EventStage::CAPTURE][EventType::TOUCH_DOWN];
75     } else if (point.type == TouchType::MOVE) {
76         catchCallback = catcheventCallbacks_[EventStage::CAPTURE][EventType::TOUCH_MOVE];
77     } else if (point.type == TouchType::UP) {
78         catchCallback = catcheventCallbacks_[EventStage::CAPTURE][EventType::TOUCH_UP];
79     } else if (point.type == TouchType::CANCEL) {
80         catchCallback = catcheventCallbacks_[EventStage::CAPTURE][EventType::TOUCH_CANCEL];
81     }
82 
83     if (catchCallback) {
84         catchCallback();
85         return false;
86     }
87     return true;
88 }
89 
HandleEvent(const TouchEvent & point)90 bool RawRecognizer::HandleEvent(const TouchEvent& point)
91 {
92     HandleRawEvent(point, EventStage::BUBBLE);
93     CatchTouchEventCallback catchCallback;
94     if (point.type == TouchType::DOWN) {
95         catchCallback = catcheventCallbacks_[EventStage::BUBBLE][EventType::TOUCH_DOWN];
96     } else if (point.type == TouchType::MOVE) {
97         catchCallback = catcheventCallbacks_[EventStage::BUBBLE][EventType::TOUCH_MOVE];
98     } else if (point.type == TouchType::UP) {
99         catchCallback = catcheventCallbacks_[EventStage::BUBBLE][EventType::TOUCH_UP];
100     } else if (point.type == TouchType::CANCEL) {
101         catchCallback = catcheventCallbacks_[EventStage::BUBBLE][EventType::TOUCH_CANCEL];
102     }
103 
104     if (catchCallback) {
105         catchCallback();
106         return false;
107     }
108     return true;
109 };
110 
CreateTouchEventInfo(const std::string & type,const TouchEvent & point,bool ignoreCurrent) const111 TouchEventInfo RawRecognizer::CreateTouchEventInfo(
112     const std::string& type, const TouchEvent& point, bool ignoreCurrent) const
113 {
114     auto useNewVersion = true;
115     TouchEventInfo info(type);
116     if (useNewVersion) {
117         TouchLocationInfo changedTouchLocationInfo("onTouch", point.id);
118         changedTouchLocationInfo.SetGlobalLocation(point.GetOffset())
119             .SetLocalLocation(point.GetOffset() - coordinateOffset_)
120             .SetSize(point.size);
121         changedTouchLocationInfo.SetForce(point.force);
122         if (point.tiltX.has_value()) {
123             changedTouchLocationInfo.SetTiltX(point.tiltX.value());
124         }
125         if (point.tiltY.has_value()) {
126             changedTouchLocationInfo.SetTiltY(point.tiltY.value());
127         }
128         changedTouchLocationInfo.SetSourceTool(point.sourceTool);
129         info.AddChangedTouchLocationInfo(std::move(changedTouchLocationInfo));
130         for (auto&& touchPoint : point.pointers) {
131             TouchLocationInfo touchLocationInfo("onTouch", touchPoint.id);
132             auto offset = Offset(touchPoint.x, touchPoint.y);
133             touchLocationInfo.SetGlobalLocation(offset)
134                 .SetLocalLocation(offset - coordinateOffset_)
135                 .SetSize(touchPoint.size);
136             touchLocationInfo.SetForce(touchPoint.force);
137             if (touchPoint.tiltX.has_value()) {
138                 touchLocationInfo.SetTiltX(touchPoint.tiltX.value());
139             }
140             if (touchPoint.tiltY.has_value()) {
141                 touchLocationInfo.SetTiltY(touchPoint.tiltY.value());
142             }
143             touchLocationInfo.SetSourceTool(touchPoint.sourceTool);
144             info.AddTouchLocationInfo(std::move(touchLocationInfo));
145         }
146         info.SetTimeStamp(point.time);
147         info.SetDeviceId(point.deviceId);
148         info.SetForce(point.force);
149         if (point.tiltX.has_value()) {
150             info.SetTiltX(point.tiltX.value());
151         }
152         if (point.tiltY.has_value()) {
153             info.SetTiltY(point.tiltY.value());
154         }
155         info.SetSourceTool(point.sourceTool);
156         info.SetTarget(GetEventTarget().value_or(EventTarget()));
157         return info;
158     }
159     if (!isFirstTrack_) {
160         TouchLocationInfo lastTouchLocationInfo("onTouch", lastPoint_.id);
161         lastTouchLocationInfo.SetGlobalLocation(lastPoint_.GetOffset())
162             .SetLocalLocation(lastPoint_.GetOffset() - coordinateOffset_)
163             .SetSize(lastPoint_.size);
164         lastTouchLocationInfo.SetForce(lastPoint_.force);
165         if (lastPoint_.tiltX.has_value()) {
166             lastTouchLocationInfo.SetTiltX(lastPoint_.tiltX.value());
167         }
168         if (lastPoint_.tiltY.has_value()) {
169             lastTouchLocationInfo.SetTiltY(lastPoint_.tiltY.value());
170         }
171         lastTouchLocationInfo.SetSourceTool(lastPoint_.sourceTool);
172         info.AddChangedTouchLocationInfo(std::move(lastTouchLocationInfo));
173         info.SetDeviceId(lastPoint_.deviceId);
174         info.SetForce(point.force);
175         if (point.tiltX.has_value()) {
176             info.SetTiltX(point.tiltX.value());
177         }
178         if (point.tiltY.has_value()) {
179             info.SetTiltY(point.tiltY.value());
180         }
181         info.SetSourceTool(point.sourceTool);
182         if (ignoreCurrent) {
183             info.SetTimeStamp(lastPoint_.time);
184             return info;
185         }
186     }
187     info.SetTimeStamp(point.time);
188     info.SetDeviceId(point.deviceId);
189     info.SetForce(point.force);
190     if (point.tiltX.has_value()) {
191         info.SetTiltX(point.tiltX.value());
192     }
193     if (point.tiltY.has_value()) {
194         info.SetTiltY(point.tiltY.value());
195     }
196     info.SetSourceTool(point.sourceTool);
197     info.SetPressedKeyCodes(point.pressedKeyCodes_);
198     TouchLocationInfo currentTouchLocationInfo("onTouch", point.id);
199     currentTouchLocationInfo.SetGlobalLocation(point.GetOffset())
200         .SetLocalLocation(point.GetOffset() - coordinateOffset_)
201         .SetSize(point.size);
202     currentTouchLocationInfo.SetForce(point.force);
203     if (point.tiltX.has_value()) {
204         currentTouchLocationInfo.SetTiltX(point.tiltX.value());
205     }
206     if (point.tiltY.has_value()) {
207         currentTouchLocationInfo.SetTiltY(point.tiltY.value());
208     }
209     currentTouchLocationInfo.SetSourceTool(point.sourceTool);
210     info.AddTouchLocationInfo(std::move(currentTouchLocationInfo));
211     info.SetTarget(GetEventTarget().value_or(EventTarget()));
212     return info;
213 }
214 
215 } // namespace OHOS::Ace