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