/*
- * Copyright (c) 2023 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.
// INTERNAL INCLUDES
#include <dali-test-suite-utils.h>
-#include <dali/internal/common/ordered-set.h>
+#include <dali/integration-api/ordered-set.h>
-using namespace Dali::Internal;
+using namespace Dali;
+using namespace Dali::Integration;
-void utc_dali_internal_owner_set_startup(void)
+void utc_dali_internal_ordered_set_startup(void)
{
test_return_value = TET_UNDEF;
}
-void utc_dali_internal_owner_set_cleanup(void)
+void utc_dali_internal_ordered_set_cleanup(void)
{
test_return_value = TET_PASS;
}
bool& mSignalCalled;
};
+struct InheritedVisibilityChangedFunctorData
+{
+ InheritedVisibilityChangedFunctorData()
+ : actor(),
+ visible(false),
+ called(false)
+ {
+ }
+
+ void Reset()
+ {
+ actor.Reset();
+ visible = false;
+ called = false;
+ }
+
+ void Check(bool compareCalled, Actor compareActor, bool compareVisible, const char* location)
+ {
+ DALI_TEST_EQUALS(called, compareCalled, TEST_INNER_LOCATION(location));
+ DALI_TEST_EQUALS(actor, compareActor, TEST_INNER_LOCATION(location));
+ DALI_TEST_EQUALS(visible, compareVisible, TEST_INNER_LOCATION(location));
+ }
+
+ void Check(bool compareCalled, const std::string& location)
+ {
+ DALI_TEST_EQUALS(called, compareCalled, TEST_INNER_LOCATION(location));
+ }
+
+ Actor actor;
+ bool visible;
+ bool called;
+};
+
+struct InheritedVisibilityChangedFunctor
+{
+ InheritedVisibilityChangedFunctor(InheritedVisibilityChangedFunctorData& dataVar)
+ : data(dataVar)
+ {
+ }
+
+ void operator()(Actor actor, bool visible)
+ {
+ data.actor = actor;
+ data.visible = visible;
+ data.called = true;
+ }
+
+ InheritedVisibilityChangedFunctorData& data;
+};
+
struct ChildOrderChangedFunctor
{
ChildOrderChangedFunctor(bool& signalCalled, Actor& actor)
END_TEST;
}
+int utcDaliActorInheritedVisibilityChangeSignal1(void)
+{
+ TestApplication application;
+ tet_infoline("Check that the inherited visibility change signal is called when the visibility changes for the actor itself");
+
+ Actor parentActor = Actor::New();
+ Actor actor = Actor::New();
+
+ InheritedVisibilityChangedFunctorData data;
+ actor.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(data));
+
+ parentActor.Add(actor);
+ data.Check(false, TEST_LOCATION);
+
+ data.Reset();
+ application.GetScene().Add(parentActor);
+ data.Check(true, actor, true, TEST_LOCATION);
+
+ data.Reset();
+ actor.SetProperty(Actor::Property::VISIBLE, false);
+ data.Check(true, actor, false, TEST_LOCATION);
+
+ data.Reset();
+ actor.SetProperty(Actor::Property::VISIBLE, false);
+ data.Check(false, TEST_LOCATION);
+
+ data.Reset();
+ actor.SetProperty(Actor::Property::VISIBLE, true);
+ data.Check(true, actor, true, TEST_LOCATION);
+
+ data.Reset();
+ actor.SetProperty(Actor::Property::VISIBLE, true);
+ data.Check(false, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int utcDaliActorInheritedVisibilityChangeSignal2(void)
+{
+ TestApplication application;
+ tet_infoline("Check that the inherited visibility change signal is called when the actor or one of the parent become on scene or off scene");
+
+ Actor parentActor = Actor::New();
+ Actor childActor = Actor::New();
+
+ InheritedVisibilityChangedFunctorData dataP, dataC;
+ parentActor.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(dataP));
+ childActor.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(dataC));
+
+ dataP.Reset();
+ dataC.Reset();
+ parentActor.Add(childActor);
+ dataP.Check(false, TEST_LOCATION);
+ dataC.Check(false, TEST_LOCATION);
+
+ dataP.Reset();
+ dataC.Reset();
+ application.GetScene().Add(parentActor);
+ dataP.Check(true, parentActor, true, TEST_LOCATION);
+ dataC.Check(true, childActor, true, TEST_LOCATION);
+
+ dataP.Reset();
+ dataC.Reset();
+ childActor.Unparent();
+ dataP.Check(false, TEST_LOCATION);
+ dataC.Check(true, childActor, false, TEST_LOCATION);
+
+ dataP.Reset();
+ dataC.Reset();
+ childActor.SetProperty(Actor::Property::VISIBLE, false);
+ dataP.Check(false, TEST_LOCATION);
+ dataC.Check(false, TEST_LOCATION);
+
+ dataP.Reset();
+ dataC.Reset();
+ parentActor.Add(childActor);
+ dataP.Check(false, TEST_LOCATION);
+ dataC.Check(false, TEST_LOCATION);
+
+ dataP.Reset();
+ dataC.Reset();
+ childActor.SetProperty(Actor::Property::VISIBLE, true);
+ dataP.Check(false, TEST_LOCATION);
+ dataC.Check(true, childActor, true, TEST_LOCATION);
+
+ dataP.Reset();
+ dataC.Reset();
+ parentActor.SetProperty(Actor::Property::VISIBLE, false);
+ dataP.Check(true, parentActor, false, TEST_LOCATION);
+ dataC.Check(true, childActor, false, TEST_LOCATION);
+
+ dataP.Reset();
+ dataC.Reset();
+ childActor.Unparent();
+ dataP.Check(false, TEST_LOCATION);
+ dataC.Check(false, TEST_LOCATION);
+
+ dataP.Reset();
+ dataC.Reset();
+ parentActor.SetProperty(Actor::Property::VISIBLE, true);
+ dataP.Check(true, parentActor, true, TEST_LOCATION);
+ dataC.Check(false, TEST_LOCATION);
+
+ dataP.Reset();
+ dataC.Reset();
+ parentActor.Add(childActor);
+ dataP.Check(false, TEST_LOCATION);
+ dataC.Check(true, childActor, true, TEST_LOCATION);
+
+ dataP.Reset();
+ dataC.Reset();
+ parentActor.Remove(childActor);
+ dataP.Check(false, TEST_LOCATION);
+ dataC.Check(true, childActor, false, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int utcDaliActorInheritedVisibilityChangeSignal3(void)
+{
+ TestApplication application;
+ tet_infoline("Check that the inherited visibility change signal is called when the visibility changes for the parent actor");
+
+ Actor parentActor = Actor::New();
+ Actor actor = Actor::New();
+ parentActor.Add(actor);
+
+ InheritedVisibilityChangedFunctorData data;
+ actor.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(data));
+
+ application.GetScene().Add(parentActor);
+ data.Check(true, actor, true, TEST_LOCATION);
+
+ // Case 1
+ // Parent true -> false : called
+ // actor true -> false : not called
+ // actor false -> true : not called
+ data.Reset();
+ parentActor.SetProperty(Actor::Property::VISIBLE, false);
+ data.Check(true, actor, false, TEST_LOCATION);
+
+ data.Reset();
+ actor.SetProperty(Actor::Property::VISIBLE, false);
+ data.Check(false, TEST_LOCATION);
+
+ data.Reset();
+ actor.SetProperty(Actor::Property::VISIBLE, true);
+ data.Check(false, TEST_LOCATION);
+
+
+ // Prepare Case 2
+ // Parent : false
+ // actor : false
+ data.Reset();
+ actor.SetProperty(Actor::Property::VISIBLE, false);
+ data.Check(false, TEST_LOCATION);
+
+ // Case 2
+ // actor : false
+ // parent false -> true : not called
+ data.Reset();
+ parentActor.SetProperty(Actor::Property::VISIBLE, true);
+ data.Check(false, TEST_LOCATION);
+
+
+ // Prepare Case 3
+ // parent : false
+ // actor : true
+ data.Reset();
+ parentActor.SetProperty(Actor::Property::VISIBLE, false);
+ data.Check(false, TEST_LOCATION);
+
+ data.Reset();
+ actor.SetProperty(Actor::Property::VISIBLE, true);
+ data.Check(false, TEST_LOCATION);
+
+ // Case 3
+ // actor : true
+ // parent false -> true : called
+ parentActor.SetProperty(Actor::Property::VISIBLE, true);
+ data.Check(true, actor, true, TEST_LOCATION);
+
+ END_TEST;
+}
+
+namespace
+{
+ InheritedVisibilityChangedFunctorData dataPA, dataPB, dataCA, dataCB, dataCC;
+ void ResetInheritedVisibilityChangedFunctorData()
+ {
+ dataPA.Reset();
+ dataPB.Reset();
+ dataCA.Reset();
+ dataCB.Reset();
+ dataCC.Reset();
+ }
+}
+
+int utcDaliActorInheritedVisibilityChangeSignal4(void)
+{
+ TestApplication application;
+ tet_infoline("Check that the inherited visibility change signal is in tree");
+
+ /**
+ * ParentA
+ * |
+ * ParentB
+ * |
+ * ChildA ChildB ChildC
+ */
+
+ Actor parentA = Actor::New();
+ Actor parentB = Actor::New();
+ Actor childA = Actor::New();
+ Actor childB = Actor::New();
+ Actor childC = Actor::New();
+ parentA.Add(parentB);
+ parentB.Add(childA);
+ parentB.Add(childB);
+ parentB.Add(childC);
+
+ parentA.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(dataPA));
+ parentB.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(dataPB));
+ childA.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(dataCA));
+ childB.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(dataCB));
+ childC.InheritedVisibilityChangedSignal().Connect(&application, InheritedVisibilityChangedFunctor(dataCC));
+
+ ResetInheritedVisibilityChangedFunctorData();
+ application.GetScene().Add(parentA);
+ dataPA.Check(true, parentA, true, TEST_LOCATION);
+ dataPB.Check(true, parentB, true, TEST_LOCATION);
+ dataCA.Check(true, childA, true, TEST_LOCATION);
+ dataCB.Check(true, childB, true, TEST_LOCATION);
+ dataCC.Check(true, childC, true, TEST_LOCATION);
+
+ ResetInheritedVisibilityChangedFunctorData();
+ parentA.SetProperty(Actor::Property::VISIBLE, false);
+ dataPA.Check(true, parentA, false, TEST_LOCATION);
+ dataPB.Check(true, parentB, false, TEST_LOCATION);
+ dataCA.Check(true, childA, false, TEST_LOCATION);
+ dataCB.Check(true, childB, false, TEST_LOCATION);
+ dataCC.Check(true, childC, false, TEST_LOCATION);
+
+ ResetInheritedVisibilityChangedFunctorData();
+ childA.SetProperty(Actor::Property::VISIBLE, false);
+ dataPA.Check(false, TEST_LOCATION);
+ dataPB.Check(false, TEST_LOCATION);
+ dataCA.Check(false, TEST_LOCATION);
+ dataCB.Check(false, TEST_LOCATION);
+ dataCC.Check(false, TEST_LOCATION);
+
+ ResetInheritedVisibilityChangedFunctorData();
+ parentB.SetProperty(Actor::Property::VISIBLE, false);
+ dataPA.Check(false, TEST_LOCATION);
+ dataPB.Check(false, TEST_LOCATION);
+ dataCA.Check(false, TEST_LOCATION);
+ dataCB.Check(false, TEST_LOCATION);
+ dataCC.Check(false, TEST_LOCATION);
+
+ ResetInheritedVisibilityChangedFunctorData();
+ parentA.SetProperty(Actor::Property::VISIBLE, true);
+ dataPA.Check(true, parentA, true, TEST_LOCATION);
+ dataPB.Check(false, TEST_LOCATION);
+ dataCA.Check(false, TEST_LOCATION);
+ dataCB.Check(false, TEST_LOCATION);
+ dataCC.Check(false, TEST_LOCATION);
+
+ ResetInheritedVisibilityChangedFunctorData();
+ parentB.SetProperty(Actor::Property::VISIBLE, true);
+ dataPA.Check(false, TEST_LOCATION);
+ dataPB.Check(true, parentB, true, TEST_LOCATION);
+ dataCA.Check(false, TEST_LOCATION);
+ dataCB.Check(true, childB, true, TEST_LOCATION);
+ dataCC.Check(true, childC, true, TEST_LOCATION);
+
+ END_TEST;
+}
+
static void LayoutDirectionChanged(Actor actor, LayoutDirection::Type type)
{
gLayoutDirectionType = type;
mBakeColorCallSuccess = updateProxy.BakeColor(mActorId, vec4);
mBakeScaleCallSuccess = updateProxy.BakeScale(mActorId, vec3);
- mGetOrientationCallSuccess = updateProxy.GetOrientation(mActorId, quat);
- mSetOrientationCallSuccess = updateProxy.SetOrientation(mActorId, quat);
- mBakeOrientationCallSuccess = updateProxy.BakeOrientation(mActorId, quat);
- mGetWorldTransformCallSuccess = updateProxy.GetWorldTransformAndSize(mActorId, vec3, vec3, quat, vec3);
- mGetUpdateAreaCallSuccess = updateProxy.GetUpdateArea(mActorId, vec4);
- mSetUpdateAreaCallSuccess = updateProxy.SetUpdateArea(mActorId, vec4);
+ mGetOrientationCallSuccess = updateProxy.GetOrientation(mActorId, quat);
+ mSetOrientationCallSuccess = updateProxy.SetOrientation(mActorId, quat);
+ mBakeOrientationCallSuccess = updateProxy.BakeOrientation(mActorId, quat);
+ mGetWorldTransformCallSuccess = updateProxy.GetWorldTransformAndSize(mActorId, vec3, vec3, quat, vec3);
+ mGetUpdateAreaCallSuccess = updateProxy.GetUpdateArea(mActorId, vec4);
+ mSetUpdateAreaCallSuccess = updateProxy.SetUpdateArea(mActorId, vec4);
return false;
}
mBakeColorCallSuccess = false;
mBakeScaleCallSuccess = false;
- mSetOrientationCallSuccess = false;
- mGetOrientationCallSuccess = false;
- mBakeOrientationCallSuccess = false;
+ mSetOrientationCallSuccess = false;
+ mGetOrientationCallSuccess = false;
+ mBakeOrientationCallSuccess = false;
- mGetWorldTransformCallSuccess = false;
- mGetUpdateAreaCallSuccess = false;
- mSetUpdateAreaCallSuccess = false;
+ mGetWorldTransformCallSuccess = false;
+ mGetUpdateAreaCallSuccess = false;
+ mSetUpdateAreaCallSuccess = false;
}
const uint32_t mActorId;
application.SendNotification();
application.Render();
- DALI_TEST_EQUALS(application.GetUpdateStatus(), Integration::KeepUpdating::STAGE_KEEP_RENDERING, TEST_LOCATION);
+ DALI_TEST_EQUALS(application.GetUpdateStatus(), Integration::KeepUpdating::FRAME_UPDATE_CALLBACK, TEST_LOCATION);
END_TEST;
}
END_TEST;
}
+int UtcDaliPanGestureRecognizerUpdateParamsMinNum(void)
+{
+ TestApplication application;
+
+ Integration::SetPanGestureMinimumPanEvents(8);
+
+ PanGestureDetector detector = PanGestureDetector::New();
+
+ 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();
+
+ detector.Attach(actor);
+
+ SignalData data;
+ GestureReceivedFunctor functor(data);
+ detector.DetectedSignal().Connect(&application, functor);
+
+ application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 40.0f), 251));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 60.0f), 352));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 70.0f), 453));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 80.0f), 554));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 90.0f), 655));
+
+ application.SendNotification();
+
+ DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+ application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 90.0f), 756));
+ application.SendNotification();
+ data.Reset();
+
+ Integration::SetPanGestureMinimumPanEvents(10);
+
+ application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 40.0f), 251));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 60.0f), 352));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 70.0f), 453));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 80.0f), 554));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 90.0f), 655));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 100.0f), 756));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 110.0f), 857));
+
+ application.SendNotification();
+
+ DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+ END_TEST;
+}
+
+
int UtcDaliPanGestureRecognizerNewParamsMinDistance(void)
{
TestApplication application;
END_TEST;
}
+
+int UtcDaliPanGestureRecognizerUpdateParamsMinDistance(void)
+{
+ TestApplication application;
+
+ Integration::SetPanGestureMinimumDistance(100);
+
+ PanGestureDetector detector = PanGestureDetector::New();
+
+ 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();
+
+ detector.Attach(actor);
+
+ SignalData data;
+ GestureReceivedFunctor functor(data);
+ detector.DetectedSignal().Connect(&application, functor);
+
+ application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 40.0f), 251));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 60.0f), 352));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 70.0f), 453));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 80.0f), 554));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 90.0f), 655));
+
+ application.SendNotification();
+
+ DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+ application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 90.0f), 756));
+ application.SendNotification();
+ data.Reset();
+
+ Integration::SetPanGestureMinimumDistance(130);
+
+ application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 150));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 40.0f), 251));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 60.0f), 352));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 70.0f), 453));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 80.0f), 554));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 90.0f), 655));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 100.0f),756));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 110.0f),857));
+ application.ProcessEvent(GenerateSingleTouch(PointState::MOTION, Vector2(20.0f, 120.0f),858));
+
+ application.SendNotification();
+
+ DALI_TEST_EQUALS(false, data.functorCalled, TEST_LOCATION);
+
+ END_TEST;
+}
END_TEST;
}
+int UtcDaliRenderTaskGetStopperActorP(void)
+{
+ TestApplication application;
+
+ tet_infoline("Testing RenderTask::GetStopperActor() Create a new render task, Add a new actor to the stage and set RenderTask::RenderUntil(actor). Get its stopper actor and check it is equivalent to what was set.");
+
+ RenderTaskList taskList = application.GetScene().GetRenderTaskList();
+ RenderTask task = taskList.CreateTask();
+ Actor actor = Actor::New();
+ application.GetScene().Add(actor);
+ task.RenderUntil(actor);
+
+ DALI_TEST_EQUALS(actor, task.GetStopperActor(), TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliRenderTaskGetStopperActorN(void)
+{
+ TestApplication application;
+
+ tet_infoline("Testing RenderTask::GetStopperActor() Try with empty handle");
+
+ RenderTask task;
+
+ try
+ {
+ Actor actor = task.GetStopperActor();
+ }
+ catch(Dali::DaliException& e)
+ {
+ DALI_TEST_PRINT_ASSERT(e);
+ DALI_TEST_ASSERT(e, "RenderTask handle is empty", TEST_LOCATION);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliRenderTaskRenderUntil(void)
+{
+ TestApplication application;
+ tet_infoline("Testing RenderTask::RenderUntil(actor) Check that rendering stops at the actor.");
+
+ // Make a new render task and compose a tree.
+ RenderTaskList taskList = application.GetScene().GetRenderTaskList();
+ RenderTask task = taskList.GetTask(0u);
+
+ Integration::Scene stage = application.GetScene();
+
+ Actor secondChild;
+ for(int i = 0; i < 5; i++)
+ {
+ Actor parent = CreateRenderableActor();
+ parent.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
+ parent.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ Actor child = CreateRenderableActor();
+ child.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
+
+ stage.Add(parent);
+ parent.Add(child);
+
+ if (i == 1)
+ {
+ secondChild = child;
+ }
+ }
+ task.RenderUntil(secondChild);
+
+ // Update & Render with the actor on-stage
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& drawTrace = gl.GetDrawTrace();
+ drawTrace.Enable(true);
+
+ // Update & Render
+ application.SendNotification();
+ application.Render();
+
+ // Check that rendering was cut.
+ DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 3, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliRenderTaskSetExclusive(void)
{
TestApplication application;
uint32_t updateStatus = application.GetUpdateStatus();
- DALI_TEST_CHECK(!(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING));
+ DALI_TEST_CHECK(!(updateStatus & (Integration::KeepUpdating::STAGE_KEEP_RENDERING | Integration::KeepUpdating::RENDERER_CONTINUOUSLY)));
TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
TraceCallStack& drawTrace = glAbstraction.GetDrawTrace();
updateStatus = application.GetUpdateStatus();
- DALI_TEST_CHECK(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING);
+ DALI_TEST_CHECK(updateStatus & Integration::KeepUpdating::RENDERER_CONTINUOUSLY);
value = renderer.GetCurrentProperty(DevelRenderer::Property::RENDERING_BEHAVIOR);
DALI_TEST_CHECK(value.Get(renderingBehavior));
updateStatus = application.GetUpdateStatus();
- DALI_TEST_CHECK(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING);
+ DALI_TEST_CHECK(updateStatus & Integration::KeepUpdating::RENDERER_CONTINUOUSLY);
DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION);
updateStatus = application.GetUpdateStatus();
- DALI_TEST_CHECK(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING);
+ DALI_TEST_CHECK(updateStatus & Integration::KeepUpdating::RENDERER_CONTINUOUSLY);
DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION);
}
updateStatus = application.GetUpdateStatus();
- DALI_TEST_CHECK(!(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING));
+ DALI_TEST_CHECK(!(updateStatus & (Integration::KeepUpdating::STAGE_KEEP_RENDERING | Integration::KeepUpdating::RENDERER_CONTINUOUSLY)));
END_TEST;
}
uint32_t updateStatus = application.GetUpdateStatus();
- DALI_TEST_CHECK(!(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING));
+ DALI_TEST_CHECK(!(updateStatus & (Integration::KeepUpdating::STAGE_KEEP_RENDERING | Integration::KeepUpdating::RENDERER_CONTINUOUSLY)));
// Update for several frames
application.SendNotification();
updateStatus = application.GetUpdateStatus();
- DALI_TEST_CHECK(!(updateStatus & Integration::KeepUpdating::STAGE_KEEP_RENDERING));
+ DALI_TEST_CHECK(!(updateStatus & (Integration::KeepUpdating::STAGE_KEEP_RENDERING | Integration::KeepUpdating::RENDERER_CONTINUOUSLY)));
DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION);
STAGE_KEEP_RENDERING = 1 << 1, ///< - Stage::KeepRendering() is being used
ANIMATIONS_RUNNING = 1 << 2, ///< - Animations are ongoing
MONITORING_PERFORMANCE = 1 << 3, ///< - The --enable-performance-monitor option is being used
- RENDER_TASK_SYNC = 1 << 4 ///< - A render task is waiting for render sync
+ RENDER_TASK_SYNC = 1 << 4, ///< - A render task is waiting for render sync
+ FRAME_UPDATE_CALLBACK = 1 << 5, ///< - Some FrameUpdateCallback return true
+ RENDERER_CONTINUOUSLY = 1 << 6 ///< - Some Renderer renderinb behaviour is continuously
};
}
${platform_abstraction_src_dir}/graphics-sync-abstraction.h
${platform_abstraction_src_dir}/input-options.h
${platform_abstraction_src_dir}/lockless-buffer.h
+ ${platform_abstraction_src_dir}/ordered-set.h
${platform_abstraction_src_dir}/pixel-data-integ.h
${platform_abstraction_src_dir}/platform-abstraction.h
${platform_abstraction_src_dir}/profiling.h
-#ifndef DALI_INTERNAL_ORDERED_SET_H
-#define DALI_INTERNAL_ORDERED_SET_H
+#ifndef DALI_INTEGRATION_ORDERED_SET_H
+#define DALI_INTEGRATION_ORDERED_SET_H
/*
- * Copyright (c) 2023 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.
namespace Dali
{
-namespace Internal
+namespace Integration
{
/**
* @brief Container of data which has strong point to Find & Erase.
* It will be useful when we need to iterate the order of data insertion.
* and need to check whether some object is exist or not very fast.
* @note Since the data's memory is not continuos, iteration is slower than normal vector contianer.
+ * @note Currently, we only support to hold pointer type data.
*
* @tparam T The type of class
* @tparam owned True if data is owned, So we will automatcally release the memory
MapContainer mMap{}; ///< Helper cache map to find item fast.
ListContainer mList{}; ///< Ordered by PushBack API called. Actual ownership will be stored here.
};
-} // namespace Internal
-
+} // namespace Integration
} // namespace Dali
-#endif // DALI_INTERNAL_ORDERED_SET_H
+#endif // DALI_INTEGRATION_ORDERED_SET_H
// Signals
-static constexpr std::string_view SIGNAL_HOVERED = "hovered";
-static constexpr std::string_view SIGNAL_WHEEL_EVENT = "wheelEvent";
-static constexpr std::string_view SIGNAL_ON_SCENE = "onScene";
-static constexpr std::string_view SIGNAL_OFF_SCENE = "offScene";
-static constexpr std::string_view SIGNAL_ON_RELAYOUT = "onRelayout";
-static constexpr std::string_view SIGNAL_TOUCHED = "touched";
-static constexpr std::string_view SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
-static constexpr std::string_view SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
-static constexpr std::string_view SIGNAL_CHILD_ADDED = "childAdded";
-static constexpr std::string_view SIGNAL_CHILD_REMOVED = "childRemoved";
+static constexpr std::string_view SIGNAL_HOVERED = "hovered";
+static constexpr std::string_view SIGNAL_WHEEL_EVENT = "wheelEvent";
+static constexpr std::string_view SIGNAL_ON_SCENE = "onScene";
+static constexpr std::string_view SIGNAL_OFF_SCENE = "offScene";
+static constexpr std::string_view SIGNAL_ON_RELAYOUT = "onRelayout";
+static constexpr std::string_view SIGNAL_TOUCHED = "touched";
+static constexpr std::string_view SIGNAL_VISIBILITY_CHANGED = "visibilityChanged";
+static constexpr std::string_view SIGNAL_INHERITED_VISIBILITY_CHANGED = "inheritedVisibilityChanged";
+static constexpr std::string_view SIGNAL_LAYOUT_DIRECTION_CHANGED = "layoutDirectionChanged";
+static constexpr std::string_view SIGNAL_CHILD_ADDED = "childAdded";
+static constexpr std::string_view SIGNAL_CHILD_REMOVED = "childRemoved";
// Actions
{
actor->VisibilityChangedSignal().Connect(tracker, functor);
}
+ else if(name == SIGNAL_INHERITED_VISIBILITY_CHANGED)
+ {
+ actor->InheritedVisibilityChangedSignal().Connect(tracker, functor);
+ }
else if(name == SIGNAL_LAYOUT_DIRECTION_CHANGED)
{
actor->LayoutDirectionChangedSignal().Connect(tracker, functor);
SignalConnectorType signalConnector6(mType, std::string(SIGNAL_ON_RELAYOUT), &DoConnectSignal);
SignalConnectorType signalConnector7(mType, std::string(SIGNAL_TOUCHED), &DoConnectSignal);
SignalConnectorType signalConnector8(mType, std::string(SIGNAL_VISIBILITY_CHANGED), &DoConnectSignal);
-SignalConnectorType signalConnector9(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &DoConnectSignal);
-SignalConnectorType signalConnector10(mType, std::string(SIGNAL_CHILD_ADDED), &DoConnectSignal);
-SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_REMOVED), &DoConnectSignal);
+SignalConnectorType signalConnector9(mType, std::string(SIGNAL_INHERITED_VISIBILITY_CHANGED), &DoConnectSignal);
+SignalConnectorType signalConnector10(mType, std::string(SIGNAL_LAYOUT_DIRECTION_CHANGED), &DoConnectSignal);
+SignalConnectorType signalConnector11(mType, std::string(SIGNAL_CHILD_ADDED), &DoConnectSignal);
+SignalConnectorType signalConnector12(mType, std::string(SIGNAL_CHILD_REMOVED), &DoConnectSignal);
TypeAction a1(mType, std::string(ACTION_SHOW), &DoAction);
TypeAction a2(mType, std::string(ACTION_HIDE), &DoAction);
EmitSignal(*this, mVisibilityChangedSignal, visible, type);
}
+void Actor::EmitInheritedVisibilityChangedSignal(bool visible)
+{
+ EmitSignal(*this, mInheritedVisibilityChangedSignal, visible);
+}
+
void Actor::EmitLayoutDirectionChangedSignal(LayoutDirection::Type type)
{
EmitSignal(*this, mLayoutDirectionChangedSignal, type);
mOffSceneSignal(),
mOnRelayoutSignal(),
mVisibilityChangedSignal(),
+ mInheritedVisibilityChangedSignal(),
mLayoutDirectionChangedSignal(),
mHitTestResultSignal(),
mTargetOrientation(Quaternion::IDENTITY),
void Actor::SetParent(ActorParent* parent, bool notify)
{
+ bool emitInheritedVisible = false;
+ bool visiblility = true;
if(parent)
{
DALI_ASSERT_ALWAYS(!mParent && "Actor cannot have 2 parents");
{
// Instruct each actor to create a corresponding node in the scene graph
ConnectToScene(parentActor->GetHierarchyDepth(), parentActor->GetLayer3DParentCount(), notify);
+
+ Actor* actor = this;
+ emitInheritedVisible = true;
+ while(emitInheritedVisible && actor)
+ {
+ emitInheritedVisible &= actor->GetProperty(Dali::Actor::Property::VISIBLE).Get<bool>();
+ actor = actor->GetParent();
+ }
}
// Resolve the name and index for the child properties if any
{
DALI_ASSERT_ALWAYS(mParent != nullptr && "Actor should have a parent");
+ if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
+ OnScene())
+ {
+ Actor* actor = this;
+ emitInheritedVisible = true;
+ while(emitInheritedVisible && actor)
+ {
+ emitInheritedVisible &= actor->GetProperty(Dali::Actor::Property::VISIBLE).Get<bool>();
+ actor = actor->GetParent();
+ }
+ visiblility = false;
+ }
+
mParent = nullptr;
if(!EventThreadServices::IsShuttingDown() && // Don't emit signals or send messages during Core destruction
mScene = nullptr;
}
+
+ if(emitInheritedVisible)
+ {
+ EmitInheritedVisibilityChangedSignalRecursively(visiblility);
+ }
}
Rect<> Actor::CalculateScreenExtents() const
RequestRenderingMessage(GetEventThreadServices().GetUpdateManager());
}
+ Actor* actor = this->GetParent();
+ bool emitInheritedVisible = OnScene();
+ while(emitInheritedVisible && actor)
+ {
+ emitInheritedVisible &= actor->GetProperty(Dali::Actor::Property::VISIBLE).Get<bool>();
+ actor = actor->GetParent();
+ }
+
mVisible = visible;
// Emit the signal on this actor and all its children
mParentImpl.EmitVisibilityChangedSignalRecursively(visible, DevelActor::VisibilityChange::SELF);
+ if(emitInheritedVisible)
+ {
+ EmitInheritedVisibilityChangedSignalRecursively(visible);
+ }
+ }
+}
+
+void Actor::EmitInheritedVisibilityChangedSignalRecursively(bool visible)
+{
+ ActorContainer inheritedVisibilityChangedList;
+ mParentImpl.InheritVisibilityRecursively(inheritedVisibilityChangedList);
+ // Notify applications about the newly connected actors.
+ for(const auto& actor : inheritedVisibilityChangedList)
+ {
+ actor->EmitInheritedVisibilityChangedSignal(visible);
}
}
void EmitVisibilityChangedSignal(bool visible, DevelActor::VisibilityChange::Type type);
/**
+ * @brief Emits the inherited visibility change signal for this actor.
+ * @param[in] visible Whether the actor has become visible or not considering all parent Actors.
+ */
+ void EmitInheritedVisibilityChangedSignal(bool visible);
+
+ /**
* @brief Emits the layout direction change signal for this actor and all its children.
* @param[in] type Whether the actor's layout direction property has changed or a parent's.
*/
}
/**
+ * @copydoc DevelActor::InheritedVisibilityChangedSignal
+ */
+ Dali::Actor::InheritedVisibilityChangedSignalType& InheritedVisibilityChangedSignal()
+ {
+ return mInheritedVisibilityChangedSignal;
+ }
+
+ /**
* @copydoc LayoutDirectionChangedSignal
*/
Dali::Actor::LayoutDirectionChangedSignalType& LayoutDirectionChangedSignal()
void SetVisibleInternal(bool visible, SendMessage::Type sendMessage);
/**
+ * Emits the visibility flag of an actor.
+ * @param[in] visible The new visibility flag.
+ * @param[in] sendMessage Whether to send a message to the update thread or not.
+ */
+ void EmitInheritedVisibilityChangedSignalRecursively(bool visible);
+
+ /**
* @copydoc ActorParent::SetSiblingOrderOfChild
*/
void SetSiblingOrderOfChild(Actor& child, uint32_t order) override;
ActorGestureData* mGestureData; ///< Optional Gesture data. Only created when actor requires gestures
// Signals
- Dali::Actor::TouchEventSignalType mInterceptTouchedSignal;
- Dali::Actor::TouchEventSignalType mTouchedSignal;
- Dali::Actor::HoverSignalType mHoveredSignal;
- Dali::Actor::WheelEventSignalType mInterceptWheelSignal;
- Dali::Actor::WheelEventSignalType mWheelEventSignal;
- Dali::Actor::OnSceneSignalType mOnSceneSignal;
- Dali::Actor::OffSceneSignalType mOffSceneSignal;
- Dali::Actor::OnRelayoutSignalType mOnRelayoutSignal;
- DevelActor::VisibilityChangedSignalType mVisibilityChangedSignal;
- Dali::Actor::LayoutDirectionChangedSignalType mLayoutDirectionChangedSignal;
- Dali::Actor::TouchEventSignalType mHitTestResultSignal;
+ Dali::Actor::TouchEventSignalType mInterceptTouchedSignal;
+ Dali::Actor::TouchEventSignalType mTouchedSignal;
+ Dali::Actor::HoverSignalType mHoveredSignal;
+ Dali::Actor::WheelEventSignalType mInterceptWheelSignal;
+ Dali::Actor::WheelEventSignalType mWheelEventSignal;
+ Dali::Actor::OnSceneSignalType mOnSceneSignal;
+ Dali::Actor::OffSceneSignalType mOffSceneSignal;
+ Dali::Actor::OnRelayoutSignalType mOnRelayoutSignal;
+ DevelActor::VisibilityChangedSignalType mVisibilityChangedSignal;
+ Dali::Actor::InheritedVisibilityChangedSignalType mInheritedVisibilityChangedSignal;
+ Dali::Actor::LayoutDirectionChangedSignalType mLayoutDirectionChangedSignal;
+ Dali::Actor::TouchEventSignalType mHitTestResultSignal;
Quaternion mTargetOrientation; ///< Event-side storage for orientation
Vector4 mTargetColor; ///< Event-side storage for color
/*
- * Copyright (c) 2023 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.
ActorIter end = mChildren->end();
for(ActorIter iter = mChildren->begin(); iter != end; ++iter)
{
- ActorPtr actor = (*iter);
-
- if(actor.Get() == &child)
+ if((*iter).Get() == &child)
{
// Keep handle for OnChildRemove notification
- removed = actor;
+ removed = (*iter);
// Do this first, since user callbacks from within SetParent() may need to add the child
mChildren->erase(iter);
- DALI_ASSERT_DEBUG(actor->GetParent() == &mOwner);
- actor->SetParent(nullptr, notify);
+ DALI_ASSERT_DEBUG(removed->GetParent() == &mOwner);
+ removed->SetParent(nullptr, notify);
break;
}
auto iter = std::find(mChildren->begin(), mChildren->end(), &child);
if(iter != mChildren->end())
{
+ ActorPtr childPtr(&child); // ensure actor remains referenced.
+
mChildren->erase(iter);
- mChildren->push_back(ActorPtr(&child));
+ mChildren->push_back(childPtr);
changed = true;
}
}
bool changed = false;
if(mChildren && !mChildren->empty() && mChildren->front() != &child) // If not already at bottom,
{
- ActorPtr childPtr(&child); // ensure actor remains referenced.
-
auto iter = std::find(mChildren->begin(), mChildren->end(), &child);
if(iter != mChildren->end())
{
+ ActorPtr childPtr(&child); // ensure actor remains referenced.
+
mChildren->erase(iter);
mChildren->insert(mChildren->begin(), childPtr);
changed = true;
bool raised = false;
if(mChildren && !mChildren->empty() && mChildren->back() != &child && target.GetParent() == child.GetParent()) // If not already at top
{
- ActorPtr childPtr(&child); // ensure actor actor remains referenced.
-
auto targetIter = std::find(mChildren->begin(), mChildren->end(), &target);
auto childIter = std::find(mChildren->begin(), mChildren->end(), &child);
if(childIter < targetIter)
{
+ ActorPtr childPtr(&child); // ensure actor actor remains referenced.
+
mChildren->erase(childIter);
// Erasing early invalidates the targetIter. (Conversely, inserting first may also
// invalidate actorIter)
// If not already at bottom
if(mChildren && !mChildren->empty() && mChildren->front() != &child && target.GetParent() == child.GetParent())
{
- ActorPtr childPtr(&child); // ensure actor actor remains referenced.
-
auto targetIter = std::find(mChildren->begin(), mChildren->end(), &target);
auto childIter = std::find(mChildren->begin(), mChildren->end(), &child);
if(childIter > targetIter)
{
+ ActorPtr childPtr(&child); // ensure actor actor remains referenced.
+
mChildren->erase(childIter); // actor only invalidates iterators at or after actor point.
mChildren->insert(targetIter, childPtr);
}
}
}
+void ActorParentImpl::InheritVisibilityRecursively(ActorContainer& inheritedVisibilityChangedList)
+{
+ inheritedVisibilityChangedList.push_back(ActorPtr(&mOwner));
+
+ if(mChildren)
+ {
+ for(const auto& child : *mChildren)
+ {
+ if(child->GetProperty(Dali::Actor::Property::VISIBLE).Get<bool>())
+ {
+ child->mParentImpl.InheritVisibilityRecursively(inheritedVisibilityChangedList);
+ }
+ }
+ }
+}
+
void ActorParentImpl::EmitChildAddedSignal(Actor& child)
{
EmitSignal(child, mChildAddedSignal);
void EmitVisibilityChangedSignalRecursively(bool visible,
DevelActor::VisibilityChange::Type type);
+ /**
+ * @brief Propagates the actor's visibility on the actor tree, and retreives actor list to emit inherited-visibility-changed-signal.
+ *
+ * @param[out] inheritedVisibilityChangedList On return, the list of actors whose inherited visibility is changed.
+ */
+ void InheritVisibilityRecursively(ActorContainer& inheritedVisibilityChangedList);
+
private:
/**
* @brief Emits the ChildAdded signal for this actor
#define DALI_INTERNAL_ANIMATION_PLAYLIST_H
/*
- * Copyright (c) 2023 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.
// INTERNAL INCLUDES
#include <dali/devel-api/common/map-wrapper.h>
+#include <dali/integration-api/ordered-set.h>
#include <dali/internal/common/message.h>
-#include <dali/internal/common/ordered-set.h>
#include <dali/internal/event/common/complete-notification-interface.h>
#include <dali/internal/event/common/scene-graph-notifier-interface-mapper.h>
#include <dali/public-api/animation/animation.h>
void NotifyCompleted(CompleteNotificationInterface::ParameterList notifierList) override;
private:
- OrderedSet<Animation, false> mAnimations; ///< All existing animations (not owned)
- std::map<Dali::Animation, uint32_t> mPlaylist; ///< The currently playing animations (owned through handle).
- ///< Note we can hold same handles multiple, since OnClear can be called after NotifyCompleted.
+ Integration::OrderedSet<Animation, false> mAnimations; ///< All existing animations (not owned)
+ std::map<Dali::Animation, uint32_t> mPlaylist; ///< The currently playing animations (owned through handle).
+ ///< Note we can hold same handles multiple, since OnClear can be called after NotifyCompleted.
};
/**
#define DALI_INTERNAL_PROPERTY_NOTIFICATION_MANAGER_H
/*
- * Copyright (c) 2023 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.
#include <unordered_map>
// INTERNAL INCLUDES
-#include <dali/internal/common/ordered-set.h>
+#include <dali/integration-api/ordered-set.h>
#include <dali/internal/event/common/property-notifier.h>
#include <dali/internal/event/common/scene-graph-notifier-interface-mapper.h>
#include <dali/public-api/common/dali-vector.h>
PropertyNotificationManager& operator=(const PropertyNotificationManager& rhs);
private:
- OrderedSet<PropertyNotification, false> mPropertyNotifications; ///< All existing PropertyNotifications (not owned)
+ Integration::OrderedSet<PropertyNotification, false> mPropertyNotifications; ///< All existing PropertyNotifications (not owned)
};
} // namespace Internal
void GestureEventProcessor::SetPanGestureMinimumDistance(int32_t value)
{
envOptionMinimumPanDistance = value;
+ mPanGestureProcessor.SetMinimumDistance(value);
}
void GestureEventProcessor::SetPanGestureMinimumPanEvents(int32_t value)
{
envOptionMinimumPanEvents = value;
+ mPanGestureProcessor.SetMinimumPanEvents(value);
}
void GestureEventProcessor::SetPinchGestureMinimumDistance(float value)
mSceneObject->SetMultitapSmoothingRange(value);
}
+void PanGestureProcessor::SetMinimumDistance(int32_t value)
+{
+ if(mGestureRecognizer)
+ {
+ PanGestureRecognizer* panRecognizer = dynamic_cast<PanGestureRecognizer*>(mGestureRecognizer.Get());
+ if(panRecognizer)
+ {
+ panRecognizer->SetMinimumDistance(value);
+ }
+ }
+}
+
+void PanGestureProcessor::SetMinimumPanEvents(int32_t value)
+{
+ if(mGestureRecognizer)
+ {
+ PanGestureRecognizer* panRecognizer = dynamic_cast<PanGestureRecognizer*>(mGestureRecognizer.Get());
+ if(panRecognizer)
+ {
+ panRecognizer->SetMinimumPanEvents(value);
+ }
+ }
+}
+
+
const SceneGraph::PanGesture& PanGestureProcessor::GetSceneObject() const
{
return *mSceneObject;
*/
void SetMultitapSmoothingRange(int value);
+ /**
+ * This method sets the minimum distance to start a pan
+ * @param[in] value The distance in pixels
+ */
+ void SetMinimumDistance(int32_t value);
+
+ /**
+ * Sets the minimum touch events required before a pan can be started
+ * @param[in] value The number of touch events
+ */
+ void SetMinimumPanEvents(int32_t value);
+
public: // for PanGestureDetector
/**
* @return the pan gesture scene object
}
}
+void PanGestureRecognizer::SetMinimumDistance(int32_t minimumDistance)
+{
+ if(minimumDistance >= 0)
+ {
+ mMinimumDistanceSquared = minimumDistance * minimumDistance;
+
+ // Usually, we do not want to apply the threshold straight away, but phased over the first few pans
+ // Set our distance to threshold adjustments ratio here.
+ float fMinimumDistance = static_cast<float>(minimumDistance);
+ mThresholdTotalAdjustments = static_cast<unsigned int>(fMinimumDistance * MINIMUM_MOTION_DISTANCE_TO_THRESHOLD_ADJUSTMENTS_RATIO);
+ }
+}
+
+void PanGestureRecognizer::SetMinimumPanEvents(int32_t minimumPanEvents)
+{
+ if(minimumPanEvents >= 1)
+ {
+ mMinimumMotionEvents = minimumPanEvents - 1; // Down is the first event
+ }
+}
+
} // namespace Internal
} // namespace Dali
public:
/**
+ * This method sets the minimum distance to start a pan
+ * @param[in] minimumDistance The distance in pixels
+ */
+ void SetMinimumDistance(int32_t minimumDistance);
+
+ /**
+ * Sets the minimum touch events required before a pan can be started
+ * @param[in] minimumPanEvents The number of touch events
+ */
+ void SetMinimumPanEvents(int32_t minimumPanEvents);
+
+ /**
* @copydoc Dali::Internal::GestureDetector::SendEvent(const Integration::TouchEvent&)
*/
void SendEvent(const Integration::TouchEvent& event) override;
distanceDelta.y > mMaximumMotionAllowedDistance)
{
event.state = GestureState::CANCELLED;
+ DALI_LOG_RELEASE_INFO("There is a long distance between touch down and touch up. (%f or %f > %f)\n", distanceDelta.x, distanceDelta.y, mMaximumMotionAllowedDistance);
}
EmitTap(time, event);
}
return mSourceActor.GetActor();
}
+Actor* RenderTask::GetStopperActor() const
+{
+ return mStopperActor.GetActor();
+}
+
void RenderTask::SetExclusive(bool exclusive)
{
if(mExclusive != exclusive)
return mRenderTaskId;
}
+void RenderTask::RenderUntil(Actor* actor)
+{
+ Actor* target = mSourceActor.GetActor();
+ DALI_ASSERT_ALWAYS((target && actor)
+ && "RenderTask::RenderUntil() has empty actors.");
+ DALI_ASSERT_ALWAYS((target->GetHierarchyDepth() < actor->GetHierarchyDepth())
+ && "RenderTask::RenderUntil() has reversed hierarchy.");
+
+ Actor* parent = actor;
+ while(parent != target && !(parent->IsLayer()))
+ {
+ parent = parent->GetParent();
+ }
+
+ if(parent == target && GetRenderTaskSceneObject())
+ {
+ mStopperActor.SetActor(actor);
+ SetStopperNodeMessage(GetEventThreadServices(), *GetRenderTaskSceneObject(), &actor->GetNode());
+ }
+}
+
const SceneGraph::RenderTask* RenderTask::GetRenderTaskSceneObject() const
{
return static_cast<const SceneGraph::RenderTask*>(mUpdateObject);
*/
Actor* GetSourceActor() const;
+ Actor* GetStopperActor() const;
+
/**
* @copydoc Dali::RenderTask::SetExclusive()
*/
*/
uint32_t GetRenderTaskId() const;
+ void RenderUntil(Actor* actor);
+
public: // Used by RenderTaskList, which owns the SceneGraph::RenderTasks
/**
* Retrieve the scene-graph RenderTask object.
ActorObserver mSourceActor; ///< Source actor
ActorObserver mCameraActor; ///< Camera actor
ActorObserver mViewportGuideActor; ///< Actor to matching viewport of this render task to this Actor.
+ ActorObserver mStopperActor; ///< A child of mSourceActor. Actor to stop rendering.
WeakHandle<Dali::Actor> mInputMappingActor; /// used to mapping screen to frame buffer coordinate, not kept alive by rendertask
RenderTaskList& mRenderTaskList; ///< The render task list
#define DALI_INTERNAL_MEMORY_POOL_RELAYOUT_CONTAINER_H
/*
- * Copyright (c) 2023 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.
#include <dali/public-api/common/dali-vector.h>
#include <dali/public-api/size-negotiation/relayout-container.h>
+#include <dali/integration-api/ordered-set.h>
#include <dali/internal/common/memory-pool-object-allocator.h>
-#include <dali/internal/common/ordered-set.h>
namespace Dali
{
bool Contains(const Dali::Actor& actor);
private:
- using RelayoutInfoContainer = Dali::Internal::OrderedSet<RelayoutInfo, false, RelayoutInfo::RelayoutInfoHash, RelayoutInfo::RelayoutInfoCompare>;
+ using RelayoutInfoContainer = Dali::Integration::OrderedSet<RelayoutInfo, false, RelayoutInfo::RelayoutInfoHash, RelayoutInfo::RelayoutInfoCompare>;
RelayoutInfoContainer mRelayoutInfos; ///< The list of relayout infos
#define DALI_INTERNAL_RELAYOUT_CONTROLLER_IMPL_H
/*
- * Copyright (c) 2023 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.
#include <memory> // for unique_ptr
// INTERNAL INCLUDES
+#include <dali/integration-api/ordered-set.h>
#include <dali/internal/common/memory-pool-object-allocator.h>
-#include <dali/internal/common/ordered-set.h>
#include <dali/internal/event/size-negotiation/memory-pool-relayout-container.h>
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/object/base-object.h>
void OnObjectDestroyed(const Dali::RefObject* object);
private:
- using RawActorList = Dali::Internal::OrderedSet<Dali::Internal::Actor, false>;
+ using RawActorList = Dali::Integration::OrderedSet<Dali::Internal::Actor, false>;
/**
* @brief Request for relayout. Relays out whole scene.
// INTERNAL INCLUDES
#include <dali/integration-api/core.h>
-#include <dali/internal/common/ordered-set.h>
+#include <dali/integration-api/ordered-set.h>
#include <dali/internal/event/common/scene-impl.h>
std::vector<SceneGraph::Scene*> sceneContainer; ///< List of pointers to the scene graph objects of the scenes
Render::RenderAlgorithms renderAlgorithms; ///< The RenderAlgorithms object is used to action the renders required by a RenderInstruction
- OrderedSet<Render::Sampler> samplerContainer; ///< List of owned samplers
- OrderedSet<Render::FrameBuffer> frameBufferContainer; ///< List of owned framebuffers
- OrderedSet<Render::VertexBuffer> vertexBufferContainer; ///< List of owned vertex buffers
- OrderedSet<Render::Geometry> geometryContainer; ///< List of owned Geometries
- OwnerKeyContainer<Render::Renderer> rendererContainer; ///< List of owned renderers
- OwnerKeyContainer<Render::Texture> textureContainer; ///< List of owned textures
+ Integration::OrderedSet<Render::Sampler> samplerContainer; ///< List of owned samplers
+ Integration::OrderedSet<Render::FrameBuffer> frameBufferContainer; ///< List of owned framebuffers
+ Integration::OrderedSet<Render::VertexBuffer> vertexBufferContainer; ///< List of owned vertex buffers
+ Integration::OrderedSet<Render::Geometry> geometryContainer; ///< List of owned Geometries
+ OwnerKeyContainer<Render::Renderer> rendererContainer; ///< List of owned renderers
+ OwnerKeyContainer<Render::Texture> textureContainer; ///< List of owned textures
- OrderedSet<Render::RenderTracker> mRenderTrackers; ///< List of owned render trackers
+ Integration::OrderedSet<Render::RenderTracker> mRenderTrackers; ///< List of owned render trackers
OwnerKeyContainer<Render::Texture> textureDiscardQueue; ///< Discarded textures
#define DALI_INTERNAL_SCENEGRAPH_PROPERTY_RESETTER_H
/*
- * Copyright (c) 2023 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.
*/
~PropertyResetterBase() override
{
- if(mPropertyOwner != nullptr)
+ if(DALI_LIKELY(mInitialized))
{
- mPropertyOwner->RemoveObserver(*this);
+ if(mPropertyOwner != nullptr)
+ {
+ mPropertyOwner->RemoveObserver(*this);
+ }
}
}
*/
void Initialize()
{
+ DALI_ASSERT_ALWAYS(!mInitialized && "Dont call PropertyResetterBase::Initialize() twice");
+
+ mInitialized = true;
mPropertyOwner->AddObserver(*this);
mPropertyOwner->SetUpdated(true);
}
mBaseProperty(baseProperty),
mRunning(ACTIVE),
mActive(ACTIVE),
+ mInitialized(false),
mDisconnected(false)
{
}
PropertyBase* mBaseProperty; ///< The base property being animated or constrained
int8_t mRunning; ///< Used to determine if we should finish or not, 2 if running, 1 if aging, 0 if stopped
int8_t mActive; ///< 2 if active, 1 if aging, 0 if stopped
- bool mDisconnected; ///< True if the property owner has been disconnected
+ bool mInitialized : 1;
+ bool mDisconnected : 1; ///< True if the property owner has been disconnected
};
class BakerResetter : public PropertyResetterBase
* @param[in] clippingDepth The current scissor clipping depth
* @param[out] clippingUsed Gets set to true if any clipping nodes have been found
* @param[out] keepRendering Gets set to true if rendering should be kept.
+ * @param[out] renderStopped Gets set to true if rendering should be stopped.
*/
void AddRenderablesForTask(BufferIndex updateBufferIndex,
Node& node,
uint32_t clippingDepth,
uint32_t scissorDepth,
bool& clippingUsed,
- bool& keepRendering)
+ bool& keepRendering,
+ bool& renderStopped)
{
+ if(renderStopped)
+ {
+ return;
+ }
+
// Short-circuit for invisible nodes
if(!node.IsVisible(updateBufferIndex))
{
// Recurse children.
NodeContainer& children = node.GetChildren();
const NodeIter endIter = children.End();
- for(NodeIter iter = children.Begin(); iter != endIter; ++iter)
+ for(NodeIter iter = children.Begin(); !renderStopped && iter != endIter; ++iter)
{
Node& child = **iter;
- AddRenderablesForTask(updateBufferIndex, child, parentVisibilityChanged, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth, scissorDepth, clippingUsed, keepRendering);
+ if(child == renderTask.GetStopperNode())
+ {
+ renderStopped = true;
+ break;
+ }
+ AddRenderablesForTask(updateBufferIndex, child, parentVisibilityChanged, *layer, renderTask, inheritedDrawMode, currentClippingId, clippingDepth, scissorDepth, clippingUsed, keepRendering, renderStopped);
}
}
sortedLayer->ClearRenderables();
}
+ bool stopRendering = false;
+
AddRenderablesForTask(updateBufferIndex,
*sourceNode,
false,
0u,
0u,
hasClippingNodes,
- keepRendering);
+ keepRendering,
+ stopRendering);
renderInstructionProcessor.Prepare(updateBufferIndex,
sortedLayers,
mImpl->frameCallbackProcessor || // ..a frame callback processor is existed OR
gestureUpdated; // ..a gesture property was updated
- uint32_t keepUpdating = 0;
- bool keepRendererRendering = false;
- mImpl->renderingRequired = false;
+ uint32_t keepUpdating = 0;
+ mImpl->renderingRequired = false;
// Although the scene-graph may not require an update, we still need to synchronize double-buffered
// values if the scene was updated in the previous frame.
// Call the frame-callback-processor if set
if(mImpl->frameCallbackProcessor)
{
- keepRendererRendering |= mImpl->frameCallbackProcessor->Update(bufferIndex, elapsedSeconds);
+ if(mImpl->frameCallbackProcessor->Update(bufferIndex, elapsedSeconds))
+ {
+ keepUpdating |= KeepUpdating::FRAME_UPDATE_CALLBACK;
+ }
}
// Update node hierarchy, apply constraints,
if(mImpl->renderersAdded)
{
// Calculate how many render tasks we have in total
- std::size_t numberOfRenderTasks = 0;
+ std::size_t numberOfRenderTasks = 0;
+ std::size_t numberOfRenderInstructions = 0;
+ bool renderContinuously = false;
for(auto&& scene : mImpl->scenes)
{
if(scene && scene->taskList)
}
}
- std::size_t numberOfRenderInstructions = 0;
- mImpl->renderInstructionCapacity = 0u;
+ mImpl->renderInstructionCapacity = 0u;
for(auto&& scene : mImpl->scenes)
{
if(scene && scene->root && scene->taskList && scene->scene)
// or keep rendering is requested
if(!isAnimationRunning || animationActive || mImpl->renderingRequired || (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || sceneKeepUpdating)
{
- keepRendererRendering |= mImpl->renderTaskProcessor.Process(bufferIndex,
- *scene->taskList,
- *scene->root,
- scene->sortedLayerList,
- scene->scene->GetRenderInstructions(),
- renderToFboEnabled,
- isRenderingToFbo);
+ renderContinuously |= mImpl->renderTaskProcessor.Process(bufferIndex,
+ *scene->taskList,
+ *scene->root,
+ scene->sortedLayerList,
+ scene->scene->GetRenderInstructions(),
+ renderToFboEnabled,
+ isRenderingToFbo);
mImpl->renderInstructionCapacity += scene->scene->GetRenderInstructions().GetCapacity();
scene->scene->SetSkipRendering(false);
}
}
+ if(renderContinuously)
+ {
+ keepUpdating |= KeepUpdating::RENDERER_CONTINUOUSLY;
+ }
+
DALI_LOG_INFO(gLogFilter, Debug::General, "Update: numberOfRenderTasks(%d), Render Instructions(%d)\n", numberOfRenderTasks, numberOfRenderInstructions);
}
}
// Check whether further updates are required
keepUpdating |= KeepUpdatingCheck(elapsedSeconds);
- if(keepRendererRendering)
- {
- keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
- }
-
- if(keepUpdating & KeepUpdating::STAGE_KEEP_RENDERING)
+ if(keepUpdating & (KeepUpdating::STAGE_KEEP_RENDERING | KeepUpdating::FRAME_UPDATE_CALLBACK | KeepUpdating::RENDERER_CONTINUOUSLY))
{
// Set dirty flags for next frame to continue rendering
mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
new(slot) LocalType(&task, &RenderTask::SetSourceNode, node);
}
+inline void SetStopperNodeMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Node* constNode)
+{
+ // Scene graph thread can destroy this object.
+ Node* node = const_cast<Node*>(constNode);
+
+ using LocalType = MessageValue1<RenderTask, Node*>;
+
+ // Reserve some memory inside the message queue
+ uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
+
+ // Construct message in the message queue memory; note that delete should not be called on the return value
+ new(slot) LocalType(&task, &RenderTask::SetStopperNode, node);
+}
+
inline void SetCameraMessage(EventThreadServices& eventThreadServices, const RenderTask& task, const Camera* constCamera)
{
using LocalType = MessageValue1<RenderTask, Camera*>;
return mSourceNode;
}
+void RenderTask::SetStopperNode(Node* node)
+{
+ mStopperNode = node;
+}
+
+Node* RenderTask::GetStopperNode() const
+{
+ return mStopperNode;
+}
+
void RenderTask::SetViewportGuideNode(Node* node)
{
mViewportGuideNode = node;
*/
Node* GetSourceNode() const;
+ void SetStopperNode(Node* node);
+ Node* GetStopperNode() const;
+
/**
* Set the ViewportGuideNode.
* @param[in] node This node is used to compute viewport of the render task.
RenderMessageDispatcher* mRenderMessageDispatcher;
Render::RenderTracker* mRenderSyncTracker;
Node* mSourceNode;
+ Node* mStopperNode;
SceneGraph::Camera* mCameraNode;
Node* mViewportGuideNode;
Render::FrameBuffer* mFrameBuffer;
return GetImplementation(*this).LayoutDirectionChangedSignal();
}
+Actor::InheritedVisibilityChangedSignalType& Actor::InheritedVisibilityChangedSignal()
+{
+ return GetImplementation(*this).InheritedVisibilityChangedSignal();
+}
+
Actor::Actor(Internal::Actor* internal)
: Handle(internal)
{
* @nosubgrouping
*
* Signals
- * | %Signal Name | Method |
- * |-------------------|------------------------------|
- * | touched | @ref TouchedSignal() |
- * | hovered | @ref HoveredSignal() |
- * | wheelEvent | @ref WheelEventSignal() |
- * | onScene | @ref OnSceneSignal() |
- * | offScene | @ref OffSceneSignal() |
- * | onRelayout | @ref OnRelayoutSignal() |
+ * | %Signal Name | Method |
+ * |----------------------------|-----------------------------------------|
+ * | touched | @ref TouchedSignal() |
+ * | hovered | @ref HoveredSignal() |
+ * | wheelEvent | @ref WheelEventSignal() |
+ * | onScene | @ref OnSceneSignal() |
+ * | offScene | @ref OffSceneSignal() |
+ * | onRelayout | @ref OnRelayoutSignal() |
+ * | layoutDirectionChanged | @ref LayoutDirectionChangedSignal() |
+ * | inheritedVisibilityChanged | @ref InheritedVisibilityChangedSignal() |
*
* Actions
* | %Action Name | %Actor method called |
// Typedefs
- using TouchEventSignalType = Signal<bool(Actor, const TouchEvent&)>; ///< Touch signal type @SINCE_1_1.37
- using HoverSignalType = Signal<bool(Actor, const HoverEvent&)>; ///< Hover signal type @SINCE_1_0.0
- using WheelEventSignalType = Signal<bool(Actor, const WheelEvent&)>; ///< Wheel signal type @SINCE_1_0.0
- using OnSceneSignalType = Signal<void(Actor)>; ///< Scene connection signal type @SINCE_1_9.24
- using OffSceneSignalType = Signal<void(Actor)>; ///< Scene disconnection signal type @SINCE_1_9.24
- using OnRelayoutSignalType = Signal<void(Actor)>; ///< Called when the actor is relaid out @SINCE_1_0.0
- using LayoutDirectionChangedSignalType = Signal<void(Actor, LayoutDirection::Type)>; ///< Layout direction changes signal type. @SINCE_1_2.60
+ using TouchEventSignalType = Signal<bool(Actor, const TouchEvent&)>; ///< Touch signal type @SINCE_1_1.37
+ using HoverSignalType = Signal<bool(Actor, const HoverEvent&)>; ///< Hover signal type @SINCE_1_0.0
+ using WheelEventSignalType = Signal<bool(Actor, const WheelEvent&)>; ///< Wheel signal type @SINCE_1_0.0
+ using OnSceneSignalType = Signal<void(Actor)>; ///< Scene connection signal type @SINCE_1_9.24
+ using OffSceneSignalType = Signal<void(Actor)>; ///< Scene disconnection signal type @SINCE_1_9.24
+ using OnRelayoutSignalType = Signal<void(Actor)>; ///< Called when the actor is relaid out @SINCE_1_0.0
+ using LayoutDirectionChangedSignalType = Signal<void(Actor, LayoutDirection::Type)>; ///< Layout direction changes signal type. @SINCE_1_2.60
+ using InheritedVisibilityChangedSignalType = Signal<void(Actor, bool)>; ///< Signal type of InheritedVisibilityChangedSignalType. @SINCE_2_3.22
// Creation
*/
LayoutDirectionChangedSignalType& LayoutDirectionChangedSignal();
+ /**
+ * @brief This signal is emitted when the visible property of this actor or any of its parents (right up to the root layer) changes.
+ *
+ * A callback of the following type may be connected:
+ * @code
+ * void YourCallbackName( Actor actor, bool visible );
+ * @endcode
+ * actor: The actor whose inherited visibility has changed.
+ * visible: This is true if this actor's inherited VISIBLE property is true.
+ * If it is true, it denotes one of the 2 cases.
+ * One is VISIBLE property of this actor or only one of the parent actors were originally false and it becomes true now.
+ * Another is this actor is connected on Scene now with that the VISIBLE property of this actor and all of its parent were true.
+ * If it is false, it also denotes one of the 2 cases.
+ * One is that VISIBLE property of this actor and all of the parent actors were originally true but one of them becomes false now.
+ * Another is VISIBLE property of this actor and all of the parent actors are true and this actor is disconnected from the Scene now.
+ *
+ * @SINCE_2_3.22
+ * @return The signal to connect to
+ * @pre The Actor has been initialized.
+ * @note This signal is NOT emitted if the actor becomes transparent (or the reverse).
+ * @note For reference, an actor is only shown if it and it's parents (up to the root actor) are also visible, are not transparent, and this actor has a non-zero size.
+ */
+ DALI_CORE_API InheritedVisibilityChangedSignalType& InheritedVisibilityChangedSignal();
+
public: // Not intended for application developers
/// @cond internal
/**
{
const uint32_t CORE_MAJOR_VERSION = 2;
const uint32_t CORE_MINOR_VERSION = 3;
-const uint32_t CORE_MICRO_VERSION = 19;
+const uint32_t CORE_MICRO_VERSION = 22;
const char* const CORE_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
TRACKBALL, ///< A trackball style mouse. @SINCE_1_2.60
REMOCON, ///< A remote controller. @SINCE_1_2.61
VIRTUAL_KEYBOARD, ///< A virtual keyboard. @SINCE_1_2.61
+ VIRTUAL_REMOCON, ///< A virtual remocon. @SINCE_2_3.22
+ VIRTUAL_MOUSE, ///< A virtual mouse. @SINCE_2_3.22
};
} // namespace Subclass
return Dali::Actor(GetImplementation(*this).GetSourceActor());
}
+Actor RenderTask::GetStopperActor() const
+{
+ return Dali::Actor(GetImplementation(*this).GetStopperActor());
+}
+
void RenderTask::SetExclusive(bool exclusive)
{
GetImplementation(*this).SetExclusive(exclusive);
return GetImplementation(*this).GetRenderTaskId();
}
+void RenderTask::RenderUntil(Actor actor)
+{
+ DALI_ASSERT_ALWAYS(actor && "RenderUntil() actor does not exist.");
+ Internal::Actor* actorImpl(&GetImplementation(actor));
+ return GetImplementation(*this).RenderUntil(actorImpl);
+}
+
RenderTask::RenderTask(Internal::RenderTask* internal)
: Handle(internal)
{
*/
Actor GetSourceActor() const;
+ Actor GetStopperActor() const;
+
/**
* @brief Sets whether the RenderTask has exclusive access to the source actors; the default is false.
* @SINCE_1_0.0
*/
uint32_t GetRenderTaskId() const;
+ void RenderUntil(Actor actor);
+
public: // Signals
/**
* @brief If the refresh rate is REFRESH_ONCE, connect to this signal to be notified when a RenderTask has finished.
Name: dali2
Summary: DALi 3D Engine
-Version: 2.3.19
+Version: 2.3.22
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT