2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/events/tap-gesture/tap-gesture-detector-impl.h>
22 #include <cstring> // for strcmp
25 #include <dali/integration-api/debug.h>
26 #include <dali/integration-api/platform-abstraction.h>
27 #include <dali/internal/event/common/thread-local-storage.h>
28 #include <dali/internal/event/events/gesture-event-processor.h>
29 #include <dali/internal/event/events/tap-gesture/tap-gesture-impl.h>
30 #include <dali/public-api/events/tap-gesture.h>
31 #include <dali/public-api/object/type-registry.h>
39 constexpr uint32_t DEFAULT_TAPS_REQUIRED = 1u;
40 constexpr uint32_t DEFAULT_TOUCHES_REQUIRED = 1u;
41 constexpr uint32_t DEFAULT_TAP_WAIT_TIME = 330u;
44 const char* const SIGNAL_TAP_DETECTED = "tapDetected";
48 return Dali::TapGestureDetector::New();
51 TypeRegistration mType(typeid(Dali::TapGestureDetector), typeid(Dali::GestureDetector), Create);
53 SignalConnectorType signalConnector1(mType, SIGNAL_TAP_DETECTED, &TapGestureDetector::DoConnectSignal);
57 TapGestureDetectorPtr TapGestureDetector::New()
59 return new TapGestureDetector;
62 TapGestureDetectorPtr TapGestureDetector::New(unsigned int tapsRequired)
64 return new TapGestureDetector(tapsRequired);
67 TapGestureDetector::TapGestureDetector()
68 : GestureDetector(GestureType::TAP),
69 mMinimumTapsRequired(DEFAULT_TAPS_REQUIRED),
70 mMaximumTapsRequired(DEFAULT_TAPS_REQUIRED),
71 mTouchesRequired(DEFAULT_TOUCHES_REQUIRED),
75 mReceiveAllTapEvents(false)
79 TapGestureDetector::TapGestureDetector(unsigned int tapsRequired)
80 : GestureDetector(GestureType::TAP),
81 mMinimumTapsRequired(tapsRequired),
82 mMaximumTapsRequired(tapsRequired),
83 mTouchesRequired(DEFAULT_TOUCHES_REQUIRED),
87 mReceiveAllTapEvents(false)
91 TapGestureDetector::~TapGestureDetector()
93 if(mTimerId != 0 && ThreadLocalStorage::Created())
95 Dali::Integration::PlatformAbstraction& platformAbstraction = ThreadLocalStorage::Get().GetPlatformAbstraction();
96 platformAbstraction.CancelTimer(mTimerId);
100 void TapGestureDetector::SetMinimumTapsRequired(unsigned int taps)
102 if(mMinimumTapsRequired != taps)
104 mMinimumTapsRequired = taps;
106 if(!mAttachedActors.empty())
108 mGestureEventProcessor.GestureDetectorUpdated(this);
113 void TapGestureDetector::SetMaximumTapsRequired(unsigned int taps)
115 if(mMaximumTapsRequired != taps)
117 mMaximumTapsRequired = taps;
119 if(!mAttachedActors.empty())
121 mGestureEventProcessor.GestureDetectorUpdated(this);
126 void TapGestureDetector::SetTouchesRequired(unsigned int touches)
128 if(mTouchesRequired != touches)
130 mTouchesRequired = touches;
132 if(!mAttachedActors.empty())
134 mGestureEventProcessor.GestureDetectorUpdated(this);
139 unsigned int TapGestureDetector::GetMinimumTapsRequired() const
141 return mMinimumTapsRequired;
144 unsigned int TapGestureDetector::GetMaximumTapsRequired() const
146 return mMaximumTapsRequired;
149 unsigned int TapGestureDetector::GetTouchesRequired() const
151 return mTouchesRequired;
154 void TapGestureDetector::ReceiveAllTapEvents(bool receive)
156 mReceiveAllTapEvents = receive;
159 void TapGestureDetector::EmitTapGestureSignal(Dali::Actor tappedActor, const Dali::TapGesture& tap)
161 Dali::Integration::PlatformAbstraction& platformAbstraction = ThreadLocalStorage::Get().GetPlatformAbstraction();
164 platformAbstraction.CancelTimer(mTimerId);
168 if(mMaximumTapsRequired == 0u)
173 uint32_t numberOfTaps = tap.GetNumberOfTaps() % mMaximumTapsRequired;
174 Internal::TapGesturePtr internalTap(new Internal::TapGesture(tap.GetState()));
175 internalTap->SetTime(tap.GetTime());
176 internalTap->SetNumberOfTouches(tap.GetNumberOfTouches());
177 internalTap->SetScreenPoint(tap.GetScreenPoint());
178 internalTap->SetLocalPoint(tap.GetLocalPoint());
179 internalTap->SetSourceType(tap.GetSourceType());
180 internalTap->SetSourceData(tap.GetSourceData());
181 internalTap->SetNumberOfTaps(numberOfTaps == 0u ? mMaximumTapsRequired : numberOfTaps);
182 mTap = Dali::TapGesture(internalTap.Get());
183 if(numberOfTaps == 0u || mReceiveAllTapEvents)
185 // Guard against destruction during signal emission
186 Dali::TapGestureDetector handle(this);
188 mDetectedSignal.Emit(tappedActor, mTap);
192 mTappedActor = tappedActor;
193 mTimerId = platformAbstraction.StartTimer(DEFAULT_TAP_WAIT_TIME, MakeCallback(this, &TapGestureDetector::TimerCallback));
197 bool TapGestureDetector::TimerCallback()
199 // Guard against destruction during signal emission
200 Dali::TapGestureDetector handle(this);
202 mDetectedSignal.Emit(mTappedActor, mTap);
208 bool TapGestureDetector::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
210 bool connected(true);
211 TapGestureDetector* gesture = static_cast<TapGestureDetector*>(object); // TypeRegistry guarantees that this is the correct type.
213 if(0 == strcmp(signalName.c_str(), SIGNAL_TAP_DETECTED))
215 gesture->DetectedSignal().Connect(tracker, functor);
219 // signalName does not match any signal
226 void TapGestureDetector::OnActorAttach(Actor& actor)
231 void TapGestureDetector::OnActorDetach(Actor& actor)
236 void TapGestureDetector::OnActorDestroyed(Object& object)
241 } // namespace Internal