#include <stdlib.h>
#include <iostream>
+#include <dali-toolkit/devel-api/focus-manager/keyboard-focus-manager-devel.h>
+#include <dali/integration-api/events/touch-event-integ.h>
+
#include <dali-scene3d/public-api/controls/model/model.h>
using namespace Dali;
namespace
{
+const bool DEFAULT_MODEL_CHILDREN_SENSITIVE = false;
/**
* For the AnimatedCube.gltf and its Assets
* Donated by Norbert Nopper for glTF testing.
*/
const char* TEST_DIFFUSE_TEXTURE = TEST_RESOURCE_DIR "/forest_irradiance.ktx";
const char* TEST_SPECULAR_TEXTURE = TEST_RESOURCE_DIR "/forest_radiance.ktx";
+
+bool gTouchCallBackCalled = false;
+bool TestTouchCallback(Actor, const TouchEvent&)
+{
+ gTouchCallBackCalled = true;
+ return true;
+}
+
} // namespace
// Negative test case for a method
tet_infoline(" UtcDaliModelDownCast");
Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
- BaseHandle handle(model);
+ BaseHandle handle(model);
Scene3D::Model model2 = Scene3D::Model::DownCast(handle);
DALI_TEST_CHECK(model);
END_TEST;
}
+int UtcDaliModelChildrenSensitive01(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::Model view = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
+ view.SetProperty(Dali::Actor::Property::SIZE, Vector3(100, 100, 100));
+ view.SetProperty(Dali::Actor::Property::POSITION, Vector3(0, 0, 0));
+ view.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ view.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+
+ // Get default vaule.
+ DALI_TEST_EQUALS(view.GetChildrenSensitive(), DEFAULT_MODEL_CHILDREN_SENSITIVE, TEST_LOCATION);
+
+ // Allow children actor's event before on scene.
+ view.SetChildrenSensitive(true);
+ DALI_TEST_EQUALS(view.GetChildrenSensitive(), true, TEST_LOCATION);
+
+ application.GetScene().Add(view);
+
+ application.SendNotification();
+ application.Render();
+
+ Actor meshActor = view.FindChildByName("AnimatedCube");
+ DALI_TEST_CHECK(meshActor);
+
+ // connect hit-test signal
+ gTouchCallBackCalled = false;
+ meshActor.TouchedSignal().Connect(TestTouchCallback);
+
+ Vector2 sceneSize = application.GetScene().GetSize();
+
+ // Try to touch center of scene.
+ Dali::Integration::Point point;
+ point.SetState(PointState::DOWN);
+ point.SetScreenPosition(sceneSize * 0.5f);
+ Dali::Integration::TouchEvent event;
+ event.AddPoint(point);
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ // Not touched yet.
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+ application.ProcessEvent(event);
+ // Touched.
+ DALI_TEST_CHECK(gTouchCallBackCalled);
+
+ // Clear
+ gTouchCallBackCalled = false;
+
+ // Block children actor's event
+ view.SetChildrenSensitive(false);
+ DALI_TEST_EQUALS(view.GetChildrenSensitive(), false, TEST_LOCATION);
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ // Not touched yet.
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+ application.ProcessEvent(event);
+ // Also not touched.
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+
+ // Clear
+ gTouchCallBackCalled = false;
+
+ // Allow again
+ view.SetChildrenSensitive(true);
+ DALI_TEST_EQUALS(view.GetChildrenSensitive(), true, TEST_LOCATION);
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ // Not touched yet.
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+ application.ProcessEvent(event);
+ // Touched.
+ DALI_TEST_CHECK(gTouchCallBackCalled);
+
+ // Clear
+ gTouchCallBackCalled = false;
+
+ END_TEST;
+}
+
+int UtcDaliModelChildrenSensitive02(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::Model view = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
+ view.SetProperty(Dali::Actor::Property::SIZE, Vector3(100, 100, 100));
+ view.SetProperty(Dali::Actor::Property::POSITION, Vector3(0, 0, 0));
+ view.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ view.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+
+ // Get vaule.
+ DALI_TEST_EQUALS(view.GetChildrenSensitive(), DEFAULT_MODEL_CHILDREN_SENSITIVE, TEST_LOCATION);
+
+ // Block children actor's event before on scene.
+ view.SetChildrenSensitive(false);
+ DALI_TEST_EQUALS(view.GetChildrenSensitive(), false, TEST_LOCATION);
+
+ application.GetScene().Add(view);
+
+ application.SendNotification();
+ application.Render();
+
+ Actor meshActor = view.FindChildByName("AnimatedCube");
+ DALI_TEST_CHECK(meshActor);
+
+ // connect hit-test signal
+ gTouchCallBackCalled = false;
+ meshActor.TouchedSignal().Connect(TestTouchCallback);
+
+ Vector2 sceneSize = application.GetScene().GetSize();
+
+ // Try to touch center of scene.
+ Dali::Integration::Point point;
+ point.SetState(PointState::DOWN);
+ point.SetScreenPosition(sceneSize * 0.5f);
+ Dali::Integration::TouchEvent event;
+ event.AddPoint(point);
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ // Not touched yet.
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+ application.ProcessEvent(event);
+ // Also not touched.
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+
+ // Clear
+ gTouchCallBackCalled = false;
+
+ // Allow again
+ view.SetChildrenSensitive(true);
+ DALI_TEST_EQUALS(view.GetChildrenSensitive(), true, TEST_LOCATION);
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ // Not touched yet.
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+ application.ProcessEvent(event);
+ // Touched.
+ DALI_TEST_CHECK(gTouchCallBackCalled);
+
+ // Clear
+ gTouchCallBackCalled = false;
+
+ END_TEST;
+}
+
int UtcDaliModelAnimation01(void)
{
ToolkitTestApplication application;
namespace
{
static bool gOnRelayoutCallBackCalled = false;
-void OnRelayoutCallback(Actor actor)
+void OnRelayoutCallback(Actor actor)
{
gOnRelayoutCallBackCalled = true;
}
static bool gResourceReadyCalled = false;
-void OnResourceReady(Control control)
+void OnResourceReady(Control control)
{
gResourceReadyCalled = true;
}
-}
+} // namespace
int UtcDaliModelResourceReady(void)
{
ToolkitTestApplication application;
gOnRelayoutCallBackCalled = false;
- gResourceReadyCalled = false;
- Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_ANIMATION_TEST_FILE_NAME);
+ gResourceReadyCalled = false;
+ Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_ANIMATION_TEST_FILE_NAME);
model.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
model.OnRelayoutSignal().Connect(OnRelayoutCallback);
model.ResourceReadySignal().Connect(OnResourceReady);
{
const char* TEST_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/gallery-small-1.jpg";
const char* TEST_IMAGE_2_FILE_NAME = TEST_RESOURCE_DIR "/icon-delete.png";
+const char* TEST_IMAGE_3_FILE_NAME = TEST_RESOURCE_DIR "/icon-edit.png";
+const char* TEST_IMAGE_4_FILE_NAME = TEST_RESOURCE_DIR "/application-icon-20.png";
const char* TEST_MASK_FILE_NAME = TEST_RESOURCE_DIR "/mask.png";
class TestObserver : public Dali::Toolkit::TextureUploadObserver
TextureManager* mTextureManagerPtr; // Keep the pointer of texture manager.
};
+class TestObserverWithCustomFunction : public TestObserver
+{
+public:
+ TestObserverWithCustomFunction()
+ : TestObserver(),
+ mSignals{},
+ mData{nullptr},
+ mKeepSignal{false}
+ {
+ }
+
+ virtual void LoadComplete(bool loadSuccess, TextureInformation textureInformation) override
+ {
+ if(textureInformation.returnType == TextureUploadObserver::ReturnType::TEXTURE)
+ {
+ mCompleteType = CompleteType::UPLOAD_COMPLETE;
+ }
+ else
+ {
+ mCompleteType = CompleteType::LOAD_COMPLETE;
+ }
+ mLoaded = loadSuccess;
+ mObserverCalled = true;
+ mTextureSet = textureInformation.textureSet;
+
+ // Execute signals.
+ for(size_t i = 0; i < mSignals.size(); i++)
+ {
+ mSignals[i](mData);
+ }
+
+ // Clear signals.
+ if(!mKeepSignal)
+ {
+ mSignals.clear();
+ }
+ }
+
+ void ConnectFunction(std::function<void(void*)> signal)
+ {
+ mSignals.push_back(signal);
+ }
+
+public:
+ std::vector<std::function<void(void*)>> mSignals;
+ void* mData;
+ bool mKeepSignal;
+};
+
} // namespace
int UtcTextureManagerRequestLoad(void)
END_TEST;
}
+
+int UtcTextureManagerRemoveDuringGPUMasking(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcTextureManagerRemoveDuringGPUMasking");
+ tet_infoline("Request 3 different GPU masking image.");
+ tet_infoline("Control to mask image load last. and then, check execute result.");
+
+ TextureManager textureManager; // Create new texture manager
+
+ TestObserverWithCustomFunction observer1;
+ TestObserverWithCustomFunction observer2;
+ TestObserver observer3;
+ TestObserver observer4;
+
+ std::string filename1(TEST_IMAGE_FILE_NAME);
+ std::string filename2(TEST_IMAGE_2_FILE_NAME);
+ std::string filename3(TEST_IMAGE_3_FILE_NAME);
+ std::string filename4(TEST_IMAGE_4_FILE_NAME);
+
+ auto textureId1(TextureManager::INVALID_TEXTURE_ID);
+ auto textureId2(TextureManager::INVALID_TEXTURE_ID);
+ auto textureId3(TextureManager::INVALID_TEXTURE_ID);
+ auto textureId4(TextureManager::INVALID_TEXTURE_ID);
+
+ std::string maskname(TEST_MASK_FILE_NAME);
+ TextureManager::MaskingDataPointer maskInfo[3] = {nullptr, nullptr, nullptr};
+ for(int i = 0; i < 3; i++)
+ {
+ maskInfo[i].reset(new TextureManager::MaskingData());
+ maskInfo[i]->mAlphaMaskUrl = maskname;
+ maskInfo[i]->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
+ maskInfo[i]->mCropToMask = true;
+ maskInfo[i]->mPreappliedMasking = false; // To make GPU masking
+ maskInfo[i]->mContentScaleFactor = 1.0f;
+ }
+ Vector4 atlasRect(0.f, 0.f, 1.f, 1.f);
+ Dali::ImageDimensions atlasRectSize(0, 0);
+ bool synchronousLoading(false);
+ bool atlasingStatus(false);
+ bool loadingStatus(false);
+ auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+ ImageAtlasManagerPtr atlasManager = nullptr;
+ Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
+
+ // Request image 1, 2, 3 with GPU masking
+ textureManager.LoadTexture(
+ filename1,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo[0],
+ synchronousLoading,
+ textureId1,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer1,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ textureManager.LoadTexture(
+ filename2,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo[1],
+ synchronousLoading,
+ textureId2,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer2,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ textureManager.LoadTexture(
+ filename3,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo[2],
+ synchronousLoading,
+ textureId3,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer3,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION);
+
+ // Check we use cached mask image
+ DALI_TEST_CHECK(maskInfo[0]->mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID);
+ DALI_TEST_EQUALS(maskInfo[0]->mAlphaMaskId, maskInfo[1]->mAlphaMaskId, TEST_LOCATION);
+ DALI_TEST_EQUALS(maskInfo[0]->mAlphaMaskId, maskInfo[2]->mAlphaMaskId, TEST_LOCATION);
+
+ // Connect observer1 custom function
+ struct CustomData1
+ {
+ TextureManager* textureManagerPtr{nullptr};
+ TextureManager::TextureId removeTextureId{TextureManager::INVALID_TEXTURE_ID};
+ TestObserver* removeTextureObserver{nullptr};
+ };
+ CustomData1 data1;
+ data1.textureManagerPtr = &textureManager;
+ data1.removeTextureId = textureId3;
+ data1.removeTextureObserver = &observer3;
+
+ observer1.mData = &data1;
+ observer1.ConnectFunction(
+ [](void* data) {
+ DALI_TEST_CHECK(data);
+ CustomData1 data1 = *(CustomData1*)data;
+
+ DALI_TEST_CHECK(data1.textureManagerPtr);
+ DALI_TEST_CHECK(data1.removeTextureId != TextureManager::INVALID_TEXTURE_ID);
+ DALI_TEST_CHECK(data1.removeTextureObserver);
+
+ // Remove textureId3
+ data1.textureManagerPtr->Remove(data1.removeTextureId, data1.removeTextureObserver);
+ });
+
+ // Connect observer2 custom function
+ struct CustomData2
+ {
+ TextureManager* textureManagerPtr{nullptr};
+ std::string addTextureUrl{};
+ TextureManager::TextureId* addTextureIdPtr{nullptr};
+ TestObserver* addTextureObserver{nullptr};
+ };
+ CustomData2 data2;
+ data2.textureManagerPtr = &textureManager;
+ data2.addTextureUrl = filename4;
+ data2.addTextureIdPtr = &textureId4;
+ data2.addTextureObserver = &observer4;
+
+ observer2.mData = &data2;
+ observer2.ConnectFunction(
+ [](void* data) {
+ DALI_TEST_CHECK(data);
+ CustomData2 data2 = *(CustomData2*)data;
+
+ DALI_TEST_CHECK(data2.textureManagerPtr);
+ DALI_TEST_CHECK(!data2.addTextureUrl.empty());
+ DALI_TEST_CHECK(data2.addTextureIdPtr);
+ DALI_TEST_CHECK(data2.addTextureObserver);
+
+ auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+
+ // Load textureId4
+ (*data2.addTextureIdPtr) = data2.textureManagerPtr->RequestLoad(
+ data2.addTextureUrl,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ TextureManager::UseAtlas::NO_ATLAS,
+ data2.addTextureObserver,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+ });
+
+ application.SendNotification();
+ application.Render();
+
+ tet_printf("Id info - mask : {%d}, 1 : {%d}, 2 : {%d}, 3 : {%d}, 4 : {%d}\n", static_cast<int>(maskInfo[0]->mAlphaMaskId), static_cast<int>(textureId1), static_cast<int>(textureId2), static_cast<int>(textureId3), static_cast<int>(textureId4));
+
+ // CAPTION : HARD-CODING.
+ {
+ // Complete async load 1, 2, 3.
+ std::vector<Devel::PixelBuffer> pixelBuffers;
+
+ pixelBuffers.clear();
+ pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
+ textureManager.AsyncLoadComplete(textureId1, pixelBuffers);
+ pixelBuffers.clear();
+ pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
+ textureManager.AsyncLoadComplete(textureId2, pixelBuffers);
+ pixelBuffers.clear();
+ pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
+ textureManager.AsyncLoadComplete(textureId3, pixelBuffers);
+
+ DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION);
+
+ // Complete mask load.
+ pixelBuffers.clear();
+ pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::L8));
+ textureManager.AsyncLoadComplete(maskInfo[0]->mAlphaMaskId, pixelBuffers);
+
+ tet_printf("Id info after observer notify - mask : {%d}, 1 : {%d}, 2 : {%d}, 3 : {%d}, 4 : {%d}\n", static_cast<int>(maskInfo[0]->mAlphaMaskId), static_cast<int>(textureId1), static_cast<int>(textureId2), static_cast<int>(textureId3), static_cast<int>(textureId4));
+
+ // Check observer 1 and 2 called, but 3 and 4 not called.
+ DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer4.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer4.mObserverCalled, false, TEST_LOCATION);
+
+ // Check textureId4
+ DALI_TEST_CHECK(textureId4 != TextureManager::INVALID_TEXTURE_ID);
+
+ // Complete 4.
+ pixelBuffers.clear();
+ pixelBuffers.push_back(Devel::PixelBuffer::New(1, 1, Pixel::Format::RGB888));
+ textureManager.AsyncLoadComplete(textureId4, pixelBuffers);
+
+ DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer3.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer3.mObserverCalled, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer4.mLoaded, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer4.mObserverCalled, true, TEST_LOCATION);
+ }
+
+ END_TEST;
+}
\ No newline at end of file
tet_infoline("UtcDaliVisualFactoryGetAnimatedVectorImageVisual04: Request animated vector image visual with a Property::Map");
int startFrame = 1, endFrame = 3;
+ int desiredWidth = 100, desiredHeight = 150;
float cornerRadius = 22.0f;
float borderlineWidth = 2.0f;
Vector4 borderlineColor = Vector4(1.0f, 1.0f, 1.0f, 1.0f);
.Add("borderlineWidth", borderlineWidth)
.Add("borderlineColor", borderlineColor)
.Add("borderlineOffset", borderlineOffset)
- .Add("synchronousLoading", true);
+ .Add("desiredWidth", desiredWidth)
+ .Add("desiredHeight", desiredHeight);
Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap);
DALI_TEST_CHECK(visual);
DALI_TEST_CHECK(value);
DALI_TEST_EQUALS(value->Get<float>(), borderlineOffset, TEST_LOCATION);
+ value = resultMap.Find(ImageVisual::Property::DESIRED_WIDTH, Property::INTEGER);
+ DALI_TEST_CHECK(value);
+ DALI_TEST_EQUALS(value->Get<int>(), desiredWidth, TEST_LOCATION);
+
+ value = resultMap.Find(ImageVisual::Property::DESIRED_HEIGHT, Property::INTEGER);
+ DALI_TEST_CHECK(value);
+ DALI_TEST_EQUALS(value->Get<int>(), desiredHeight, TEST_LOCATION);
+
actor.Unparent();
DALI_TEST_CHECK(actor.GetRendererCount() == 0u);
tet_infoline("UtcDaliAnimatedVectorImageVisualGetPropertyMap01");
int startFrame = 1, endFrame = 3;
+ int desiredWidth = 100, desiredHeight = 150;
Vector4 cornerRadius(50.0f, 22.0f, 0.0f, 3.0f);
float borderlineWidth = 2.3f;
Vector4 borderlineColor = Vector4(0.3f, 0.3f, 1.0f, 1.0f);
.Add(DevelVisual::Property::BORDERLINE_WIDTH, borderlineWidth)
.Add(DevelVisual::Property::BORDERLINE_COLOR, borderlineColor)
.Add(DevelVisual::Property::BORDERLINE_OFFSET, borderlineOffset)
- .Add(ImageVisual::Property::SYNCHRONOUS_LOADING, false);
+ .Add(ImageVisual::Property::SYNCHRONOUS_LOADING, false)
+ .Add(ImageVisual::Property::DESIRED_WIDTH, desiredWidth)
+ .Add(ImageVisual::Property::DESIRED_HEIGHT, desiredHeight);
// request AnimatedVectorImageVisual with a property map
VisualFactory factory = VisualFactory::Get();
DALI_TEST_CHECK(value);
DALI_TEST_EQUALS(value->Get<float>(), borderlineOffset, TEST_LOCATION);
+ value = resultMap.Find(ImageVisual::Property::DESIRED_WIDTH, Property::INTEGER);
+ DALI_TEST_CHECK(value);
+ DALI_TEST_EQUALS(value->Get<int>(), desiredWidth, TEST_LOCATION);
+
+ value = resultMap.Find(ImageVisual::Property::DESIRED_HEIGHT, Property::INTEGER);
+ DALI_TEST_CHECK(value);
+ DALI_TEST_EQUALS(value->Get<int>(), desiredHeight, TEST_LOCATION);
+
// request AnimatedVectorImageVisual with an URL
Visual::Base visual2 = factory.CreateVisual(TEST_VECTOR_IMAGE_FILE_NAME, ImageDimensions());
END_TEST;
}
+
+int UtcDaliAnimatedVectorImageVisualDesiredSize(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliAnimatedVectorImageVisualDesiredSize");
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ int desiredWidth = 150, desiredHeight = 200;
+
+ Visual::Base visual = VisualFactory::Get().CreateVisual(TEST_VECTOR_IMAGE_FILE_NAME, ImageDimensions(desiredWidth, desiredHeight));
+ DALI_TEST_CHECK(visual);
+
+ DummyControl actor = DummyControl::New(true);
+ DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+ application.GetScene().Add(actor);
+
+ application.SendNotification();
+ application.Render();
+
+ // Trigger count is 1 - resource ready
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ textureTrace.Enable(true);
+
+ application.SendNotification();
+ application.Render();
+
+ {
+ std::stringstream out;
+ out << GL_TEXTURE_2D << ", " << 0u << ", " << desiredWidth << ", " << desiredHeight;
+ DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str()));
+ }
+
+ // Unparent to make next trigger
+ actor.Unparent();
+
+ application.SendNotification();
+ application.Render();
+
+ // Set visual size
+ actor.SetProperty(Actor::Property::SIZE, Vector2(300.0f, 300.0f));
+ application.GetScene().Add(actor);
+
+ application.SendNotification();
+ application.Render();
+
+ // Trigger count is 1 - resource ready
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ textureTrace.Reset();
+
+ application.SendNotification();
+ application.Render();
+
+ {
+ std::stringstream out;
+ out << GL_TEXTURE_2D << ", " << 0u << ", " << desiredWidth << ", " << desiredHeight;
+ DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str())); // The size should not be changed
+ }
+
+ END_TEST;
+}
END_TEST;
}
+int UtcDaliImageViewReloadAlphaMaskImage(void)
+{
+ ToolkitTestApplication application;
+
+ gResourceReadySignalFired = false;
+
+ ImageView dummy = ImageView::New();
+ ImageView imageView = ImageView::New();
+ Property::Map propertyMap;
+
+ // To keep alpha mask cached, scene on some dummy image.
+ // Note : If we don't cache alpha mask image, the reference count of mask image become zero.
+ // In this case, we might need to wait mask image loading, which is not neccesary & can be changed behavior.
+ propertyMap[ImageVisual::Property::URL] = gImage_600_RGB;
+ propertyMap[ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_DEFAULT;
+ dummy.SetProperty(ImageView::Property::IMAGE, propertyMap);
+
+ application.GetScene().Add(dummy);
+
+ application.SendNotification();
+ application.Render(16);
+
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(16);
+
+ propertyMap.Clear();
+ propertyMap[ImageVisual::Property::URL] = gImage_34_RGBA;
+ propertyMap[ImageVisual::Property::ALPHA_MASK_URL] = TEST_BROKEN_IMAGE_DEFAULT;
+ imageView.SetProperty(ImageView::Property::IMAGE, propertyMap);
+
+ DALI_TEST_EQUALS(imageView.IsResourceReady(), false, TEST_LOCATION);
+
+ imageView.ResourceReadySignal().Connect(&ResourceReadySignal);
+
+ application.GetScene().Add(imageView);
+
+ application.SendNotification();
+ application.Render(16);
+
+ // Load image and use cached mask. Now we try to apply masking.
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(gResourceReadySignalFired, false, TEST_LOCATION);
+
+ // Cancel apply masking.
+ imageView.Unparent();
+
+ application.SendNotification();
+ application.Render(16);
+
+ // Reload same image again.
+ application.GetScene().Add(imageView);
+
+ application.SendNotification();
+ application.Render(16);
+
+ // Finish apply masking.
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(imageView.GetRendererCount(), 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(imageView.IsResourceReady(), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(gResourceReadySignalFired, true, TEST_LOCATION);
+
+ END_TEST;
+}
+
void OnRelayoutOverride(Size size)
{
gNaturalSize = size; // Size Relayout is using
END_TEST;
}
+int UtcDaliImageViewSvgDesiredSize01(void)
+{
+ ToolkitTestApplication application;
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ int desiredWidth = 100, desiredHeight = 150;
+ ImageView imageView = ImageView::New(TEST_SVG_FILE_NAME, ImageDimensions(desiredWidth, desiredHeight));
+
+ application.GetScene().Add(imageView);
+
+ application.SendNotification();
+
+ // Wait for loading & rasterization
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(16);
+
+ {
+ std::stringstream out;
+ out << GL_TEXTURE_2D << ", " << 0u << ", " << desiredWidth << ", " << desiredHeight;
+ DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str()));
+ }
+
+ END_TEST;
+}
+
+int UtcDaliImageViewSvgDesiredSize02(void)
+{
+ ToolkitTestApplication application;
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ int desiredWidth = 150, desiredHeight = 100;
+ ImageView imageView = ImageView::New();
+ imageView[ImageView::Property::IMAGE] = Property::Map().Add("url", TEST_SVG_FILE_NAME).Add("desiredWidth", desiredWidth).Add("desiredHeight", desiredHeight);
+ application.GetScene().Add(imageView);
+
+ application.SendNotification();
+
+ // Wait for loading & rasterization
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(16);
+
+ {
+ std::stringstream out;
+ out << GL_TEXTURE_2D << ", " << 0u << ", " << desiredWidth << ", " << desiredHeight;
+ DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str()));
+ }
+
+ END_TEST;
+}
+
int UtcDaliImageViewImageLoadFailure01(void)
{
ToolkitTestApplication application;
#include <dali-toolkit/dali-toolkit.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
+#include <dali/devel-api/actors/actor-devel.h>
#include <dali/integration-api/debug.h>
#include <dali/public-api/object/type-registry-helper.h>
#include <dali/public-api/object/type-registry.h>
#include <filesystem>
// INTERNAL INCLUDES
-#include <dali-scene3d/public-api/controls/model/model.h>
#include <dali-scene3d/internal/controls/scene-view/scene-view-impl.h>
+#include <dali-scene3d/public-api/controls/model/model.h>
#include <dali-scene3d/public-api/loader/animation-definition.h>
#include <dali-scene3d/public-api/loader/camera-parameters.h>
#include <dali-scene3d/public-api/loader/cube-map-loader.h>
static constexpr Vector3 Y_DIRECTION(1.0f, -1.0f, 1.0f);
+static constexpr bool DEFAULT_MODEL_CHILDREN_SENSITIVE = false;
+
static constexpr std::string_view KTX_EXTENSION = ".ktx";
static constexpr std::string_view OBJ_EXTENSION = ".obj";
static constexpr std::string_view GLTF_EXTENSION = ".gltf";
mNaturalSize(Vector3::ZERO),
mModelPivot(AnchorPoint::CENTER),
mIblScaleFactor(1.0f),
+ mModelChildrenSensitive(DEFAULT_MODEL_CHILDREN_SENSITIVE),
mModelResourceReady(false),
mIBLResourceReady(true)
{
return mModelRoot;
}
+void Model::SetChildrenSensitive(bool enable)
+{
+ if(mModelChildrenSensitive != enable)
+ {
+ mModelChildrenSensitive = enable;
+ if(mModelRoot)
+ {
+ mModelRoot.SetProperty(Dali::Actor::Property::SENSITIVE, mModelChildrenSensitive);
+ }
+ }
+}
+
+bool Model::GetChildrenSensitive() const
+{
+ return mModelChildrenSensitive;
+}
+
void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor)
{
- mIBLResourceReady = false;
+ mIBLResourceReady = false;
Texture diffuseTexture = Dali::Scene3D::Loader::LoadCubeMap(diffuseUrl);
Texture specularTexture = Dali::Scene3D::Loader::LoadCubeMap(specularUrl);
SetImageBasedLightTexture(diffuseTexture, specularTexture, scaleFactor);
mIblScaleFactor = scaleFactor;
UpdateImageBasedLightScaleFactor();
}
-
}
}
FitModelPosition();
ScaleModel();
+ mModelRoot.SetProperty(Dali::Actor::Property::SENSITIVE, mModelChildrenSensitive);
+
Self().Add(mModelRoot);
Self().SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali/public-api/actors/layer.h>
#include <dali/public-api/animation/animation.h>
-#include <dali/public-api/rendering/texture.h>
#include <dali/public-api/object/weak-handle.h>
+#include <dali/public-api/rendering/texture.h>
// INTERNAL INCLUDES
#include <dali-scene3d/public-api/controls/model/model.h>
const Actor GetModelRoot() const;
/**
+ * @copydoc Model::SetChildrenSensitive()
+ */
+ void SetChildrenSensitive(bool enable);
+
+ /**
+ * @copydoc Model::GetChildrenSensitive()
+ */
+ bool GetChildrenSensitive() const;
+
+ /**
* @copydoc Model::SetImageBasedLightSource()
*/
void SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor);
Vector3 mNaturalSize;
Vector3 mModelPivot;
float mIblScaleFactor;
+ bool mModelChildrenSensitive;
bool mModelResourceReady;
bool mIBLResourceReady;
};
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
#include <dali-toolkit/public-api/image-loader/image-url.h>
#include <dali-toolkit/public-api/image-loader/image.h>
+#include <dali/devel-api/actors/camera-actor-devel.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
#include <dali/devel-api/common/stage.h>
#include <dali/integration-api/debug.h>
#include <dali/public-api/object/type-registry-helper.h>
DALI_TYPE_REGISTRATION_BEGIN(Scene3D::SceneView, Toolkit::Control, Create);
DALI_TYPE_REGISTRATION_END()
-Property::Index RENDERING_BUFFER = Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX + 1;
+Property::Index RENDERING_BUFFER = Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX + 1;
+constexpr int32_t DEFAULT_ORIENTATION = 0;
} // anonymous namespace
SceneView::SceneView()
-: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT))
+: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
+ mWindowOrientation(DEFAULT_ORIENTATION)
{
}
void SceneView::SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor)
{
- mIBLResourceReady = false;
+ mIBLResourceReady = false;
Texture diffuseTexture = Dali::Scene3D::Loader::LoadCubeMap(diffuseUrl);
if(diffuseTexture)
{
{
UpdateRenderTask();
+ Window window = DevelWindow::Get(Self());
+ if(window)
+ {
+ window.ResizeSignal().Connect(this, &SceneView::OnWindowResized);
+ }
+
Control::OnSceneConnection(depth);
}
void SceneView::OnSceneDisconnection()
{
mModels.clear();
+
+ Window window = DevelWindow::Get(Self());
+ if(window)
+ {
+ window.ResizeSignal().Disconnect(this, &SceneView::OnWindowResized);
+ }
+
Control::OnSceneDisconnection();
}
mRenderTask.SetCameraActor(mSelectedCamera);
}
- Vector3 size = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
+ Vector3 size = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
const float aspectRatio = size.width / size.height;
mSelectedCamera.SetAspectRatio(aspectRatio);
- const float halfHeight = mSelectedCamera[Dali::CameraActor::Property::TOP_PLANE_DISTANCE];
- const float halfWidth = aspectRatio * halfHeight;
+ const float halfHeight = mSelectedCamera[Dali::CameraActor::Property::TOP_PLANE_DISTANCE];
+ const float halfWidth = aspectRatio * halfHeight;
mSelectedCamera[Dali::CameraActor::Property::LEFT_PLANE_DISTANCE] = -halfWidth;
mSelectedCamera[Dali::CameraActor::Property::RIGHT_PLANE_DISTANCE] = halfWidth;
- mSelectedCamera[Dali::CameraActor::Property::TOP_PLANE_DISTANCE] = halfHeight; // Top is +ve to keep consistency with orthographic values
+ mSelectedCamera[Dali::CameraActor::Property::TOP_PLANE_DISTANCE] = halfHeight; // Top is +ve to keep consistency with orthographic values
mSelectedCamera[Dali::CameraActor::Property::BOTTOM_PLANE_DISTANCE] = -halfHeight; // Bottom is -ve to keep consistency with orthographic values
if(mUseFrameBuffer)
{
mTexture.Reset();
}
}
+
+ RotateCamera();
+ }
+}
+
+void SceneView::OnWindowResized(Window window, Window::WindowSize size)
+{
+ mWindowOrientation = DevelWindow::GetPhysicalOrientation(window);
+ RotateCamera();
+}
+
+void SceneView::RotateCamera()
+{
+ if(mUseFrameBuffer)
+ {
+ DevelCameraActor::RotateProjection(mSelectedCamera, DEFAULT_ORIENTATION);
+ }
+ else
+ {
+ DevelCameraActor::RotateProjection(mSelectedCamera, mWindowOrientation);
}
}
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali/public-api/actors/camera-actor.h>
#include <dali/public-api/actors/layer.h>
+#include <dali/public-api/adaptor-framework/window.h>
#include <dali/public-api/animation/animation.h>
#include <dali/public-api/object/weak-handle.h>
#include <dali/public-api/render-tasks/render-task.h>
#include <dali/public-api/rendering/texture.h>
// INTERNAL INCLUDES
-#include <dali-scene3d/public-api/controls/scene-view/scene-view.h>
#include <dali-scene3d/public-api/controls/model/model.h>
+#include <dali-scene3d/public-api/controls/scene-view/scene-view.h>
namespace Dali
{
*/
void UpdateRenderTask();
+ /**
+ * @brief Callback that will be called when window is resized.
+ */
+ void OnWindowResized(Window window, Window::WindowSize size);
+
+ /**
+ * @brief Update camera's projection orientation according to the screen orientation.
+ */
+ void RotateCamera();
+
private:
Toolkit::Visual::Base mVisual;
Dali::FrameBuffer mRenderTarget;
Dali::Texture mTexture;
Dali::RenderTask mRenderTask;
-
- Layer mRootLayer;
+ Layer mRootLayer;
+ int32_t mWindowOrientation;
Dali::Texture mSpecularTexture;
Dali::Texture mDiffuseTexture;
return GetImpl(*this).GetModelRoot();
}
+void Model::SetChildrenSensitive(bool enable)
+{
+ GetImpl(*this).SetChildrenSensitive(enable);
+}
+
+bool Model::GetChildrenSensitive() const
+{
+ return GetImpl(*this).GetChildrenSensitive();
+}
+
void Model::SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor)
{
GetImpl(*this).SetImageBasedLightSource(diffuseUrl, specularUrl, scaleFactor);
// EXTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control.h>
-#include <dali/public-api/rendering/texture.h>
#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/rendering/texture.h>
namespace Dali
{
*
* By default, The loaded model has its own position and size which are defined in vertex buffer regardless of the Control size.
*
+ * @SINCE_2_1.41
* @code
*
* Model model = Model::New(modelUrl);
public:
/**
* @brief Create an initialized Model.
+ *
+ * @SINCE_2_1.41
* @param[in] modelUrl model file path.(e.g., glTF, and DLI).
* @param[in] resourceDirectoryUrl resource file path that includes binary, image etc.
* @note If resourceDirectoryUrl is empty, the parent directory path of modelUrl is used for resource path.
*
* Only derived versions can be instantiated. Calling member
* functions with an uninitialized Dali::Object is not allowed.
+ *
+ * @SINCE_2_1.41
*/
Model();
* @brief Destructor.
*
* This is non-virtual since derived Handle types must not contain data or virtual methods.
+ *
+ * @SINCE_2_1.41
*/
~Model();
/**
* @brief Copy constructor.
+ *
+ * @SINCE_2_1.41
* @param[in] model Handle to an object
*/
Model(const Model& model);
/**
* @brief Move constructor
*
+ * @SINCE_2_1.41
* @param[in] rhs A reference to the moved handle
*/
Model(Model&& rhs);
/**
* @brief Assignment operator.
+ *
+ * @SINCE_2_1.41
* @param[in] model Handle to an object
* @return reference to this
*/
/**
* @brief Move assignment
*
+ * @SINCE_2_1.41
* @param[in] rhs A reference to the moved handle
* @return A reference to this
*/
* If handle points to a Model, the downcast produces valid handle.
* If not, the returned handle is left uninitialized.
*
+ * @SINCE_2_1.41
* @param[in] handle Handle to an object
* @return Handle to a Model or an uninitialized handle
*/
/**
* @brief Retrieves model root Actor.
+ *
+ * @SINCE_2_1.41
* @return Root Actor of the model.
*/
const Actor GetModelRoot() const;
/**
+ * @brief Whether allow this model's children actor to use events.
+ *
+ * Usually, 3D Model might have a lot of actors. And most of them don't need to check events.
+ * To optimize traversal, we need to setup some flag that this model don't allow (or allow) to traversal
+ * children so that child can use events.
+ *
+ * @SINCE_2_1.43
+ * @note Even if we set children sensitive as false, model itself's sensitive
+ * is depend on it's property.
+ * @note If we don't call this API, default is false. (Allow to traversal model's children during hit-test)
+ *
+ * @param[in] enable True to enable model's children can use events.
+ */
+ void SetChildrenSensitive(bool enable);
+
+ /**
+ * @brief Gets whether this Model allow model's children actor to use events or not.
+ *
+ * @SINCE_2_1.43
+ * @return bool True if this Model allow model children sensitive.
+ */
+ bool GetChildrenSensitive() const;
+
+ /**
* @brief Changes Image Based Light as the input textures.
+ *
+ * @SINCE_2_1.41
* @param[in] diffuseUrl cube map that can be used as a diffuse IBL source.
* @param[in] specularUrl cube map that can be used as a specular IBL source.
* @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.
/**
* @brief Sets Image Based Light Texture.
*
+ * @SINCE_2_1.41
* @param[in] diffuseTexture cube map texture that can be used as a diffuse IBL source.
* @param[in] specularTexture cube map texture that can be used as a specular IBL source.
* @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.
/**
* @brief Sets Scale Factor of Image Based Light Source.
*
+ * @SINCE_2_1.41
* @note If SetImageBasedLightSource() or SetImageBasedLightTexture() method is called after this method, scaleFactor is overrided.
*
* @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f].
* @brief Gets Scale Factor of Image Based Light Source.
* Default value is 1.0f.
*
+ * @SINCE_2_1.41
* @return scale factor that controls light source intensity.
*/
float GetImageBasedLightScaleFactor() const;
/**
* @brief Gets number of animations those loaded from model file.
+ *
+ * @SINCE_2_1.41
* @return The number of loaded animations.
* @note This method should be called after Model load finished.
*/
/**
* @brief Gets animation at the index.
+ *
+ * @SINCE_2_1.41
* @param[in] index Index of animation to be retrieved.
* @return Animation at the index.
* @note This method should be called after Model load finished.
/**
* @brief Retrieves animation with the given name.
+ *
+ * @SINCE_2_1.41
* @param[in] name string name of animation to be retrieved.
* @return Animation that has the given name.
* @note This method should be called after Model load finished.
*
* And since SceneView is a Control, it can be placed together with other 2D UI components in the DALi window.
*
+ * @SINCE_2_1.38
* @code
*
* Dali::Scene3D::SceneView sceneView = Dali::Scene3D::SceneView::New();
public:
/**
* @brief Create an initialized SceneView.
+ *
+ * @SINCE_2_1.38
* @return A handle to a newly allocated Dali resource
*/
static SceneView New();
*
* Only derived versions can be instantiated. Calling member
* functions with an uninitialized Dali::Object is not allowed.
+ *
+ * @SINCE_2_1.38
*/
SceneView();
* @brief Destructor.
*
* This is non-virtual since derived Handle types must not contain data or virtual methods.
+ *
+ * @SINCE_2_1.38
*/
~SceneView();
/**
* @brief Copy constructor.
+ *
+ * @SINCE_2_1.38
* @param[in] sceneView Handle to an object
*/
SceneView(const SceneView& sceneView);
/**
* @brief Move constructor
*
+ * @SINCE_2_1.38
* @param[in] rhs A reference to the moved handle
*/
SceneView(SceneView&& rhs);
/**
* @brief Assignment operator.
+ *
+ * @SINCE_2_1.38
* @param[in] sceneView Handle to an object
* @return reference to this
*/
/**
* @brief Move assignment
*
+ * @SINCE_2_1.38
* @param[in] rhs A reference to the moved handle
* @return A reference to this
*/
* If handle points to a SceneView, the downcast produces valid handle.
* If not, the returned handle is left uninitialized.
*
+ * @SINCE_2_1.38
* @param[in] handle Handle to an object
* @return Handle to a SceneView or an uninitialized handle
*/
* @brief Adds a CameraActor to the SceneView
* The CameraActor can be used as a selected camera to render the scene by using SelectCamera(uint32_t) or SelectCamera(std::string)
*
+ * @SINCE_2_1.38
* @note
* AspectRatio property of CameraActor will be changed depending on the Size of this SceneView.
*
/**
* @brief Removes a CameraActor from this SceneView.
+ *
+ * @SINCE_2_1.38
* @note If removed CameraActor is selected CameraActor,
* first camera in the list is set to selected CameraActor.
*
/**
* @brief Retrieves the number of cameras.
*
+ * @SINCE_2_1.38
* @return Number of cameras those currently the SceneView contains.
*/
uint32_t GetCameraCount() const;
/**
* @brief Retrieves selected CameraActor.
*
+ * @SINCE_2_1.38
* @return CameraActor currently used in SceneView as a selected CameraActor
*/
CameraActor GetSelectedCamera() const;
/**
* @brief Retrieves a CameraActor of the index.
*
+ * @SINCE_2_1.38
* @param[in] index Index of CameraActor to be retrieved.
*
* @return CameraActor of the index
/**
* @brief Retrieves a CameraActor of the name.
*
+ * @SINCE_2_1.38
* @param[in] name string keyword of CameraActor to be retrieved.
*
* @return CameraActor that has the name as a Dali::Actor::Property::NAME
/**
* @brief Makes SceneView use a CameraActor of index as a selected camera.
*
+ * @SINCE_2_1.38
* @param[in] index Index of CameraActor to be used as a selected camera.
*/
void SelectCamera(uint32_t index);
/**
* @brief Makes SceneView use a CameraActor of a name as a selected camera.
*
+ * @SINCE_2_1.38
* @param[in] name string keyword of CameraActor to be used as a selected camera.
*/
void SelectCamera(const std::string& name);
/**
* @brief Sets Image Based Light Source to apply it on the all Models those added on this SceneView.
*
+ * @SINCE_2_1.38
* @note If any Models already have IBL, they are batch-overridden with the SceneView's IBL.
* If SceneView has IBL, IBL of newly added Model is also overridden.
* To set indivisual IBL for each Model, the Model's IBL should be set after the SceneView's IBL.
/**
* @brief Sets Scale Factor of Image Based Light Source.
*
+ * @SINCE_2_1.41
* @note If SetImageBasedLightSource() or SetImageBasedLightTexture() method is called after this method, scaleFactor is overriden.
* @note Default value is 1.0f.
*
* @brief Gets Scale Factor of Image Based Light Source.
* Default value is 1.0f.
*
+ * @SINCE_2_1.41
* @return scale factor that controls light source intensity.
*/
float GetImageBasedLightScaleFactor() const;
* If useFramebuffer is false, each item in SceneView is rendered on window directly.
* Default is false.
*
+ * @SINCE_2_1.38
* @note If useFramebuffer is true, it could decrease performance but entire rendering order is satisfied.
* If useFramebuffer is false, performance is become better but SceneView is rendered on top of the other 2D Actors regardless tree order.
*
/**
* @brief Gets whether this SceneView uses Framebuffer or not.
*
+ * @SINCE_2_1.38
* @return bool True if this SceneView uses Framebuffer.
*/
bool IsUsingFramebuffer() const;
ReadArcField(eRenderable, *arcNode);
}
- if(renderable) // process common properties of all renderables + register payload
+ if(renderable && eRenderable != nullptr) // process common properties of all renderables + register payload
{
// shader
renderable->mShaderIdx = 0;
auto eShader = eRenderable->GetChild("shader");
- resourceIds.push_back({ResourceType::Shader, eShader, renderable->mShaderIdx});
+ if(eShader)
+ {
+ resourceIds.push_back({ResourceType::Shader, eShader, renderable->mShaderIdx});
+ }
// color
if(modelNode)
{
modelNode->mMaterialIdx = 0; // must offer default of 0
auto eMaterial = eRenderable->GetChild("material");
- resourceIds.push_back({ResourceType::Material, eMaterial, modelNode->mMaterialIdx});
+ if(eMaterial)
+ {
+ resourceIds.push_back({ResourceType::Material, eMaterial, modelNode->mMaterialIdx});
+ }
if(!ReadColorCodeOrColor(eRenderable, modelNode->mColor, params.input.mConvertColorCode))
{
loadState == TextureManagerType::LoadState::MASK_APPLIED ? "MASK_APPLIED" : \
loadState == TextureManagerType::LoadState::UPLOADED ? "UPLOADED" : \
loadState == TextureManagerType::LoadState::CANCELLED ? "CANCELLED" : \
+ loadState == TextureManagerType::LoadState::MASK_CANCELLED ? "MASK_CANCELLED" : \
loadState == TextureManagerType::LoadState::LOAD_FAILED ? "LOAD_FAILED" : \
"Unknown"
// clang-format on
Texture TextureCacheManager::GetTexture(const TextureCacheManager::TextureId& textureId, uint32_t textureIndex)
{
- Texture texture; // empty handle
+ Texture texture; // empty handle
TextureCacheIndex cacheIndex = GetCacheIndexFromId(textureId);
switch(static_cast<TextureCacheIndexType>(cacheIndex.detailValue.type))
void TextureCacheManager::RemoveCache(TextureCacheManager::TextureInfo& textureInfo)
{
- TextureCacheIndex textureInfoIndex = GetCacheIndexFromId(textureInfo.textureId);
- bool removeTextureInfo = false;
+ TextureCacheIndex textureInfoIndex = GetCacheIndexFromId(textureInfo.textureId);
+ bool removeTextureInfo = false;
DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureCacheManager::Remove(textureId:%d) url:%s\n cacheIdx:%d loadState:%s reference count = %d\n", textureInfo.textureId, textureInfo.url.GetUrl().c_str(), textureInfoIndex.GetIndex(), GET_LOAD_STATE_STRING(textureInfo.loadState), textureInfo.referenceCount);
}
removeTextureInfo = true;
}
- else if(textureInfo.loadState == LoadState::LOADING || textureInfo.loadState == LoadState::MASK_APPLYING)
+ else if(textureInfo.loadState == LoadState::LOADING)
{
// We mark the textureInfo for removal.
// Once the load has completed, this method will be called again.
textureInfo.loadState = LoadState::CANCELLED;
}
+ else if(textureInfo.loadState == LoadState::MASK_APPLYING)
+ {
+ // We mark the textureInfo for removal.
+ // Once the load has completed, this method will be called again.
+ textureInfo.loadState = LoadState::MASK_CANCELLED;
+ }
else
{
// In other states, we are not waiting for a load so we are safe to remove the TextureInfo data.
loadState == TextureManagerType::LoadState::MASK_APPLIED ? "MASK_APPLIED" : \
loadState == TextureManagerType::LoadState::UPLOADED ? "UPLOADED" : \
loadState == TextureManagerType::LoadState::CANCELLED ? "CANCELLED" : \
+ loadState == TextureManagerType::LoadState::MASK_CANCELLED ? "MASK_CANCELLED" : \
loadState == TextureManagerType::LoadState::LOAD_FAILED ? "LOAD_FAILED" : \
"Unknown"
// clang-format on
// Update preMultiplyOnLoad value. It should be changed according to preMultiplied value of the cached info.
preMultiplyOnLoad = mTextureCacheManager[cacheIndex].preMultiplied ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture id@%d, textureId=%d, frameindex=%d, premultiplied=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, frameIndex, mTextureCacheManager[cacheIndex].preMultiplied ? 1 : 0);
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) Using cached texture id@%d, textureId=%d, maskTextureId=%d, frameindex=%d, premultiplied=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, frameIndex, mTextureCacheManager[cacheIndex].preMultiplied ? 1 : 0);
}
if(textureId == INVALID_TEXTURE_ID) // There was no caching, or caching not required
// Cache new texutre, and get cacheIndex.
cacheIndex = mTextureCacheManager.AppendCache(TextureInfo(textureId, maskTextureId, url, desiredSize, contentScale, fittingMode, samplingMode, false, cropToMask, useAtlas, textureHash, orientationCorrection, preMultiply, animatedImageLoading, frameIndex, loadYuvPlanes));
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d, frameindex=%d premultiply=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, frameIndex, preMultiply);
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d, maskTextureId=%d, frameindex=%d premultiply=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, frameIndex, preMultiply);
}
// The below code path is common whether we are using the cache or not.
TextureManager::LoadState::WAITING_FOR_MASK != textureInfo.loadState &&
TextureManager::LoadState::MASK_APPLYING != textureInfo.loadState &&
TextureManager::LoadState::MASK_APPLIED != textureInfo.loadState &&
- TextureManager::LoadState::CANCELLED != textureInfo.loadState)
+ TextureManager::LoadState::CANCELLED != textureInfo.loadState &&
+ TextureManager::LoadState::MASK_CANCELLED != textureInfo.loadState)
{
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "TextureManager::RequestLoad( url=%s observer=%p ) ForcedReload cacheIndex:%d, textureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId);
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "TextureManager::RequestLoad( url=%s observer=%p ) ForcedReload cacheIndex:%d, textureId=%d, maskTextureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex.GetIndex(), textureId, maskTextureId);
textureInfo.loadState = TextureManager::LoadState::NOT_STARTED;
}
ObserveTexture(textureInfo, observer);
break;
}
+ case TextureManager::LoadState::MASK_CANCELLED:
+ {
+ // A cancelled texture hasn't finished mask applying yet. Treat as a mask applying texture
+ // (it's ref count has already been incremented, above)
+ textureInfo.loadState = TextureManager::LoadState::MASK_APPLYING;
+ ObserveTexture(textureInfo, observer);
+ break;
+ }
case TextureManager::LoadState::LOAD_FINISHED:
{
// Loading has already completed.
{
TextureManager::TextureId maskTextureId = INVALID_TEXTURE_ID;
TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]);
- // We only need to consider maskTextureId when texture's loadState is not CANCELLED. Because it is already deleted.
- if(textureInfo.loadState != LoadState::CANCELLED)
+ // We only need to consider maskTextureId when texture's loadState is not cancelled. Because it is already deleted.
+ if(textureInfo.loadState != LoadState::CANCELLED && textureInfo.loadState != LoadState::MASK_CANCELLED)
{
if(textureInfo.maskTextureId != INVALID_TEXTURE_ID)
{
}
}
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::Remove( textureId=%d observer=%p ) cacheIndex:%d removal maskTextureId=%d, loadingQueueTextureId=%d, loadState=%s\n", textureId, observer, textureCacheIndex.GetIndex(), maskTextureId, mLoadingQueueTextureId, GET_LOAD_STATE_STRING(textureInfo.loadState));
+
// the case that LoadingQueue is working.
if(mLoadingQueueTextureId != INVALID_TEXTURE_ID)
{
}
case LoadState::LOADING:
case LoadState::CANCELLED:
+ case LoadState::MASK_CANCELLED:
case LoadState::LOAD_FINISHED:
case LoadState::WAITING_FOR_MASK:
case LoadState::MASK_APPLYING:
DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, " textureId:%d Url:%s CacheIndex:%d LoadState: %s\n", textureInfo.textureId, textureInfo.url.GetUrl().c_str(), cacheIndex.GetIndex(), GET_LOAD_STATE_STRING(textureInfo.loadState));
- if(textureInfo.loadState != LoadState::CANCELLED)
+ if(textureInfo.loadState != LoadState::CANCELLED && textureInfo.loadState != LoadState::MASK_CANCELLED)
{
// textureInfo can be invalidated after this call (as the mTextureInfoContainer may be modified)
PostLoad(textureInfo, pixelBuffers);
UploadTextures(pixelBuffers, maskTextureInfo);
}
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::CheckForWaitingTexture(): maskTextureId=%d, maskTextureUrl=%s\n", maskTextureInfo.textureId, maskTextureInfo.url.GetUrl().c_str());
+
// Search the cache, checking if any texture has this texture id as a maskTextureId
const std::size_t size = mTextureCacheManager.size();
pixelBuffers.push_back(textureInfo.pixelBuffer);
UploadTextures(pixelBuffers, textureInfo);
+ // Increase reference counts for notify required textureId.
+ // Now we can assume that we don't remove & re-assign this textureId
+ // during NotifyObserver signal emit.
+ maskTextureInfo.referenceCount++;
+ textureInfo.referenceCount++;
+
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::CheckForWaitingTexture(): Ready to notify textureId=%d\n", textureInfo.textureId);
+
notifyRequiredTextureIds.push_back(textureInfo.textureId);
}
}
- else
+ else // maskTextureInfo.loadState == LoadState::LOAD_FAILED
{
// Url texture load success, But alpha mask texture load failed. Run as normal image upload.
DALI_LOG_ERROR("Alpha mask image loading failed! Image will not be masked\n");
pixelBuffers.push_back(textureInfo.pixelBuffer);
UploadTextures(pixelBuffers, textureInfo);
+ // Increase reference counts for notify required textureId.
+ // Now we can assume that we don't remove & re-assign this textureId
+ // during NotifyObserver signal emit.
+ maskTextureInfo.referenceCount++;
+ textureInfo.referenceCount++;
+
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::CheckForWaitingTexture(): Ready to notify textureId=%d\n", textureInfo.textureId);
+
notifyRequiredTextureIds.push_back(textureInfo.textureId);
}
}
NotifyObservers(textureInfo, true);
}
}
+
+ // Decrease reference count
+ for(const auto textureId : notifyRequiredTextureIds)
+ {
+ Remove(textureId, nullptr);
+ }
}
void TextureManager::ApplyMask(TextureManager::TextureInfo& textureInfo, const TextureManager::TextureId& maskTextureId)
MASK_APPLIED, ///< Loading has finished, Mask is applyied by GPU
UPLOADED, ///< Uploaded and ready. (For GPU upload only)
CANCELLED, ///< Removed before loading completed
+ MASK_CANCELLED, ///< Removed before mask applying completed
LOAD_FAILED ///< Async loading failed, e.g. connection problem
};
AnimatedVectorImageVisualPtr AnimatedVectorImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties)
{
- AnimatedVectorImageVisualPtr visual(new AnimatedVectorImageVisual(factoryCache, shaderFactory, imageUrl));
+ AnimatedVectorImageVisualPtr visual(new AnimatedVectorImageVisual(factoryCache, shaderFactory, imageUrl, ImageDimensions{}));
visual->SetProperties(properties);
visual->Initialize();
return visual;
}
-AnimatedVectorImageVisualPtr AnimatedVectorImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl)
+AnimatedVectorImageVisualPtr AnimatedVectorImageVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size)
{
- AnimatedVectorImageVisualPtr visual(new AnimatedVectorImageVisual(factoryCache, shaderFactory, imageUrl));
+ AnimatedVectorImageVisualPtr visual(new AnimatedVectorImageVisual(factoryCache, shaderFactory, imageUrl, size));
visual->Initialize();
return visual;
}
-AnimatedVectorImageVisual::AnimatedVectorImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl)
+AnimatedVectorImageVisual::AnimatedVectorImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size)
: Visual::Base(factoryCache, Visual::FittingMode::FILL, static_cast<Toolkit::Visual::Type>(Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE)),
mUrl(imageUrl),
mAnimationData(),
mImageVisualShaderFactory(shaderFactory),
mVisualSize(),
mVisualScale(Vector2::ONE),
+ mDesiredSize(size),
mPlacementActor(),
mPlayState(DevelImageVisual::PlayState::STOPPED),
mEventCallback(nullptr),
void AnimatedVectorImageVisual::GetNaturalSize(Vector2& naturalSize)
{
- if(mVisualSize != Vector2::ZERO)
+ if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0)
+ {
+ naturalSize.x = mDesiredSize.GetWidth();
+ naturalSize.y = mDesiredSize.GetHeight();
+ }
+ else if(mVisualSize != Vector2::ZERO)
{
naturalSize = mVisualSize;
}
Property::Map layerInfo;
mVectorAnimationTask->GetLayerInfo(layerInfo);
map.Insert(Toolkit::DevelImageVisual::Property::CONTENT_INFO, layerInfo);
+
+ map.Insert(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, IsSynchronousLoadingRequired());
+ map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth());
+ map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight());
}
void AnimatedVectorImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const
{
DoSetProperty(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, keyValue.second);
}
+ else if(keyValue.first == IMAGE_DESIRED_WIDTH)
+ {
+ DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_WIDTH, keyValue.second);
+ }
+ else if(keyValue.first == IMAGE_DESIRED_HEIGHT)
+ {
+ DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, keyValue.second);
+ }
}
}
}
break;
}
+ case Toolkit::ImageVisual::Property::DESIRED_WIDTH:
+ {
+ int32_t desiredWidth = 0;
+ if(value.Get(desiredWidth))
+ {
+ mDesiredSize.SetWidth(desiredWidth);
+ }
+ break;
+ }
+
+ case Toolkit::ImageVisual::Property::DESIRED_HEIGHT:
+ {
+ int32_t desiredHeight = 0;
+ if(value.Get(desiredHeight))
+ {
+ mDesiredSize.SetHeight(desiredHeight);
+ }
+ break;
+ }
}
}
void AnimatedVectorImageVisual::SetVectorImageSize()
{
- uint32_t width = static_cast<uint32_t>(mVisualSize.width * mVisualScale.width);
- uint32_t height = static_cast<uint32_t>(mVisualSize.height * mVisualScale.height);
+ uint32_t width, height;
+ if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0)
+ {
+ width = mDesiredSize.GetWidth();
+ height = mDesiredSize.GetHeight();
+ }
+ else
+ {
+ width = static_cast<uint32_t>(mVisualSize.width * mVisualScale.width);
+ height = static_cast<uint32_t>(mVisualSize.height * mVisualScale.height);
+ }
if(mAnimationData.width != width || mAnimationData.height != height)
{
* @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
* @param[in] shaderFactory The ImageVisualShaderFactory object
* @param[in] imageUrl The URL to an animated vector image to use
+ * @param[in] size The width and height of the rasterized buffer. The visual size will be used if these are 0.
* @return A smart-pointer to the newly allocated visual.
*/
- static AnimatedVectorImageVisualPtr New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl);
+ static AnimatedVectorImageVisualPtr New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size = ImageDimensions());
public: // from Visual
/**
* @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
* @param[in] shaderFactory The ImageVisualShaderFactory object
* @param[in] imageUrl The URL to an animated vector image to use
+ * @param[in] size The width and height of the rasterized buffer. The visual size will be used if these are 0.
*/
- AnimatedVectorImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl);
+ AnimatedVectorImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size);
/**
* @brief A reference counted object may only be deleted by calling Unreference().
PropertyNotification mSizeNotification;
Vector2 mVisualSize;
Vector2 mVisualScale;
+ Dali::ImageDimensions mDesiredSize{};
WeakHandle<Actor> mPlacementActor;
DevelImageVisual::PlayState::Type mPlayState;
CallbackBase* mEventCallback; // Not owned
case Toolkit::ImageVisual::Property::DESIRED_WIDTH:
{
- float desiredWidth = 0.0f;
+ int32_t desiredWidth = 0;
if(value.Get(desiredWidth))
{
mDesiredSize.SetWidth(desiredWidth);
case Toolkit::ImageVisual::Property::DESIRED_HEIGHT:
{
- float desiredHeight = 0.0f;
+ int32_t desiredHeight = 0;
if(value.Get(desiredHeight))
{
mDesiredSize.SetHeight(desiredHeight);
SvgVisualPtr SvgVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, const Property::Map& properties)
{
- SvgVisualPtr svgVisual(new SvgVisual(factoryCache, shaderFactory, imageUrl));
+ SvgVisualPtr svgVisual(new SvgVisual(factoryCache, shaderFactory, imageUrl, ImageDimensions{}));
svgVisual->SetProperties(properties);
svgVisual->Initialize();
return svgVisual;
}
-SvgVisualPtr SvgVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl)
+SvgVisualPtr SvgVisual::New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size)
{
- SvgVisualPtr svgVisual(new SvgVisual(factoryCache, shaderFactory, imageUrl));
+ SvgVisualPtr svgVisual(new SvgVisual(factoryCache, shaderFactory, imageUrl, size));
svgVisual->Initialize();
return svgVisual;
}
-SvgVisual::SvgVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl)
+SvgVisual::SvgVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size)
: Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::SVG),
mImageVisualShaderFactory(shaderFactory),
mAtlasRect(FULL_TEXTURE_RECT),
mDefaultHeight(0),
mPlacementActor(),
mRasterizedSize(Vector2::ZERO),
+ mDesiredSize(size),
mLoadFailed(false),
mAttemptAtlasing(false)
{
{
DoSetProperty(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, keyValue.second);
}
+ else if(keyValue.first == IMAGE_DESIRED_WIDTH)
+ {
+ DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_WIDTH, keyValue.second);
+ }
+ else if(keyValue.first == IMAGE_DESIRED_HEIGHT)
+ {
+ DoSetProperty(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, keyValue.second);
+ }
}
}
}
break;
}
+ case Toolkit::ImageVisual::Property::DESIRED_WIDTH:
+ {
+ int32_t desiredWidth = 0;
+ if(value.Get(desiredWidth))
+ {
+ mDesiredSize.SetWidth(desiredWidth);
+ }
+ break;
+ }
+ case Toolkit::ImageVisual::Property::DESIRED_HEIGHT:
+ {
+ int32_t desiredHeight = 0;
+ if(value.Get(desiredHeight))
+ {
+ mDesiredSize.SetHeight(desiredHeight);
+ }
+ break;
+ }
}
}
void SvgVisual::GetNaturalSize(Vector2& naturalSize)
{
- if(mLoadFailed && mImpl->mRenderer)
+ if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0)
+ {
+ naturalSize.x = mDesiredSize.GetWidth();
+ naturalSize.y = mDesiredSize.GetHeight();
+ }
+ else if(mLoadFailed && mImpl->mRenderer)
{
// Load failed, use broken image size
auto textureSet = mImpl->mRenderer.GetTextures();
map.Insert(Toolkit::ImageVisual::Property::ATLASING, mAttemptAtlasing);
}
map.Insert(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, IsSynchronousLoadingRequired());
+ map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth());
+ map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight());
}
void SvgVisual::DoCreateInstancePropertyMap(Property::Map& map) const
void SvgVisual::OnSetTransform()
{
- Vector2 visualSize = mImpl->mTransform.GetVisualSize(mImpl->mControlSize);
-
if(IsOnScene() && !mLoadFailed)
{
- if(visualSize != mRasterizedSize || mDefaultWidth == 0 || mDefaultHeight == 0)
+ Vector2 size;
+ if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0)
+ {
+ // Use desired size
+ size = Vector2(mDesiredSize.GetWidth(), mDesiredSize.GetHeight());
+ }
+ else
+ {
+ // Use visual size
+ size = mImpl->mTransform.GetVisualSize(mImpl->mControlSize);
+ }
+
+ if(size != mRasterizedSize || mDefaultWidth == 0 || mDefaultHeight == 0)
{
- mRasterizedSize = visualSize;
- AddRasterizationTask(visualSize);
+ mRasterizedSize = size;
+ AddRasterizationTask(size);
}
}
* @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
* @param[in] shaderFactory The ImageVisualShaderFactory object
* @param[in] imageUrl The URL to svg resource to use
+ * @param[in] size The width and height of the rasterized buffer. The visual size will be used if these are 0.
* @return A smart-pointer to the newly allocated visual.
*/
- static SvgVisualPtr New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl);
+ static SvgVisualPtr New(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size = ImageDimensions());
public: // from Visual
/**
* @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
* @param[in] shaderFactory The ImageVisualShaderFactory object
* @param[in] imageUrl The URL to svg resource to use
+ * @param[in] size The width and height of the rasterized buffer. The visual size will be used if these are 0.
*/
- SvgVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl);
+ SvgVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size);
/**
* @brief A reference counted object may only be deleted by calling Unreference().
uint32_t mDefaultHeight;
WeakHandle<Actor> mPlacementActor;
Vector2 mRasterizedSize;
+ Dali::ImageDimensions mDesiredSize{};
bool mLoadFailed;
bool mAttemptAtlasing; ///< If true will attempt atlasing, otherwise create unique texture
};
case VisualUrl::TVG:
case VisualUrl::SVG:
{
- visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
+ visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size);
break;
}
case VisualUrl::GIF:
}
case VisualUrl::JSON:
{
- visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
+ visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size);
break;
}
case VisualUrl::REGULAR_IMAGE:
{
const unsigned int TOOLKIT_MAJOR_VERSION = 2;
const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 42;
+const unsigned int TOOLKIT_MICRO_VERSION = 43;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-toolkit
Summary: Dali 3D engine Toolkit
-Version: 2.1.42
+Version: 2.1.43
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT