Since PanGestureDetector use SG::PanGesture, which the memory ownership is on UpdateManager,
we need to take carefully to control the memory usage.
Change-Id: I7c2929c97b57e6e14072e0598bcd1788aa43af98
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
bool propagation;
};
-
// Data for constraints
struct ConstraintData
{
GestureReceivedFunctor functor(data);
detector.DetectedSignal().Connect(&application, functor);
- Property::Index property = actor.RegisterProperty("Dummy Property", Vector3::ZERO);
- Property::Index animatableGestureProperty = detector.RegisterProperty("Dummy Property", Vector3::ZERO); // For code coverage
+ Property::Index property = actor.RegisterProperty("Dummy Property", Vector3::ZERO);
ConstraintData constraintData;
Constraint constraint = Constraint::New<Vector3>(actor, property, PanConstraint(constraintData));
constraint.AddSource(Source(detector, PanGestureDetector::Property::LOCAL_DISPLACEMENT));
constraint.AddSource(Source(detector, PanGestureDetector::Property::LOCAL_VELOCITY));
constraint.AddSource(Source(detector, PanGestureDetector::Property::PANNING));
- constraint.AddSource(Source(detector, animatableGestureProperty));
constraint.Apply();
// Render and notify
int UtcDaliPanGestureHandleEvent(void)
{
- TestApplication application;
- Integration::Scene scene = application.GetScene();
- RenderTaskList taskList = scene.GetRenderTaskList();
- Dali::RenderTask task = taskList.GetTask(0);
+ TestApplication application;
+ Integration::Scene scene = application.GetScene();
+ RenderTaskList taskList = scene.GetRenderTaskList();
+ Dali::RenderTask task = taskList.GetTask(0);
Actor parentActor = Actor::New();
parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
PanGestureDetector parentDetector = PanGestureDetector::New();
parentDetector.DetectedSignal().Connect(&application, pFunctor);
-
Integration::TouchEvent tp = GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 100);
Internal::TouchEventPtr touchEventImpl(new Internal::TouchEvent(100));
touchEventImpl->AddPoint(tp.GetPoint(0));
Dali::TouchEvent touchEventHandle(touchEventImpl.Get());
parentDetector.HandleEvent(parentActor, touchEventHandle);
-
- tp = GenerateSingleTouch(PointState::MOTION, Vector2(70.0f, 70.0f), 150);
+ tp = GenerateSingleTouch(PointState::MOTION, Vector2(70.0f, 70.0f), 150);
touchEventImpl = new Internal::TouchEvent(150);
touchEventImpl->AddPoint(tp.GetPoint(0));
touchEventImpl->SetRenderTask(task);
touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
parentDetector.HandleEvent(parentActor, touchEventHandle);
-
- tp = GenerateSingleTouch(PointState::MOTION, Vector2(90.0f, 90.0f), 200);
+ tp = GenerateSingleTouch(PointState::MOTION, Vector2(90.0f, 90.0f), 200);
touchEventImpl = new Internal::TouchEvent(200);
touchEventImpl->AddPoint(tp.GetPoint(0));
touchEventImpl->SetRenderTask(task);
touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
parentDetector.HandleEvent(parentActor, touchEventHandle);
- tp = GenerateSingleTouch(PointState::UP, Vector2(100.0f, 100.0f), 250);
+ tp = GenerateSingleTouch(PointState::UP, Vector2(100.0f, 100.0f), 250);
touchEventImpl = new Internal::TouchEvent(250);
touchEventImpl->AddPoint(tp.GetPoint(0));
touchEventImpl->SetRenderTask(task);
touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
parentDetector.HandleEvent(parentActor, touchEventHandle);
-
DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
pData.Reset();
int UtcDaliPanGestureFeedTouchWhenGesturePropagation(void)
{
- TestApplication application;
- Integration::Scene scene = application.GetScene();
- RenderTaskList taskList = scene.GetRenderTaskList();
- Dali::RenderTask task = taskList.GetTask(0);
+ TestApplication application;
+ Integration::Scene scene = application.GetScene();
+ RenderTaskList taskList = scene.GetRenderTaskList();
+ Dali::RenderTask task = taskList.GetTask(0);
Actor parentActor = Actor::New();
parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
parentDetector.HandleEvent(parentActor, touchEventHandle);
}
- tp = GenerateSingleTouch(PointState::MOTION, Vector2(60.0f, 60.0f), 150);
+ tp = GenerateSingleTouch(PointState::MOTION, Vector2(60.0f, 60.0f), 150);
touchEventImpl = new Internal::TouchEvent(150);
touchEventImpl->AddPoint(tp.GetPoint(0));
touchEventImpl->SetRenderTask(task);
parentDetector.HandleEvent(parentActor, touchEventHandle);
}
- tp = GenerateSingleTouch(PointState::MOTION, Vector2(70.0f, 70.0f), 200);
+ tp = GenerateSingleTouch(PointState::MOTION, Vector2(70.0f, 70.0f), 200);
touchEventImpl = new Internal::TouchEvent(200);
touchEventImpl->AddPoint(tp.GetPoint(0));
touchEventImpl->SetRenderTask(task);
parentDetector.HandleEvent(parentActor, touchEventHandle);
}
- tp = GenerateSingleTouch(PointState::MOTION, Vector2(80.0f, 80.0f), 250);
+ tp = GenerateSingleTouch(PointState::MOTION, Vector2(80.0f, 80.0f), 250);
touchEventImpl = new Internal::TouchEvent(200);
touchEventImpl->AddPoint(tp.GetPoint(0));
touchEventImpl->SetRenderTask(task);
parentDetector.HandleEvent(parentActor, touchEventHandle);
}
- tp = GenerateSingleTouch(PointState::UP, Vector2(100.0f, 100.0f), 300);
+ tp = GenerateSingleTouch(PointState::UP, Vector2(100.0f, 100.0f), 300);
touchEventImpl = new Internal::TouchEvent(250);
touchEventImpl->AddPoint(tp.GetPoint(0));
touchEventImpl->SetRenderTask(task);
cData.Reset();
pData.Reset();
-
// If GesturePropargation is set, a gesture event is to pass over to the parent.
SignalData cPData;
PropagationActorFunctor cPFunctor(cPData, true);
childDetector.DetectedSignal().Connect(&application, cPFunctor);
// So now the parent got the gesture event.
- tp = GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 100);
+ tp = GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 100);
touchEventImpl = new Internal::TouchEvent(100);
touchEventImpl->AddPoint(tp.GetPoint(0));
touchEventImpl->SetRenderTask(task);
parentDetector.HandleEvent(parentActor, touchEventHandle);
}
- tp = GenerateSingleTouch(PointState::MOTION, Vector2(60.0f, 60.0f), 150);
+ tp = GenerateSingleTouch(PointState::MOTION, Vector2(60.0f, 60.0f), 150);
touchEventImpl = new Internal::TouchEvent(150);
touchEventImpl->AddPoint(tp.GetPoint(0));
touchEventImpl->SetRenderTask(task);
parentDetector.HandleEvent(parentActor, touchEventHandle);
}
- tp = GenerateSingleTouch(PointState::MOTION, Vector2(70.0f, 70.0f), 200);
+ tp = GenerateSingleTouch(PointState::MOTION, Vector2(70.0f, 70.0f), 200);
touchEventImpl = new Internal::TouchEvent(200);
touchEventImpl->AddPoint(tp.GetPoint(0));
touchEventImpl->SetRenderTask(task);
parentDetector.HandleEvent(parentActor, touchEventHandle);
}
- tp = GenerateSingleTouch(PointState::MOTION, Vector2(80.0f, 80.0f), 250);
+ tp = GenerateSingleTouch(PointState::MOTION, Vector2(80.0f, 80.0f), 250);
touchEventImpl = new Internal::TouchEvent(250);
touchEventImpl->AddPoint(tp.GetPoint(0));
touchEventImpl->SetRenderTask(task);
parentDetector.HandleEvent(parentActor, touchEventHandle);
}
- tp = GenerateSingleTouch(PointState::UP, Vector2(100.0f, 100.0f), 300);
+ tp = GenerateSingleTouch(PointState::UP, Vector2(100.0f, 100.0f), 300);
touchEventImpl = new Internal::TouchEvent(300);
touchEventImpl->AddPoint(tp.GetPoint(0));
touchEventImpl->SetRenderTask(task);
const Integration::Scene::TouchPropagationType propagationType)
{
bool isClippingOrHittable = clippingActor || hitCheck.IsActorHittable(&actor);
- bool isGeometry = propagationType == Integration::Scene::TouchPropagationType::GEOMETRY;
+ bool isGeometry = propagationType == Integration::Scene::TouchPropagationType::GEOMETRY;
if(isClippingOrHittable || isGeometry)
{
Vector3 size(actor.GetCurrentSize());
Vector2 hitPointLocal;
float distance;
if(!(rayTest.SphereTest(*actor.GetParent(), rayOrigin, rayDir) &&
- rayTest.ActorTest(*actor.GetParent(), rayOrigin, rayDir, hitPointLocal, distance)))
+ rayTest.ActorTest(*actor.GetParent(), rayOrigin, rayDir, hitPointLocal, distance)))
{
return false;
}
* - When comparing against renderable parents, if Actor is the same distance
* or closer than it's renderable parent, then it takes priority.
*/
-HitActor HitTestWithinLayer(Actor& actor,
- const RenderTask& renderTask,
- const RenderTaskList::ExclusivesContainer& exclusives,
- const Vector4& rayOrigin,
- const Vector4& rayDir,
- const float& nearClippingPlane,
- const float& farClippingPlane,
- HitTestInterface& hitCheck,
- const bool& overlayed,
- bool& overlayHit,
- bool layerIs3d,
- const RayTest& rayTest,
- const Integration::Point& point,
- const uint32_t eventTime,
- std::list<Dali::Internal::Actor*>& actorLists,
- const Integration::Scene::TouchPropagationType propagationType)
+HitActor HitTestWithinLayer(Actor& actor,
+ const RenderTask& renderTask,
+ const RenderTaskList::ExclusivesContainer& exclusives,
+ const Vector4& rayOrigin,
+ const Vector4& rayDir,
+ const float& nearClippingPlane,
+ const float& farClippingPlane,
+ HitTestInterface& hitCheck,
+ const bool& overlayed,
+ bool& overlayHit,
+ bool layerIs3d,
+ const RayTest& rayTest,
+ const Integration::Point& point,
+ const uint32_t eventTime,
+ std::list<Dali::Internal::Actor*>& actorLists,
+ const Integration::Scene::TouchPropagationType propagationType)
{
HitActor hit;
Dali::Actor FindPriorActorInLayer(Dali::Actor rootActor, Dali::Actor firstActor, Dali::Actor secondActor)
{
Dali::Actor priorActor;
- Dali::Layer layer = rootActor.GetLayer();
- bool firstActorIncluded = firstActor.GetLayer() == layer;
- bool secondActorIncluded = secondActor.GetLayer() == layer;
+ Dali::Layer layer = rootActor.GetLayer();
+ bool firstActorIncluded = firstActor.GetLayer() == layer;
+ bool secondActorIncluded = secondActor.GetLayer() == layer;
if(firstActorIncluded && !secondActorIncluded)
{
*/
Dali::Actor FindPriorActorInLayers(const LayerList& layers, Dali::Actor rootActor, Dali::Actor firstActor, Dali::Actor secondActor)
{
- Dali::Layer sourceLayer = rootActor.GetLayer();
+ Dali::Layer sourceLayer = rootActor.GetLayer();
const uint32_t sourceActorDepth(sourceLayer.GetProperty<int>(Dali::Layer::Property::DEPTH));
Dali::Actor priorActor;
- uint32_t layerCount = layers.GetLayerCount();
+ uint32_t layerCount = layers.GetLayerCount();
if(layerCount > 0)
{
for(int32_t i = layerCount - 1; i >= 0; --i)
* @param[in] propagationType Whether the scene using geometry event propagation touch and hover events.
* @return True if we have a hit, false otherwise
*/
-bool HitTestRenderTaskList(const Vector2& sceneSize,
- LayerList& layers,
- RenderTaskList& taskList,
- const Vector2& screenCoordinates,
- Results& results,
- HitTestInterface& hitCheck,
- const Integration::Scene::TouchPropagationType propagationType)
+bool HitTestRenderTaskList(const Vector2& sceneSize,
+ LayerList& layers,
+ RenderTaskList& taskList,
+ const Vector2& screenCoordinates,
+ Results& results,
+ HitTestInterface& hitCheck,
+ const Integration::Scene::TouchPropagationType propagationType)
{
if(propagationType == Integration::Scene::TouchPropagationType::GEOMETRY)
{
{
bool wasHit(false);
// Hit-test the regular on-scene actors
- Results hitTestResults;
+ Results hitTestResults;
+ hitTestResults.eventTime = 0u; ///< Unused
+
HitTestFunctionWrapper hitTestFunctionWrapper(func);
if(HitTestForEachRenderTask(sceneSize, layerList, taskList, screenCoordinates, hitTestResults, hitTestFunctionWrapper, propagationType))
{
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
Dali::PanGestureDetector handle(this);
DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Emitting Signal (%p)\n", this);
- if(pan.GetState() != GestureState::CONTINUING)
+ if(pan.GetState() != GestureState::CONTINUING)
{
DALI_LOG_DEBUG_INFO("emitting pan gesture actor id(%d) state(%d)\n", actor.GetProperty<int32_t>(Dali::Actor::Property::ID), pan.GetState());
}
}
PanGestureDetector::PanGestureDetector(const SceneGraph::PanGesture& sceneObject)
-: GestureDetector(GestureType::PAN, &sceneObject),
+: GestureDetector(GestureType::PAN),
mMinimumTouches(1),
mMaximumTouches(1),
mMaximumMotionEventAge(std::numeric_limits<uint32_t>::max()),
mPossiblePanPosition(0.f, 0.f),
- mSceneObject(SceneGraph::PanGesture::New())
+ mSceneObject(const_cast<SceneGraph::PanGesture*>(&sceneObject))
{
}
const SceneGraph::PanGesture& PanGestureDetector::GetPanGestureSceneObject() const
{
- return static_cast<const SceneGraph::PanGesture&>(GetSceneObject());
+ return static_cast<const SceneGraph::PanGesture&>(*mSceneObject);
}
void PanGestureDetector::OnActorAttach(Actor& actor)
return HandleEvent(actor, touchEvent);
}
-
void PanGestureDetector::SetDefaultProperty(Property::Index index, const Property::Value& property)
{
// None of our properties should be settable from Public API
if(!mGestureRecognizer)
{
const PanGestureProcessor& panGestureProcessor = mGestureEventProcessor.GetPanGestureProcessor();
- int32_t minDistance = panGestureProcessor.GetMinimumDistance();
- int32_t minPanEvents = panGestureProcessor.GetMinimumPanEvents();
+ int32_t minDistance = panGestureProcessor.GetMinimumDistance();
+ int32_t minPanEvents = panGestureProcessor.GetMinimumPanEvents();
PanGestureRequest request;
request.minTouches = GetMinimumTouchesRequired();
case GestureState::CONTINUING:
{
Actor* currentGesturedActor = mCurrentPanActor.GetActor();
- Actor* feededActor = mFeededActor.GetActor();
+ Actor* feededActor = mFeededActor.GetActor();
if(currentGesturedActor && currentGesturedActor->NeedGesturePropagation() && feededActor && feededActor != currentGesturedActor)
{
if(feededActor->IsHittable() && CheckGestureDetector(&panEvent, feededActor, mRenderTask, mPossiblePanPosition))
CheckGestureDetector(gestureEvent, actor, renderTask);
const PanGestureEvent* panEvent(static_cast<const PanGestureEvent*>(gestureEvent));
- bool retVal(false);
+ bool retVal(false);
if((panEvent->numberOfTouches >= GetMinimumTouchesRequired()) &&
(panEvent->numberOfTouches <= GetMaximumTouchesRequired()))
}
}
-
-void PanGestureDetector::EmitPanSignal(Actor* actor,
- const PanGestureEvent& panEvent,
- Vector2 localCurrent,
- GestureState state,
- RenderTaskPtr renderTask)
+void PanGestureDetector::EmitPanSignal(Actor* actor,
+ const PanGestureEvent& panEvent,
+ Vector2 localCurrent,
+ GestureState state,
+ RenderTaskPtr renderTask)
{
SetDetected(true);
Internal::PanGesturePtr pan(new Internal::PanGesture(panEvent.state));
// When the gesture ends, we may incorrectly get a ZERO velocity (as we have lifted our finger without any movement)
// so we should use the last recorded velocity instead in this scenario.
if((panEvent.state == GestureState::FINISHED) && (pan->GetScreenVelocity() == Vector2::ZERO) &&
- (panEvent.timeDelta < MAXIMUM_TIME_WITH_VALID_LAST_VELOCITY))
+ (panEvent.timeDelta < MAXIMUM_TIME_WITH_VALID_LAST_VELOCITY))
{
pan->SetVelocity(mLastVelocity);
pan->SetScreenVelocity(mLastScreenVelocity);
mLastScreenVelocity = pan->GetScreenVelocity();
}
- if(mSceneObject)
+ // We should not use scene object if Core is shutting down.
+ if(DALI_LIKELY(Dali::Stage::IsInstalled() && mSceneObject))
{
// We update the scene object directly rather than sending a message.
// Sending a message could cause unnecessary delays, the scene object ensure thread safe behaviour.
#define DALI_INTERNAL_PAN_GESTURE_DETECTOR_H
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
*/
void CancelProcessing() override;
- /**
+ /**
* This method is called whenever a pan gesture event occurs.
* @param[in] scene The scene the pan gesture event occurs in.
* @param[in] panEvent The event that has occurred.
* @param[in] state The state of the gesture.
* @param[in] renderTask The renderTask to use.
*/
- void EmitPanSignal(Actor* actor, const PanGestureEvent& panEvent, Vector2 localCurrent, GestureState state, RenderTaskPtr renderTask);
-
+ void EmitPanSignal(Actor* actor, const PanGestureEvent& panEvent, Vector2 localCurrent, GestureState state, RenderTaskPtr renderTask);
// Default property extensions from Object
private:
Dali::PanGestureDetector::DetectedSignalType mDetectedSignal;
- uint32_t mMinimumTouches; ///< The minimum number of fingers required to be touching for pan.
- uint32_t mMaximumTouches; ///< The maximum number of fingers required to be touching for pan.
- uint32_t mMaximumMotionEventAge; ///< The maximum age of motion events as milliseconds.
-
- AngleContainer mAngleContainer; ///< A container of all angles allowed for pan to occur.
-
- Vector2 mPossiblePanPosition; ///< The Position when possible state.
- Vector2 mLastVelocity; ///< The last recorded velocity in local actor coordinates.
- Vector2 mLastScreenVelocity; ///< The last recorded velocity in screen coordinates.
- ActorObserver mCurrentPanActor; ///< The current actor that has been gestured.
- SceneGraph::PanGesture* mSceneObject; ///< Not owned, but we write to it directly
+ uint32_t mMinimumTouches; ///< The minimum number of fingers required to be touching for pan.
+ uint32_t mMaximumTouches; ///< The maximum number of fingers required to be touching for pan.
+ uint32_t mMaximumMotionEventAge; ///< The maximum age of motion events as milliseconds.
+ AngleContainer mAngleContainer; ///< A container of all angles allowed for pan to occur.
+ Vector2 mPossiblePanPosition; ///< The Position when possible state.
+ Vector2 mLastVelocity; ///< The last recorded velocity in local actor coordinates.
+ Vector2 mLastScreenVelocity; ///< The last recorded velocity in screen coordinates.
+ ActorObserver mCurrentPanActor; ///< The current actor that has been gestured.
+ SceneGraph::PanGesture* mSceneObject; ///< Not owned, but we write to it directly (Owned by UpdateManager)
};
} // namespace Internal