It only receive for touch events that started from itself.
So if it's not a touch started by myself, actor doesn't receive a touch event.
Change-Id: I58151d7072a4f1dbae1a015e6b3fc0b298745773
}
END_TEST;
}
+
+int UtcDaliActorAllowOnlyOwnTouchPropertyP(void)
+{
+ TestApplication application;
+
+ Actor actor = Actor::New();
+ DALI_TEST_EQUALS(actor.GetProperty(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH).Get<bool>(), false, TEST_LOCATION);
+ actor.SetProperty(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH, true);
+ DALI_TEST_EQUALS(actor.GetProperty(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH).Get<bool>(), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.GetPropertyType(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH), Property::BOOLEAN, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsPropertyWritable(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsPropertyAnimatable(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH), false, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsPropertyAConstraintInput(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH), false, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.GetPropertyName(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH), "allowOnlyOwnTouch", TEST_LOCATION);
+ END_TEST;
+}
+
+int UtcDaliActorAllowOnlyOwnTouchPropertyN(void)
+{
+ TestApplication application;
+
+ Actor actor = Actor::New();
+
+ // Make sure setting invalid types does not cause a crash
+ try
+ {
+ actor.SetProperty(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH, 1.0f);
+ actor.SetProperty(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH, Vector2::ONE);
+ actor.SetProperty(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH, Vector3::ONE);
+ actor.SetProperty(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH, Vector4::ONE);
+ actor.SetProperty(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH, Property::Map());
+ actor.SetProperty(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH, Property::Array());
+ tet_result(TET_PASS);
+ }
+ catch(...)
+ {
+ tet_result(TET_FAIL);
+ }
+ END_TEST;
+}
\ No newline at end of file
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
END_TEST;
}
+
+int UtcDaliTouchEventAllowOnlyOwnTouchPropertySet(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();
+
+ // Connect to actor's touched signal
+ SignalData data;
+ TouchEventFunctor functor(data);
+ actor.TouchedSignal().Connect(&application, functor);
+
+ // Emit a down signal outside of actor, we should not receive the event
+ application.ProcessEvent(GenerateSingleTouch(PointState::STARTED, Vector2(110.0f, 110.0f)));
+ DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Now motion inside of actor, we should receive the event
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(80.0f, 80.0f)));
+ DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Up event, should not receive the event
+ application.ProcessEvent(GenerateSingleTouch(PointState::FINISHED, Vector2(110.0f, 110.0f)));
+ DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Now set the only allow own touch property
+ actor.SetProperty(DevelActor::Property::ALLOW_ONLY_OWN_TOUCH, true);
+
+ // Emit a down signal outside of actor, we should not receive the event
+ application.ProcessEvent(GenerateSingleTouch(PointState::STARTED, Vector2(110.0f, 110.0f)));
+ DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Now motion inside of actor, we should NOT receive the event
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(80.0f, 80.0f)));
+ DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Up event, should not receive the event
+ application.ProcessEvent(GenerateSingleTouch(PointState::FINISHED, Vector2(110.0f, 110.0f)));
+ DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Emit a down signal inside of actor, we should receive the event
+ application.ProcessEvent(GenerateSingleTouch(PointState::STARTED, Vector2(10.0f, 10.0f)));
+ DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Now motion inside of actor, we should receive the event
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(80.0f, 80.0f)));
+ DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Now motion outsize of actor, we should receive the event
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(110.0f, 110.0f)));
+ DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+ data.Reset();
+
+ // Up event, should receive an interrupted
+ application.ProcessEvent(GenerateSingleTouch(PointState::FINISHED, Vector2(110.0f, 110.0f)));
+ DALI_TEST_EQUALS(true, data.functorCalled, TEST_LOCATION);
+ DALI_TEST_EQUALS(data.receivedTouch.GetPoint(0).state, PointState::INTERRUPTED, TEST_LOCATION);
+ data.Reset();
+
+ END_TEST;
+}
\ No newline at end of file
* @note Default value is true.
*/
USER_INTERACTION_ENABLED,
+
+ /**
+ * @brief It only receive for touch events that started from itself.
+ * @details Name "allowOnlyOwnTouch", type Property::BOOLEAN
+ * @note Default is false.
+ */
+ ALLOW_ONLY_OWN_TOUCH,
};
} // namespace Property
DALI_PROPERTY("touchFocusable", BOOLEAN, true, false, false, Dali::DevelActor::Property::TOUCH_FOCUSABLE)
DALI_PROPERTY("keyboardFocusableChildren", BOOLEAN, true, false, false, Dali::DevelActor::Property::KEYBOARD_FOCUSABLE_CHILDREN)
DALI_PROPERTY("userInteractionEnabled", BOOLEAN, true, false, false, Dali::DevelActor::Property::USER_INTERACTION_ENABLED)
+DALI_PROPERTY("allowOnlyOwnTouch", BOOLEAN, true, false, false, Dali::DevelActor::Property::ALLOW_ONLY_OWN_TOUCH)
DALI_PROPERTY_TABLE_END(DEFAULT_ACTOR_PROPERTY_START_INDEX, ActorDefaultProperties)
// Signals
mIsBlendEquationSet(false),
mNeedGesturePropagation(false),
mUserInteractionEnabled(true),
+ mAllowOnlyOwnTouch(false),
mLayoutDirection(LayoutDirection::LEFT_TO_RIGHT),
mDrawMode(DrawMode::NORMAL),
mColorMode(Node::DEFAULT_COLOR_MODE),
return mTouchAreaOffset;
}
+ /**
+ * Query whether the actor will only receive own touch.
+ * @return true, if it only receives touches that started from itself.
+ */
+ bool IsAllowedOnlyOwnTouch() const
+ {
+ return mAllowOnlyOwnTouch;
+ }
+
// Gestures
/**
bool mIsBlendEquationSet : 1; ///< Flag to identify whether the Blend equation is set
bool mNeedGesturePropagation : 1; ///< Whether the parent listens for gesture events or not
bool mUserInteractionEnabled : 1; ///< Whether the actor should be enabled user interaction.
+ bool mAllowOnlyOwnTouch : 1; ///< whether the actor will only receive own touch. it only receives touches that started from itself.
LayoutDirection::Type mLayoutDirection : 2; ///< Layout direction, Left to Right or Right to Left.
DrawMode::Type mDrawMode : 3; ///< Cached: How the actor and its children should be drawn
ColorMode mColorMode : 3; ///< Cached: Determines whether mWorldColor is inherited
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
break;
}
+ case Dali::DevelActor::Property::ALLOW_ONLY_OWN_TOUCH:
+ {
+ bool boolValue = false;
+ if(property.Get(boolValue))
+ {
+ actor.mAllowOnlyOwnTouch = boolValue;
+ }
+ break;
+ }
+
default:
{
// this can happen in the case of a non-animatable default property so just do nothing
break;
}
+ case Dali::DevelActor::Property::ALLOW_ONLY_OWN_TOUCH:
+ {
+ value = actor.mAllowOnlyOwnTouch;
+ break;
+ }
+
default:
{
// Must be a scene-graph only property
bool ActorRequiresHitResultCheck(Actor* actor, Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp) override
{
+ if(point.GetState() != PointState::STARTED && actor->IsAllowedOnlyOwnTouch() && ownActor != actor)
+ {
+ return false;
+ }
return actor->EmitHitTestResultSignal(point, hitPointLocal, timeStamp);
}
+
+ void SetOwnActor(const Actor* actor)
+ {
+ ownActor = actor;
+ }
+ const Actor* ownActor;
};
/**
return wasHit;
}
-bool HitTest(const Vector2& sceneSize, RenderTaskList& renderTaskList, LayerList& layerList, const Vector2& screenCoordinates, Results& results)
+bool HitTest(const Vector2& sceneSize, RenderTaskList& renderTaskList, LayerList& layerList, const Vector2& screenCoordinates, Results& results, const Actor* ownActor)
{
ActorTouchableCheck actorTouchableCheck;
+ actorTouchableCheck.SetOwnActor(ownActor);
return HitTest(sceneSize, renderTaskList, layerList, screenCoordinates, results, actorTouchableCheck);
}
* @param[in] layerList The layer list of the scene.
* @param[in] screenCoordinates The screen coordinates.
* @param[out] results The results of the hit-test.
+ * @param[in] ownActor The actor from which the touch down was started.
* @return true if something was hit
*
* @see HitTest(Stage&, const Vector2&, Results&, HitTestInterface&)
*/
-bool HitTest(const Vector2& sceneSize, RenderTaskList& renderTaskList, LayerList& layerList, const Vector2& screenCoordinates, Results& results);
+bool HitTest(const Vector2& sceneSize, RenderTaskList& renderTaskList, LayerList& layerList, const Vector2& screenCoordinates, Results& results, const Actor* ownActor = nullptr);
} // namespace HitTestAlgorithm
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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 ParsePrimaryTouchPoint(
HitTestAlgorithm::Results& hitTestResults,
ActorObserver& capturingTouchActorObserver,
+ ActorObserver& ownTouchActorObserver,
const RenderTaskPtr& lastRenderTask,
const Integration::Point& currentPoint,
const Internal::Scene& scene)
}
else
{
- HitTestAlgorithm::HitTest(scene.GetSize(), scene.GetRenderTaskList(), scene.GetLayerList(), currentPoint.GetScreenPosition(), hitTestResults);
+ Actor* ownTouchActor = ownTouchActorObserver.GetActor();
+ HitTestAlgorithm::HitTest(scene.GetSize(), scene.GetRenderTaskList(), scene.GetLayerList(), currentPoint.GetScreenPosition(), hitTestResults, ownTouchActor);
if(currentPoint.GetState() == PointState::STARTED && hitTestResults.actor)
{
{
capturingTouchActorObserver.SetActor(hitActor);
}
+ if(hitActor->IsAllowedOnlyOwnTouch())
+ {
+ ownTouchActorObserver.SetActor(hitActor);
+ }
}
}
}
mLastPrimaryHitActor(MakeCallback(this, &TouchEventProcessor::OnObservedActorDisconnected)),
mLastConsumedActor(),
mCapturingTouchActor(),
+ mOwnTouchActor(),
mTouchDownConsumedActor(),
mLastRenderTask(),
mLastPrimaryPointState(PointState::FINISHED)
DALI_LOG_TRACE_METHOD(gLogFilter);
}
+void TouchEventProcessor::Clear()
+{
+ mLastPrimaryHitActor.SetActor(nullptr);
+ mLastConsumedActor.SetActor(nullptr);
+ mCapturingTouchActor.SetActor(nullptr);
+ mOwnTouchActor.SetActor(nullptr);
+ mLastRenderTask.Reset();
+ mLastPrimaryPointState = PointState::FINISHED;
+}
+
bool TouchEventProcessor::ProcessTouchEvent(const Integration::TouchEvent& event)
{
DALI_LOG_TRACE_METHOD(gLogFilter);
AllocAndEmitTouchSignals(event.time, touchDownConsumedActorHandle, currentPoint);
}
- mLastPrimaryHitActor.SetActor(nullptr);
- mLastConsumedActor.SetActor(nullptr);
- mCapturingTouchActor.SetActor(nullptr);
+ Clear();
mTouchDownConsumedActor.SetActor(nullptr);
- mLastRenderTask.Reset();
- mLastPrimaryPointState = PointState::FINISHED;
currentPoint.SetHitActor(Dali::Actor());
for(auto&& currentPoint : event.points)
{
HitTestAlgorithm::Results hitTestResults;
- hitTestResults.point = currentPoint;
+ hitTestResults.point = currentPoint;
hitTestResults.eventTime = event.time;
if(!firstPointParsed)
{
firstPointParsed = true;
- ParsePrimaryTouchPoint(hitTestResults, mCapturingTouchActor, mLastRenderTask, currentPoint, mScene);
+ ParsePrimaryTouchPoint(hitTestResults, mCapturingTouchActor, mOwnTouchActor, mLastRenderTask, currentPoint, mScene);
// Only set the currentRenderTask for the primary hit actor.
currentRenderTask = hitTestResults.renderTask;
// time so set our last primary actor to NULL. Do the same to the last consumed actor as well.
if(primaryPointState == PointState::UP)
{
- mLastPrimaryHitActor.SetActor(nullptr);
- mLastConsumedActor.SetActor(nullptr);
- mCapturingTouchActor.SetActor(nullptr);
- mLastRenderTask.Reset();
- mLastPrimaryPointState = PointState::FINISHED;
+ Clear();
}
else
{
}
else
{
- mLastPrimaryHitActor.SetActor(nullptr);
- mLastConsumedActor.SetActor(nullptr);
- mCapturingTouchActor.SetActor(nullptr);
- mLastRenderTask.Reset();
- mLastPrimaryPointState = PointState::FINISHED;
+ Clear();
}
}
#define DALI_INTERNAL_TOUCH_EVENT_PROCESSOR_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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 OnObservedActorDisconnected(Actor* actor);
+ /**
+ * Clears the value.
+ */
+ void Clear();
+
ActorObserver mLastPrimaryHitActor; ///< Stores the last primary point hit actor
ActorObserver mLastConsumedActor; ///< Stores the last consumed actor
ActorObserver mCapturingTouchActor; ///< Stored the actor that captures touch
+ ActorObserver mOwnTouchActor; ///< Stored the actor that own touch
ActorObserver mTouchDownConsumedActor; ///< Stores the touch-down consumed actor
RenderTaskPtr mLastRenderTask; ///< The RenderTask used for the last hit actor
PointState::Type mLastPrimaryPointState; ///< Stores the last primary point state