DALI_TEST_EQUALS(data.receivedGesture.GetSourceType(), GestureSourceType::TERTIARY, TEST_LOCATION);
END_TEST;
+}
+
+int UtcDaliTapGestureReceiveAllTapEvents(void)
+{
+ TestApplication application;
+
+ Actor actor = Actor::New();
+ actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ application.GetScene().Add(actor);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ SignalData data;
+ GestureReceivedFunctor functor(data);
+
+ TapGestureDetector detector = TapGestureDetector::New();
+ detector.SetMaximumTapsRequired(2u);
+ detector.Attach(actor);
+ detector.DetectedSignal().Connect(&application, functor);
+
+ // Emit signals, Because MaximumTapsRequired is 2, a timer that checks whether it is a single tap or a double tap operates internally.
+ application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 100));
+ application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 120));
+ application.SendNotification();
+
+ // So detector don't get the tap event yet.
+ DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Emit signals, Send the second tab.
+ application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 130));
+ application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 150));
+ application.SendNotification();
+ application.GetPlatform().TriggerTimer();
+
+ // It find out to be a double tap. Detector receives events.
+ DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Detector want to receive all tap events.
+ detector.ReceiveAllTapEvents(true);
+
+ // Emit signals, should receive
+ application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 0, 500));
+ application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 0, 520));
+ application.SendNotification();
+
+ DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Emit signals, should receive
+ application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 530));
+ application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 550));
+ application.SendNotification();
+
+ DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ END_TEST;
}
\ No newline at end of file
#include <cstring> // for strcmp
// INTERNAL INCLUDES
-#include <dali/public-api/events/tap-gesture.h>
-#include <dali/public-api/object/type-registry.h>
#include <dali/integration-api/debug.h>
+#include <dali/integration-api/platform-abstraction.h>
+#include <dali/internal/event/common/thread-local-storage.h>
#include <dali/internal/event/events/gesture-event-processor.h>
+#include <dali/internal/event/events/tap-gesture/tap-gesture-impl.h>
+#include <dali/public-api/events/tap-gesture.h>
+#include <dali/public-api/object/type-registry.h>
namespace Dali
{
namespace
{
-
-const unsigned int DEFAULT_TAPS_REQUIRED = 1u;
-const unsigned int DEFAULT_TOUCHES_REQUIRED = 1u;
+constexpr uint32_t DEFAULT_TAPS_REQUIRED = 1u;
+constexpr uint32_t DEFAULT_TOUCHES_REQUIRED = 1u;
+constexpr uint32_t DEFAULT_TAP_WAIT_TIME = 330u;
// Signals
const char* const SIGNAL_TAP_DETECTED = "tapDetected";
}
TapGestureDetector::TapGestureDetector()
-: GestureDetector( GestureType::TAP ),
- mMinimumTapsRequired( DEFAULT_TAPS_REQUIRED ),
- mMaximumTapsRequired( DEFAULT_TAPS_REQUIRED ),
- mTouchesRequired( DEFAULT_TOUCHES_REQUIRED )
+: GestureDetector(GestureType::TAP),
+ mMinimumTapsRequired(DEFAULT_TAPS_REQUIRED),
+ mMaximumTapsRequired(DEFAULT_TAPS_REQUIRED),
+ mTouchesRequired(DEFAULT_TOUCHES_REQUIRED),
+ mTimerId(0),
+ mTappedActor(),
+ mTap(),
+ mReceiveAllTapEvents(false)
{
}
-TapGestureDetector::TapGestureDetector( unsigned int tapsRequired )
-: GestureDetector( GestureType::TAP ),
- mMinimumTapsRequired( tapsRequired ),
- mMaximumTapsRequired( tapsRequired ),
- mTouchesRequired( DEFAULT_TOUCHES_REQUIRED )
+TapGestureDetector::TapGestureDetector(unsigned int tapsRequired)
+: GestureDetector(GestureType::TAP),
+ mMinimumTapsRequired(tapsRequired),
+ mMaximumTapsRequired(tapsRequired),
+ mTouchesRequired(DEFAULT_TOUCHES_REQUIRED),
+ mTimerId(0),
+ mTappedActor(),
+ mTap(),
+ mReceiveAllTapEvents(false)
{
}
-TapGestureDetector::~TapGestureDetector() = default;
+TapGestureDetector::~TapGestureDetector()
+{
+ if(mTimerId != 0 && ThreadLocalStorage::Created())
+ {
+ Dali::Integration::PlatformAbstraction& platformAbstraction = ThreadLocalStorage::Get().GetPlatformAbstraction();
+ platformAbstraction.CancelTimer(mTimerId);
+ }
+}
void TapGestureDetector::SetMinimumTapsRequired(unsigned int taps)
{
return mTouchesRequired;
}
+void TapGestureDetector::ReceiveAllTapEvents(bool receive)
+{
+ mReceiveAllTapEvents = receive;
+}
+
void TapGestureDetector::EmitTapGestureSignal(Dali::Actor tappedActor, const Dali::TapGesture& tap)
{
+ Dali::Integration::PlatformAbstraction& platformAbstraction = ThreadLocalStorage::Get().GetPlatformAbstraction();
+ if(mTimerId != 0)
+ {
+ platformAbstraction.CancelTimer(mTimerId);
+ mTimerId = 0;
+ }
+ if(mMaximumTapsRequired > tap.GetNumberOfTaps() && !mReceiveAllTapEvents)
+ {
+ mTappedActor = tappedActor;
+
+ Internal::TapGesturePtr internalTap(new Internal::TapGesture(tap.GetState()));
+ internalTap->SetTime(tap.GetTime());
+ internalTap->SetNumberOfTaps(tap.GetNumberOfTaps());
+ internalTap->SetNumberOfTouches(tap.GetNumberOfTouches());
+ internalTap->SetScreenPoint(tap.GetScreenPoint());
+ internalTap->SetLocalPoint(tap.GetLocalPoint());
+ internalTap->SetGestureSourceType(tap.GetSourceType());
+ mTap = Dali::TapGesture(internalTap.Get());
+
+ mTimerId = platformAbstraction.StartTimer(DEFAULT_TAP_WAIT_TIME, MakeCallback(this, &TapGestureDetector::TimerCallback));
+ }
+ else
+ {
+ // Guard against destruction during signal emission
+ Dali::TapGestureDetector handle(this);
+
+ mDetectedSignal.Emit(tappedActor, tap);
+ }
+}
+
+bool TapGestureDetector::TimerCallback()
+{
// Guard against destruction during signal emission
Dali::TapGestureDetector handle( this );
- mDetectedSignal.Emit( tappedActor, tap );
+ mDetectedSignal.Emit(mTappedActor, mTap);
+
+ mTimerId = 0;
+ return false;
}
bool TapGestureDetector::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
*/
unsigned int GetTouchesRequired() const;
+ /**
+ * @copydoc Dali::TapGestureDetector::ReceiveAllTapEvents()
+ */
+ void ReceiveAllTapEvents(bool receive);
+
public:
/**
TapGestureDetector(const TapGestureDetector&);
TapGestureDetector& operator=(const TapGestureDetector& rhs);
+ /**
+ * Timer Callback
+ * @return will return false; one-shot timer.
+ */
+ bool TimerCallback();
+
private: // GestureDetector overrides
/**
Dali::TapGestureDetector::DetectedSignalType mDetectedSignal;
- unsigned int mMinimumTapsRequired;
- unsigned int mMaximumTapsRequired;
- unsigned int mTouchesRequired;
+ unsigned int mMinimumTapsRequired;
+ unsigned int mMaximumTapsRequired;
+ unsigned int mTouchesRequired;
+ uint32_t mTimerId;
+ Dali::Actor mTappedActor;
+ Dali::TapGesture mTap;
+ bool mReceiveAllTapEvents;
};
} // namespace Internal
} // namespace Dali
-#endif // DALI_INTERNAL_TAP_GESTURE_DETECTOR_H
+#endif // DALI_INTERNAL_TAP_GESTURE_DETECTOR_H
\ No newline at end of file
*
* @param[in] tap event for processing
*/
- void ProcessEvent( TapGestureEvent& event );
+ void ProcessEvent(TapGestureEvent& event);
private:
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
return GetImplementation(*this).GetMaximumTapsRequired();
}
+void TapGestureDetector::ReceiveAllTapEvents(bool receive)
+{
+ return GetImplementation(*this).ReceiveAllTapEvents(receive);
+}
+
TapGestureDetector::DetectedSignalType& TapGestureDetector::DetectedSignal()
{
return GetImplementation(*this).DetectedSignal();
#define DALI_TAP_GESTURE_DETECTOR_H
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* @param[in] minimumTaps The minimum taps required
* @pre The gesture detector has been initialized.
* @note The default is '1', the maximum is 2.
+ * @see ReceiveAllTapEvents
*/
void SetMinimumTapsRequired(uint32_t minimumTaps);
* @param[in] maximumTaps The maximum taps required
* @pre The gesture detector has been initialized.
* @note The default is '1', the maximum is 2.
+ * @see ReceiveAllTapEvents
*/
void SetMaximumTapsRequired(uint32_t maximumTaps);
+ /**
+ * @brief When set to true, all tap gestures will be received when multiple taps are supported by the gesture detector.
+ *
+ * @param[in] receive The receiving all tap events flag
+ * @pre The gesture detector has been initialized.
+ * @note The default is false.
+ */
+ void ReceiveAllTapEvents(bool receive);
+
public: // Getters
/**
* @brief Retrieves the minimum number of taps required.