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/press_recognizer.h"
17
18 namespace OHOS::Ace {
19 namespace {
20
21 constexpr int32_t PRESS_TIMEOUT = 30;
22 constexpr double MAX_THRESHOLD = 2.0;
23
24 } // namespace
25
OnAccepted(size_t touchId)26 void PressRecognizer::OnAccepted(size_t touchId)
27 {
28 LOGD("press gesture has been accepted! the touch id is %{public}zu", touchId);
29 state_ = DetectState::DETECTED;
30 if (onPress_) {
31 PressInfo info(touchId);
32 info.SetTimeStamp(trackPoint_.time);
33 info.SetGlobalLocation(trackPoint_.GetOffset()).SetLocalLocation(trackPoint_.GetOffset() - coordinateOffset_);
34 info.SetTarget(GetEventTarget().value_or(EventTarget()));
35 info.SetForce(trackPoint_.force);
36 if (trackPoint_.tiltX.has_value()) {
37 info.SetTiltX(trackPoint_.tiltX.value());
38 }
39 if (trackPoint_.tiltY.has_value()) {
40 info.SetTiltY(trackPoint_.tiltY.value());
41 }
42 info.SetSourceTool(trackPoint_.sourceTool);
43 onPress_(info);
44 }
45 }
46
OnRejected(size_t touchId)47 void PressRecognizer::OnRejected(size_t touchId)
48 {
49 LOGD("press gesture has been rejected! the touch id is %{public}zu", touchId);
50 deadlineTimer_.Cancel();
51 state_ = DetectState::READY;
52 }
53
HandleTouchDownEvent(const TouchEvent & event)54 void PressRecognizer::HandleTouchDownEvent(const TouchEvent& event)
55 {
56 LOGD("press recognizer receives touch down event, begin to detect press event");
57 if (state_ == DetectState::READY) {
58 auto context = context_.Upgrade();
59 if (!context) {
60 LOGE("fail to detect press gesture due to context is nullptr");
61 return;
62 }
63 trackPoint_ = event;
64 state_ = DetectState::DETECTING;
65 deadlineTimer_.Reset([weakPtr = AceType::WeakClaim(this)] {
66 auto refPtr = weakPtr.Upgrade();
67 if (refPtr) {
68 refPtr->HandleOverdueDeadline();
69 } else {
70 LOGE("fail to handle overdue deadline due to context is nullptr");
71 }
72 });
73 auto taskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
74 taskExecutor.PostDelayedTask(deadlineTimer_, PRESS_TIMEOUT);
75 } else {
76 LOGW("the state is not ready for detecting press gesture");
77 }
78 }
79
HandleTouchUpEvent(const TouchEvent & event)80 void PressRecognizer::HandleTouchUpEvent(const TouchEvent& event)
81 {
82 LOGD("press recognizer receives touch up event");
83 if (state_ == DetectState::DETECTING) {
84 LOGD("this gesture is not press, try to reject it");
85 OnRejected(trackPoint_.id);
86 } else if (state_ == DetectState::DETECTED) {
87 if (onPressCancel_) {
88 onPressCancel_();
89 }
90 }
91 state_ = DetectState::READY;
92 }
93
HandleTouchMoveEvent(const TouchEvent & event)94 void PressRecognizer::HandleTouchMoveEvent(const TouchEvent& event)
95 {
96 LOGD("press recognizer receives touch move event");
97 if (state_ == DetectState::DETECTING) {
98 Offset offset = event.GetOffset() - trackPoint_.GetOffset();
99 if (offset.GetDistance() > MAX_THRESHOLD) {
100 LOGD("this gesture is not press, try to reject it");
101 OnRejected(event.id);
102 }
103 } else if (state_ == DetectState::DETECTED) {
104 Offset offset = event.GetOffset() - trackPoint_.GetOffset();
105 if (offset.GetDistance() > MAX_THRESHOLD && onPressCancel_) {
106 onPressCancel_();
107 }
108 }
109 }
110
HandleTouchCancelEvent(const TouchEvent & event)111 void PressRecognizer::HandleTouchCancelEvent(const TouchEvent& event)
112 {
113 LOGD("press recognizer receives touch cancel event");
114 if (state_ == DetectState::DETECTING) {
115 LOGD("cancel press gesture detect, try to reject it");
116 OnRejected(event.id);
117 }
118 state_ = DetectState::READY;
119 }
120
HandleOverdueDeadline()121 void PressRecognizer::HandleOverdueDeadline()
122 {
123 if (state_ == DetectState::DETECTING) {
124 LOGD("this gesture is press, try to accept it");
125 OnAccepted(trackPoint_.id);
126 } else {
127 LOGW("the state is not detecting for accept press gesture");
128 }
129 }
130
131 } // namespace OHOS::Ace
132