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