1 /*
2 * Copyright (c) 2024 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/components_ng/pattern/text/multiple_click_recognizer.h"
17
18 #include "base/utils/utils.h"
19 #include "core/pipeline_ng/pipeline_context.h"
20
21 namespace OHOS::Ace::NG {
22 namespace {
23 constexpr uint32_t SECONDS_TO_MILLISECONDS = 1000;
24 constexpr int32_t SINGLE_CLICK_TIME = 1;
25 constexpr int32_t DOUBLE_CLICK_TIME = 2;
26 constexpr int32_t TRIPLE_CLICK_TIME = 3;
27 }
Start(const GestureEvent & event)28 void MultipleClickRecognizer::Start(const GestureEvent& event)
29 {
30 if (clickCountTask_ && IsValidClick(event)) {
31 clickTimes_++;
32 } else {
33 clickTimes_ = SINGLE_CLICK_TIME;
34 beginGlobalLocation_ = event.GetGlobalLocation();
35 beginLocalLocation_ = event.GetLocalLocation();
36 }
37 lastClickTimeStamp_ = event.GetTimeStamp();
38 lastClickPosition_ = event.GetGlobalLocation();
39 auto context = PipelineContext::GetCurrentContextSafely();
40 if (!context || !context->GetTaskExecutor()) {
41 Stop();
42 return;
43 }
44 auto taskExecutor = context->GetTaskExecutor();
45 auto weak = WeakClaim(this);
46 clickCountTask_.Reset([weak] {
47 auto recognizer = weak.Upgrade();
48 CHECK_NULL_VOID(recognizer);
49 recognizer->Stop();
50 });
51 taskExecutor->PostDelayedTask(
52 clickCountTask_, TaskExecutor::TaskType::UI, maxIntervalTime_, "MultipleClickRecognizerCountTask");
53 }
54
IsValidClick(const GestureEvent & event) const55 bool MultipleClickRecognizer::IsValidClick(const GestureEvent& event) const
56 {
57 TimeStamp clickTimeStamp = event.GetTimeStamp();
58 std::chrono::duration<float, std::ratio<1, SECONDS_TO_MILLISECONDS>> timeout = clickTimeStamp - lastClickTimeStamp_;
59 Offset location = event.GetGlobalLocation();
60 auto deltaOffset = location - lastClickPosition_;
61 auto deltaDistance = deltaOffset.GetDistance();
62 if (GreatOrEqual(timeout.count(), minIntervalTime_) && LessNotEqual(timeout.count(), maxIntervalTime_) &&
63 LessNotEqual(deltaDistance, maxDeltaDistance_.ConvertToPx())) {
64 return true;
65 }
66 return false;
67 }
68
IsSingleClick() const69 bool MultipleClickRecognizer::IsSingleClick() const
70 {
71 return GetClickTimes() == SINGLE_CLICK_TIME;
72 }
73
IsDoubleClick() const74 bool MultipleClickRecognizer::IsDoubleClick() const
75 {
76 return GetClickTimes() == DOUBLE_CLICK_TIME;
77 }
78
IsTripleClick() const79 bool MultipleClickRecognizer::IsTripleClick() const
80 {
81 return GetClickTimes() == TRIPLE_CLICK_TIME;
82 }
83 } // namespace OHOS::Ace::NG