[Tizen] Support asan build option tizen
authorSeungho Baek <sbsh.baek@samsung.com>
Mon, 13 May 2024 05:21:28 +0000 (14:21 +0900)
committerSeungho Baek <sbsh.baek@samsung.com>
Mon, 13 May 2024 05:21:39 +0000 (14:21 +0900)
This reverts commit ce5eaef843a6ed327f97ffd6a98bf6d5ef112d1c.

Change-Id: Ie671d5602c9dc3e57c97ad9e052c782d73bf0800

114 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Accessible.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Accessibility-Value.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor-impl.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-adaptor.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-clipboard.h
automated-tests/src/dali-toolkit/utc-Dali-AnimatedImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-AnimatedVectorImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
dali-scene3d/internal/controls/scene-view/scene-view-impl.cpp
dali-scene3d/internal/controls/scene-view/scene-view-impl.h
dali-scene3d/internal/graphics/shaders/shadow-map-shader.vert
dali-toolkit/devel-api/controls/control-accessible.cpp
dali-toolkit/devel-api/controls/control-depth-index-ranges.h
dali-toolkit/devel-api/controls/control-devel.h
dali-toolkit/devel-api/controls/text-controls/text-editor-devel.cpp
dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h
dali-toolkit/devel-api/controls/text-controls/text-field-devel.cpp
dali-toolkit/devel-api/controls/text-controls/text-field-devel.h
dali-toolkit/devel-api/controls/text-controls/text-style-properties-devel.h
dali-toolkit/devel-api/text/range.h
dali-toolkit/devel-api/text/spans/base-span.h
dali-toolkit/devel-api/visual-factory/visual-base.h
dali-toolkit/devel-api/visuals/image-visual-properties-devel.h
dali-toolkit/internal/builder/tree-node-manipulator.cpp
dali-toolkit/internal/builder/tree-node-manipulator.h
dali-toolkit/internal/controls/buttons/check-box-button-impl.cpp
dali-toolkit/internal/controls/buttons/push-button-impl.cpp
dali-toolkit/internal/controls/buttons/radio-button-impl.cpp
dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/controls/control/control-data-impl.h
dali-toolkit/internal/controls/gl-view/drawable-view-impl.cpp
dali-toolkit/internal/controls/gl-view/drawable-view-impl.h
dali-toolkit/internal/controls/gl-view/gl-view-impl.cpp
dali-toolkit/internal/controls/gl-view/gl-view-impl.h
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/controls/progress-bar/progress-bar-impl.cpp
dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp
dali-toolkit/internal/controls/slider/slider-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.h
dali-toolkit/internal/controls/text-controls/text-editor-property-handler.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.h
dali-toolkit/internal/controls/text-controls/text-field-property-handler.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/controls/web-view/web-view-impl.cpp
dali-toolkit/internal/text/controller/text-controller-event-handler.cpp
dali-toolkit/internal/text/controller/text-controller-impl.cpp
dali-toolkit/internal/text/controller/text-controller-impl.h
dali-toolkit/internal/text/controller/text-controller-text-updater.cpp
dali-toolkit/internal/text/controller/text-controller-text-updater.h
dali-toolkit/internal/text/controller/text-controller.cpp
dali-toolkit/internal/text/controller/text-controller.h
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/rendering/text-typesetter.cpp
dali-toolkit/internal/text/rendering/view-model.cpp
dali-toolkit/internal/text/rendering/view-model.h
dali-toolkit/internal/text/spannable/span-ranges-container-impl.h
dali-toolkit/internal/text/spannable/spannable-impl.h
dali-toolkit/internal/text/spannable/spannable-string-impl.h
dali-toolkit/internal/text/spannable/spanned-impl.h
dali-toolkit/internal/text/spannable/spans/base-span-impl.h
dali-toolkit/internal/text/string-text/character-sequence-impl.h
dali-toolkit/internal/text/string-text/range-impl.h
dali-toolkit/internal/text/text-effects-style.cpp
dali-toolkit/internal/text/text-model-interface.h
dali-toolkit/internal/text/text-model.cpp
dali-toolkit/internal/text/text-model.h
dali-toolkit/internal/text/text-scroller.cpp
dali-toolkit/internal/text/text-scroller.h
dali-toolkit/internal/text/text-view-interface.h
dali-toolkit/internal/text/text-view.cpp
dali-toolkit/internal/text/text-view.h
dali-toolkit/internal/text/visual-model-impl.cpp
dali-toolkit/internal/text/visual-model-impl.h
dali-toolkit/internal/texture-manager/texture-manager-impl.cpp
dali-toolkit/internal/texture-manager/texture-manager-impl.h
dali-toolkit/internal/visuals/animated-image/animated-image-visual.cpp
dali-toolkit/internal/visuals/animated-image/animated-image-visual.h
dali-toolkit/internal/visuals/animated-image/fixed-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/image-cache.cpp
dali-toolkit/internal/visuals/animated-image/image-cache.h
dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.cpp
dali-toolkit/internal/visuals/animated-image/rolling-animated-image-cache.h
dali-toolkit/internal/visuals/animated-image/rolling-image-cache.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.cpp
dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-manager.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-manager.h
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-task.h
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.cpp
dali-toolkit/internal/visuals/animated-vector-image/vector-animation-thread.h
dali-toolkit/internal/visuals/gradient/gradient-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/internal/visuals/text/text-visual.cpp
dali-toolkit/internal/visuals/text/text-visual.h
dali-toolkit/internal/visuals/visual-base-data-impl.cpp
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/internal/visuals/visual-string-constants.cpp
dali-toolkit/internal/visuals/visual-string-constants.h
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index f76c4a0..eee08a7 100644 (file)
 // test harness headers before dali headers.
 #include <dali-toolkit-test-suite-utils.h>
 
-#include <dali.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
+#include <dali.h>
 
-#include <dali/devel-api/adaptor-framework/accessibility.h>
 #include <dali/devel-api/adaptor-framework/accessibility-bridge.h>
+#include <dali/devel-api/adaptor-framework/accessibility.h>
 #include <dali/devel-api/atspi-interfaces/accessible.h>
 
 #include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
@@ -45,10 +46,10 @@ int utcDaliAccessibilityCheckBoxButtonGetStates(void)
   ToolkitTestApplication application;
 
   auto check_box_button = Toolkit::CheckBoxButton::New();
-  auto q = Dali::Accessibility::Accessible::Get( check_box_button );
-  DALI_TEST_CHECK( q );
+  auto q                = Dali::Accessibility::Accessible::Get(check_box_button);
+  DALI_TEST_CHECK(q);
   auto states = q->GetStates();
-  DALI_TEST_EQUALS( (int) states[ Dali::Accessibility::State::SELECTABLE ], (int) true, TEST_LOCATION );
+  DALI_TEST_EQUALS((int)states[Dali::Accessibility::State::SELECTABLE], (int)true, TEST_LOCATION);
 
   END_TEST;
 }
@@ -60,9 +61,9 @@ int utcDaliAccessibilityCheckLabelText(void)
   auto check_box_button = Toolkit::CheckBoxButton::New();
   //check_box_button.SetLabelText( "button" );
   check_box_button.SetProperty(Toolkit::Button::Property::LABEL, "button");
-  auto q = Dali::Accessibility::Accessible::Get( check_box_button );
-  DALI_TEST_CHECK( q );
-  DALI_TEST_EQUALS( q->GetName(), "button", TEST_LOCATION );
+  auto q = Dali::Accessibility::Accessible::Get(check_box_button);
+  DALI_TEST_CHECK(q);
+  DALI_TEST_EQUALS(q->GetName(), "button", TEST_LOCATION);
 
   END_TEST;
 }
@@ -77,7 +78,7 @@ int UtcDaliAccessibilityCheckShowingState(void)
   parentButton.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
   parentButton.SetProperty(Actor::Property::POSITION, Dali::Vector2(0.0f, 0.0f));
   parentButton.SetProperty(Actor::Property::SIZE, Dali::Vector2(200.0f, 200.0f));
-  application.GetScene().Add( parentButton );
+  application.GetScene().Add(parentButton);
 
   // Toatally inside of parent
   auto buttonA = Toolkit::PushButton::New();
@@ -99,7 +100,7 @@ int UtcDaliAccessibilityCheckShowingState(void)
   auto buttonC = Toolkit::PushButton::New();
   buttonC.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
   buttonC.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
-  buttonC.SetProperty(Actor::Property::POSITION, Dali::Vector2(100.0f,100.0f));
+  buttonC.SetProperty(Actor::Property::POSITION, Dali::Vector2(100.0f, 100.0f));
   buttonC.SetProperty(Actor::Property::SIZE, Dali::Vector2(200.0f, 200.0f));
   parentButton.Add(buttonC);
 
@@ -109,17 +110,17 @@ int UtcDaliAccessibilityCheckShowingState(void)
   auto q = Dali::Accessibility::Accessible::Get(buttonA);
   DALI_TEST_CHECK(q);
   auto states = q->GetStates();
-  DALI_TEST_EQUALS((int) states[Dali::Accessibility::State::SHOWING], (int) true, TEST_LOCATION);
+  DALI_TEST_EQUALS((int)states[Dali::Accessibility::State::SHOWING], (int)true, TEST_LOCATION);
 
   q = Dali::Accessibility::Accessible::Get(buttonB);
   DALI_TEST_CHECK(q);
   states = q->GetStates();
-  DALI_TEST_EQUALS((int) states[Dali::Accessibility::State::SHOWING], (int) true, TEST_LOCATION);
+  DALI_TEST_EQUALS((int)states[Dali::Accessibility::State::SHOWING], (int)true, TEST_LOCATION);
 
   q = Dali::Accessibility::Accessible::Get(buttonC);
   DALI_TEST_CHECK(q);
   states = q->GetStates();
-  DALI_TEST_EQUALS((int) states[Dali::Accessibility::State::SHOWING], (int) true, TEST_LOCATION);
+  DALI_TEST_EQUALS((int)states[Dali::Accessibility::State::SHOWING], (int)true, TEST_LOCATION);
 
   // Make SHOWING object invisible
   buttonC.SetProperty(Actor::Property::VISIBLE, false);
@@ -128,7 +129,7 @@ int UtcDaliAccessibilityCheckShowingState(void)
   application.Render(16);
 
   states = q->GetStates();
-  DALI_TEST_EQUALS((int) states[Dali::Accessibility::State::SHOWING], (int) false, TEST_LOCATION);
+  DALI_TEST_EQUALS((int)states[Dali::Accessibility::State::SHOWING], (int)false, TEST_LOCATION);
 
   // Make SHOWING parent invisible
   parentButton.SetProperty(Actor::Property::VISIBLE, false);
@@ -139,7 +140,7 @@ int UtcDaliAccessibilityCheckShowingState(void)
   q = Dali::Accessibility::Accessible::Get(buttonA);
   DALI_TEST_CHECK(q);
   states = q->GetStates();
-  DALI_TEST_EQUALS((int) states[Dali::Accessibility::State::SHOWING], (int) false, TEST_LOCATION);
+  DALI_TEST_EQUALS((int)states[Dali::Accessibility::State::SHOWING], (int)false, TEST_LOCATION);
 
   END_TEST;
 }
@@ -206,3 +207,70 @@ int utcDaliAutomationId(void)
 
   END_TEST;
 }
+
+int utcDaliImgSrc(void)
+{
+  ToolkitTestApplication application;
+  const std::string      imageSrcKey = "imgSrc";
+  // Check that imgSrc is NOT added for non-image view w/ no additional property
+  {
+    const auto checkBoxButton    = Toolkit::CheckBoxButton::New();
+    const auto controlAccessible = Dali::Accessibility::Accessible::Get(checkBoxButton);
+    auto       attributes        = controlAccessible->GetAttributes();
+    DALI_TEST_CHECK(attributes.find(imageSrcKey) == attributes.end());
+  }
+
+  // Check that imgSrc is NOT added for non-image view w/ additional properties
+  {
+    const auto textLabel         = Toolkit::TextLabel::New("Hello");
+    const auto controlAccessible = Dali::Accessibility::Accessible::Get(textLabel);
+    auto       attributes        = controlAccessible->GetAttributes();
+    DALI_TEST_CHECK(attributes.find(imageSrcKey) == attributes.end());
+  }
+
+  // Check that imgSrc is added for image view w/ Url
+  {
+    const std::string imagePath         = "gallery-small-1.jpg";
+    const auto        imageView         = Toolkit::ImageView::New(imagePath);
+    const auto        controlAccessible = Dali::Accessibility::Accessible::Get(imageView);
+    auto              attributes        = controlAccessible->GetAttributes();
+    DALI_TEST_CHECK(attributes.find(imageSrcKey) != attributes.end());
+    DALI_TEST_EQUALS(attributes[imageSrcKey], imagePath, TEST_LOCATION);
+  }
+
+  // Check that imgSrc is added for image view w/ imageMap; single url case
+  {
+    const std::string imagePathForImageMap = "icon-edit.png";
+    Property::Map     imageMap;
+    imageMap[Toolkit::ImageVisual::Property::URL]            = imagePathForImageMap;
+    imageMap[Toolkit::ImageVisual::Property::RELEASE_POLICY] = Toolkit::ImageVisual::ReleasePolicy::DETACHED;
+
+    auto imageView = Toolkit::ImageView::New();
+    imageView.SetProperty(Toolkit::ImageView::Property::IMAGE, imageMap);
+
+    const auto controlAccessible = Dali::Accessibility::Accessible::Get(imageView);
+    auto       attributes        = controlAccessible->GetAttributes();
+    DALI_TEST_CHECK(attributes.find(imageSrcKey) != attributes.end());
+    DALI_TEST_EQUALS(attributes[imageSrcKey], imagePathForImageMap, TEST_LOCATION);
+  }
+
+  // Check that imgSrc is added for image view w/ imageMap; url array returns first element
+  {
+    const std::string image1 = "application-icon-20.png";
+    const std::string image2 = "application-icon-21.png";
+    Property::Map     imageMap;
+    Property::Array   urls{image1, image2};
+    imageMap[Toolkit::ImageVisual::Property::URL]            = urls;
+    imageMap[Toolkit::ImageVisual::Property::RELEASE_POLICY] = Toolkit::ImageVisual::ReleasePolicy::DETACHED;
+
+    auto imageView = Toolkit::ImageView::New();
+    imageView.SetProperty(Toolkit::ImageView::Property::IMAGE, imageMap);
+
+    const auto controlAccessible = Dali::Accessibility::Accessible::Get(imageView);
+    auto       attributes        = controlAccessible->GetAttributes();
+    DALI_TEST_CHECK(attributes.find(imageSrcKey) != attributes.end());
+    DALI_TEST_EQUALS(attributes[imageSrcKey], image1, TEST_LOCATION);
+  }
+
+  END_TEST;
+}
index ff95317..d19755a 100644 (file)
 #include <dali/devel-api/adaptor-framework/accessibility.h>
 #include <dali/devel-api/adaptor-framework/accessibility-bridge.h>
 #include <dali/devel-api/atspi-interfaces/accessible.h>
+#include <dali/devel-api/atspi-interfaces/component.h>
 #include <dali/devel-api/atspi-interfaces/value.h>
 
 #include <dali-toolkit/devel-api/controls/scroll-bar/scroll-bar.h>
 
+#include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/accessibility-test-utils.h>
 #include <automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/dbus-wrapper.h>
 
 using namespace Dali::Accessibility;
@@ -87,17 +89,20 @@ int utcDaliAccessibilityProgressBarGetMinimumIncrement(void)
 int utcDaliAccessibilityProgressBarGetSetCurrent(void)
 {
   ToolkitTestApplication application;
+  Dali::Accessibility::TestEnableSC(true);
 
   Toolkit::ProgressBar progress_bar = Toolkit::ProgressBar::New();
   auto q = Dali::Accessibility::Accessible::Get(progress_bar);
   auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
   DALI_TEST_CHECK( x );
+  DALI_TEST_CHECK(Dali::Accessibility::Component::DownCast(q)->GrabHighlight());
   DALI_TEST_EQUALS( x->GetCurrent(), 0.0, TEST_LOCATION );
   DALI_TEST_EQUALS( x->SetCurrent( 2.0 ), false, TEST_LOCATION );
   DALI_TEST_EQUALS( x->SetCurrent( 0.25 ), true, TEST_LOCATION );
   DALI_TEST_EQUALS( x->GetCurrent(), 0.25, TEST_LOCATION );
   DALI_TEST_EQUALS( x->GetValueText().empty(), true, TEST_LOCATION ); // not implemented
 
+  Dali::Accessibility::TestEnableSC(false);
   END_TEST;
 }
 
@@ -169,6 +174,7 @@ int utcDaliAccessibilityScrollBarGetMinimumIncrement(void)
 int utcDaliAccessibilityScrollBarGetSetCurrent(void)
 {
   ToolkitTestApplication application;
+  Dali::Accessibility::TestEnableSC(true);
 
   // Create a source actor that owns the scroll properties required by the scroll bar
   Actor sourceActor = Actor::New();
@@ -189,12 +195,14 @@ int utcDaliAccessibilityScrollBarGetSetCurrent(void)
   auto q = Dali::Accessibility::Accessible::Get(scroll_bar);
   auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
   DALI_TEST_CHECK( x );
+  DALI_TEST_CHECK(Dali::Accessibility::Component::DownCast(q)->GrabHighlight());
   DALI_TEST_EQUALS( x->GetCurrent(), 0.0, TEST_LOCATION );
   DALI_TEST_EQUALS( x->SetCurrent( 1000.0 ), false, TEST_LOCATION );
   DALI_TEST_EQUALS( x->SetCurrent( 50.0 ), false, TEST_LOCATION );
   DALI_TEST_EQUALS( x->GetCurrent(), 0.0, TEST_LOCATION );
   DALI_TEST_EQUALS( x->GetValueText().empty(), true, TEST_LOCATION ); // not implemented
 
+  Dali::Accessibility::TestEnableSC(false);
   END_TEST;
 }
 
@@ -240,11 +248,13 @@ int utcDaliAccessibilitySliderGetMinimumIncrement(void)
 int utcDaliAccessibilitySliderGetSetCurrent(void)
 {
   ToolkitTestApplication application;
+  Dali::Accessibility::TestEnableSC(true);
 
   Toolkit::Slider slider = Toolkit::Slider::New();
   auto q = Dali::Accessibility::Accessible::Get(slider);
   auto x = dynamic_cast< Dali::Accessibility::Value* >( q );
   DALI_TEST_CHECK( x );
+  DALI_TEST_CHECK(Dali::Accessibility::Component::DownCast(q)->GrabHighlight());
   DALI_TEST_EQUALS( x->GetCurrent(), 0.0, TEST_LOCATION );
   DALI_TEST_EQUALS( x->SetCurrent( 2.0 ), false, TEST_LOCATION );
   DALI_TEST_EQUALS( x->SetCurrent( 0.25 ), true, TEST_LOCATION );
@@ -269,5 +279,7 @@ int utcDaliAccessibilitySliderGetSetCurrent(void)
   // depending if the new value is greater/less than current value
   DALI_TEST_CHECK( x->SetCurrent( 0.2f ) );
   DALI_TEST_EQUALS( static_cast<float>( x->GetCurrent() ),  marks[2].Get<float>(), TEST_LOCATION );
+
+  Dali::Accessibility::TestEnableSC(false);
   END_TEST;
 }
index 6a3a84a..774cce1 100644 (file)
@@ -1362,3 +1362,44 @@ int UtcDaliTextControllerDeleteSurroundings(void)
 
   END_TEST;
 }
+
+int UtcDaliTextControllerMultipleInsert(void)
+{
+  tet_infoline(" UtcDaliTextControllerMultipleInsert");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  ConfigureTextField(controller);
+
+  // Get the implementation of the text controller
+  Controller::Impl& mImpl = Controller::Impl::GetImplementation(*controller.Get());
+
+  DALI_TEST_EQUALS(EventData::INACTIVE, mImpl.mEventData->mState, TEST_LOCATION);
+
+  InputMethodContext inputMethodContext = InputMethodContext::New();
+
+  // When maid thread is busy, multiple event might be executed.
+  InputMethodContext::EventData imfEvent1 = InputMethodContext::EventData(InputMethodContext::PRE_EDIT, "A", 0, 1);
+  InputMethodContext::EventData imfEvent2 = InputMethodContext::EventData(InputMethodContext::PRE_EDIT, "AAAAA", 0, 5);
+  controller->OnInputMethodContextEvent(inputMethodContext, imfEvent1);
+  controller->OnInputMethodContextEvent(inputMethodContext, imfEvent2);
+
+  // Perform a relayout
+  const Size size(application.GetScene().GetSize());
+
+  application.SendNotification();
+  application.Render();
+
+  controller->Relayout(size);
+
+  std::string text;
+  controller->GetText(text);
+
+  DALI_TEST_EQUALS("AAAAA", text, TEST_LOCATION);
+
+  tet_result(TET_PASS);
+
+  END_TEST;
+}
index 56b3b5e..262afcf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 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 "dummy-control.h"
 
 #include <dali-toolkit/dali-toolkit.h>
-#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 
 namespace Dali
 {
-
 namespace Toolkit
 {
-
 DummyControl::DummyControl()
 {
 }
 
 DummyControl::DummyControl(const DummyControl& control)
-: Control( control )
+: Control(control)
 {
 }
 
@@ -40,60 +38,60 @@ DummyControl::~DummyControl()
 {
 }
 
-DummyControl DummyControl::DownCast( BaseHandle handle )
+DummyControl DummyControl::DownCast(BaseHandle handle)
 {
   return Control::DownCast<DummyControl, DummyControlImpl>(handle);
 }
 
 DummyControl& DummyControl::operator=(const DummyControl& control)
 {
-  Control::operator=( control );
+  Control::operator=(control);
   return *this;
 }
 
 // Used to test signal connections
-void DummyControlImpl::CustomSlot1( Actor actor )
+void DummyControlImpl::CustomSlot1(Actor actor)
 {
   mCustomSlot1Called = true;
 }
 
-namespace {
-
+namespace
+{
 BaseHandle Create()
 {
   return DummyControlImpl::New();
 }
 
-DALI_TYPE_REGISTRATION_BEGIN( Toolkit::DummyControl, Toolkit::Control, Create );
+DALI_TYPE_REGISTRATION_BEGIN(Toolkit::DummyControl, Toolkit::Control, Create);
 DALI_TYPE_REGISTRATION_END()
 
 Dali::PropertyRegistration dummyControlVisualProperty01(
-  typeRegistration, "testVisual", Dali::Toolkit::DummyControl::Property::TEST_VISUAL, Dali::Property::MAP, &Dali::Toolkit::DummyControlImpl::SetProperty, &Dali::Toolkit::DummyControlImpl::GetProperty );
+  typeRegistration, "testVisual", Dali::Toolkit::DummyControl::Property::TEST_VISUAL, Dali::Property::MAP, &Dali::Toolkit::DummyControlImpl::SetProperty, &Dali::Toolkit::DummyControlImpl::GetProperty);
 
 Dali::PropertyRegistration dummyControlVisualProperty02(
-  typeRegistration, "testVisual2", Dali::Toolkit::DummyControl::Property::TEST_VISUAL2, Dali::Property::MAP, &Dali::Toolkit::DummyControlImpl::SetProperty, &Dali::Toolkit::DummyControlImpl::GetProperty );
+  typeRegistration, "testVisual2", Dali::Toolkit::DummyControl::Property::TEST_VISUAL2, Dali::Property::MAP, &Dali::Toolkit::DummyControlImpl::SetProperty, &Dali::Toolkit::DummyControlImpl::GetProperty);
 
 Dali::PropertyRegistration dummyControlVisualProperty03(
-  typeRegistration, "foregroundVisual", Dali::Toolkit::DummyControl::Property::FOREGROUND_VISUAL, Dali::Property::MAP, &Dali::Toolkit::DummyControlImpl::SetProperty, &Dali::Toolkit::DummyControlImpl::GetProperty );
+  typeRegistration, "foregroundVisual", Dali::Toolkit::DummyControl::Property::FOREGROUND_VISUAL, Dali::Property::MAP, &Dali::Toolkit::DummyControlImpl::SetProperty, &Dali::Toolkit::DummyControlImpl::GetProperty);
 
 Dali::PropertyRegistration dummyControlVisualProperty04(
-  typeRegistration, "focusVisual", Dali::Toolkit::DummyControl::Property::FOCUS_VISUAL, Dali::Property::MAP, &Dali::Toolkit::DummyControlImpl::SetProperty, &Dali::Toolkit::DummyControlImpl::GetProperty );
+  typeRegistration, "focusVisual", Dali::Toolkit::DummyControl::Property::FOCUS_VISUAL, Dali::Property::MAP, &Dali::Toolkit::DummyControlImpl::SetProperty, &Dali::Toolkit::DummyControlImpl::GetProperty);
 
 Dali::PropertyRegistration dummyControlVisualProperty05(
-  typeRegistration, "labelVisual", Dali::Toolkit::DummyControl::Property::LABEL_VISUAL, Dali::Property::MAP, &Dali::Toolkit::DummyControlImpl::SetProperty, &Dali::Toolkit::DummyControlImpl::GetProperty );
+  typeRegistration, "labelVisual", Dali::Toolkit::DummyControl::Property::LABEL_VISUAL, Dali::Property::MAP, &Dali::Toolkit::DummyControlImpl::SetProperty, &Dali::Toolkit::DummyControlImpl::GetProperty);
 
-}
+} // namespace
 
 DummyControl DummyControlImpl::New()
 {
-  IntrusivePtr< DummyControlImpl > impl = new DummyControlImpl;
-  DummyControl control( *impl );
+  IntrusivePtr<DummyControlImpl> impl = new DummyControlImpl;
+  DummyControl                   control(*impl);
   impl->Initialize();
   return control;
 }
 
 DummyControlImpl::DummyControlImpl()
-: Control( ControlBehaviour() ),
+: Control(ControlBehaviour()),
   mCustomSlot1Called(false)
 {
 }
@@ -102,69 +100,80 @@ DummyControlImpl::~DummyControlImpl()
 {
 }
 
-void DummyControlImpl::RegisterVisual( Property::Index index, Toolkit::Visual::Base visual )
+void DummyControlImpl::RegisterVisual(Property::Index index, Toolkit::Visual::Base visual)
+{
+  DevelControl::RegisterVisual(*this, index, visual);
+
+  VisualIndices::iterator iter = std::find(mRegisteredVisualIndices.begin(), mRegisteredVisualIndices.end(), index);
+  if(iter == mRegisteredVisualIndices.end())
+  {
+    mRegisteredVisualIndices.push_back(index);
+  }
+}
+
+void DummyControlImpl::RegisterVisual(Property::Index index, Toolkit::Visual::Base visual, bool enabled)
 {
-  DevelControl::RegisterVisual( *this, index, visual );
+  DevelControl::RegisterVisual(*this, index, visual, enabled);
 
-  VisualIndices::iterator iter = std::find( mRegisteredVisualIndices.begin(), mRegisteredVisualIndices.end(), index );
-  if( iter == mRegisteredVisualIndices.end() )
+  VisualIndices::iterator iter = std::find(mRegisteredVisualIndices.begin(), mRegisteredVisualIndices.end(), index);
+  if(iter == mRegisteredVisualIndices.end())
   {
     mRegisteredVisualIndices.push_back(index);
   }
 }
 
-void DummyControlImpl::RegisterVisual( Property::Index index, Toolkit::Visual::Base visual, bool enabled )
+void DummyControlImpl::RegisterVisual(Property::Index index, Toolkit::Visual::Base visual, int depthIndex)
 {
-  DevelControl::RegisterVisual( *this, index, visual, enabled );
+  DevelControl::RegisterVisual(*this, index, visual, depthIndex);
 
-  VisualIndices::iterator iter = std::find( mRegisteredVisualIndices.begin(), mRegisteredVisualIndices.end(), index );
-  if( iter == mRegisteredVisualIndices.end() )
+  VisualIndices::iterator iter = std::find(mRegisteredVisualIndices.begin(), mRegisteredVisualIndices.end(), index);
+  if(iter == mRegisteredVisualIndices.end())
   {
     mRegisteredVisualIndices.push_back(index);
   }
 }
 
-void DummyControlImpl::UnregisterVisual( Property::Index index )
+void DummyControlImpl::UnregisterVisual(Property::Index index)
 {
-  DevelControl::UnregisterVisual( *this, index );
+  DevelControl::UnregisterVisual(*this, index);
 
-  VisualIndices::iterator iter = std::find( mRegisteredVisualIndices.begin(), mRegisteredVisualIndices.end(), index );
-  if( iter != mRegisteredVisualIndices.end() )
+  VisualIndices::iterator iter = std::find(mRegisteredVisualIndices.begin(), mRegisteredVisualIndices.end(), index);
+  if(iter != mRegisteredVisualIndices.end())
   {
     mRegisteredVisualIndices.erase(iter);
   }
 }
 
-Toolkit::Visual::Base DummyControlImpl::GetVisual( Property::Index index )
+Toolkit::Visual::Base DummyControlImpl::GetVisual(Property::Index index)
 {
-  return DevelControl::GetVisual( *this, index );
+  return DevelControl::GetVisual(*this, index);
 }
 
-void DummyControlImpl::EnableVisual( Property::Index index, bool enabled )
+void DummyControlImpl::EnableVisual(Property::Index index, bool enabled)
 {
-  DevelControl::EnableVisual( *this, index, enabled );
+  DevelControl::EnableVisual(*this, index, enabled);
 }
 
-bool DummyControlImpl::IsVisualEnabled( Property::Index index )
+bool DummyControlImpl::IsVisualEnabled(Property::Index index)
 {
-  return DevelControl::IsVisualEnabled( *this, index );
+  return DevelControl::IsVisualEnabled(*this, index);
 }
 
-Animation DummyControlImpl::CreateTransition( const Toolkit::TransitionData& transition )
+Animation DummyControlImpl::CreateTransition(const Toolkit::TransitionData& transition)
 {
-  return DevelControl::CreateTransition( *this, transition );
+  return DevelControl::CreateTransition(*this, transition);
 }
 
-void DummyControlImpl::DoAction( Dali::Property::Index index, Dali::Property::Index action, const Dali::Property::Value attributes )
+void DummyControlImpl::DoAction(Dali::Property::Index index, Dali::Property::Index action, const Dali::Property::Value attributes)
 {
-  DummyControl control( *this );
-  DevelControl::DoAction(  control, index, action, attributes);
+  DummyControl control(*this);
+  DevelControl::DoAction(control, index, action, attributes);
 }
 
-void DummyControlImpl::SetProperty( BaseObject* object, Dali::Property::Index index, const Dali::Property::Value& value )
+void DummyControlImpl::SetProperty(BaseObject* object, Dali::Property::Index index, const Dali::Property::Value& value)
 {
-  Toolkit::DummyControl control = Toolkit::DummyControl::DownCast( Dali::BaseHandle( object ) );
-  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(control.GetImplementation());
+  Toolkit::DummyControl control   = Toolkit::DummyControl::DownCast(Dali::BaseHandle(object));
+  DummyControlImpl&     dummyImpl = static_cast<DummyControlImpl&>(control.GetImplementation());
 
   switch(index)
   {
@@ -175,10 +184,10 @@ void DummyControlImpl::SetProperty( BaseObject* object, Dali::Property::Index in
     case Toolkit::DummyControl::Property::LABEL_VISUAL:
     {
       const Property::Map* map = value.GetMap();
-      if( map != NULL )
+      if(map != NULL)
       {
         VisualFactory visualFactory = VisualFactory::Get();
-        Visual::Base visual = visualFactory.CreateVisual(*map);
+        Visual::Base  visual        = visualFactory.CreateVisual(*map);
         dummyImpl.RegisterVisual(index, visual);
       }
       break;
@@ -186,27 +195,26 @@ void DummyControlImpl::SetProperty( BaseObject* object, Dali::Property::Index in
   }
 }
 
-Property::Value DummyControlImpl::GetProperty( BaseObject* object, Dali::Property::Index propertyIndex )
+Property::Value DummyControlImpl::GetProperty(BaseObject* object, Dali::Property::Index propertyIndex)
 {
-  Toolkit::DummyControl control = Toolkit::DummyControl::DownCast( Dali::BaseHandle( object ) );
-  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>( control.GetImplementation() );
+  Toolkit::DummyControl control   = Toolkit::DummyControl::DownCast(Dali::BaseHandle(object));
+  DummyControlImpl&     dummyImpl = static_cast<DummyControlImpl&>(control.GetImplementation());
 
-  Visual::Base visual = dummyImpl.GetVisual( propertyIndex );
+  Visual::Base  visual = dummyImpl.GetVisual(propertyIndex);
   Property::Map map;
-  if( visual )
+  if(visual)
   {
-    visual.CreatePropertyMap( map );
+    visual.CreatePropertyMap(map);
   }
   Dali::Property::Value value = map;
 
   return value;
 }
 
-
 Toolkit::DummyControl Impl::DummyControl::New()
 {
-  IntrusivePtr< Toolkit::Impl::DummyControl > impl = new Toolkit::Impl::DummyControl;
-  Toolkit::DummyControl control( *impl );
+  IntrusivePtr<Toolkit::Impl::DummyControl> impl = new Toolkit::Impl::DummyControl;
+  Toolkit::DummyControl                     control(*impl);
   impl->Initialize();
   return control;
 }
@@ -245,29 +253,75 @@ Impl::DummyControl::~DummyControl()
   ++destructorCount;
 }
 
-void Impl::DummyControl::OnInitialize() { initializeCalled = true; }
-bool Impl::DummyControl::OnAccessibilityActivated() { activatedCalled = true; return true; }
-bool Impl::DummyControl::OnAccessibilityValueChange( bool isIncrease )
+void Impl::DummyControl::OnInitialize()
+{
+  initializeCalled = true;
+}
+bool Impl::DummyControl::OnAccessibilityActivated()
 {
-  onAccValueChangeCalled = true; return true;
+  activatedCalled = true;
+  return true;
+}
+bool Impl::DummyControl::OnAccessibilityValueChange(bool isIncrease)
+{
+  onAccValueChangeCalled = true;
+  return true;
 }
 
-void Impl::DummyControl::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
+void Impl::DummyControl::OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change)
 {
   themeChangeCalled = change == StyleChange::THEME_CHANGE;
-  fontChangeCalled = change == StyleChange::DEFAULT_FONT_SIZE_CHANGE;
-}
-void Impl::DummyControl::OnPinch(const PinchGesture& pinch) { pinchCalled = true; }
-void Impl::DummyControl::OnPan(const PanGesture& pan) { panCalled = true; }
-void Impl::DummyControl::OnTap(const TapGesture& tap) { tapCalled = true; }
-void Impl::DummyControl::OnLongPress(const LongPressGesture& longPress) { longPressCalled = true; }
-void Impl::DummyControl::OnSceneConnection( int depth ) { Control::OnSceneConnection( depth ); stageConnectionCalled = true; }
-void Impl::DummyControl::OnSceneDisconnection() { stageDisconnectionCalled = true; Control::OnSceneDisconnection(); }
-void Impl::DummyControl::OnChildAdd(Actor& child) { childAddCalled = true; }
-void Impl::DummyControl::OnChildRemove(Actor& child) { childRemoveCalled = true; }
-void Impl::DummyControl::OnSizeSet(const Vector3& targetSize) { Control::OnSizeSet( targetSize ); sizeSetCalled = true; }
-void Impl::DummyControl::OnSizeAnimation(Animation& animation, const Vector3& targetSize) { Control::OnSizeAnimation( animation, targetSize ); sizeAnimationCalled = true; }
-bool Impl::DummyControl::OnKeyEvent(const KeyEvent& event) { keyEventCalled = true; return false;}
+  fontChangeCalled  = change == StyleChange::DEFAULT_FONT_SIZE_CHANGE;
+}
+void Impl::DummyControl::OnPinch(const PinchGesture& pinch)
+{
+  pinchCalled = true;
+}
+void Impl::DummyControl::OnPan(const PanGesture& pan)
+{
+  panCalled = true;
+}
+void Impl::DummyControl::OnTap(const TapGesture& tap)
+{
+  tapCalled = true;
+}
+void Impl::DummyControl::OnLongPress(const LongPressGesture& longPress)
+{
+  longPressCalled = true;
+}
+void Impl::DummyControl::OnSceneConnection(int depth)
+{
+  Control::OnSceneConnection(depth);
+  stageConnectionCalled = true;
+}
+void Impl::DummyControl::OnSceneDisconnection()
+{
+  stageDisconnectionCalled = true;
+  Control::OnSceneDisconnection();
+}
+void Impl::DummyControl::OnChildAdd(Actor& child)
+{
+  childAddCalled = true;
+}
+void Impl::DummyControl::OnChildRemove(Actor& child)
+{
+  childRemoveCalled = true;
+}
+void Impl::DummyControl::OnSizeSet(const Vector3& targetSize)
+{
+  Control::OnSizeSet(targetSize);
+  sizeSetCalled = true;
+}
+void Impl::DummyControl::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
+{
+  Control::OnSizeAnimation(animation, targetSize);
+  sizeAnimationCalled = true;
+}
+bool Impl::DummyControl::OnKeyEvent(const KeyEvent& event)
+{
+  keyEventCalled = true;
+  return false;
+}
 void Impl::DummyControl::OnKeyInputFocusGained()
 {
   if(this->HasKeyInputFocus())
@@ -283,41 +337,41 @@ void Impl::DummyControl::OnKeyInputFocusLost()
   }
 }
 
-void Impl::DummyControl::SetLayout( Property::Index visualIndex, Property::Map& map )
+void Impl::DummyControl::SetLayout(Property::Index visualIndex, Property::Map& map)
 {
-  Property::Value value( map );
+  Property::Value value(map);
   mLayouts[visualIndex] = value;
 }
 
-void Impl::DummyControl::OnRelayout( const Vector2& size, RelayoutContainer& container )
+void Impl::DummyControl::OnRelayout(const Vector2& size, RelayoutContainer& container)
 {
-  if ( mRelayoutCallback )
+  if(mRelayoutCallback)
   {
-    mRelayoutCallback( size );  // Execute callback if set
+    mRelayoutCallback(size); // Execute callback if set
   }
 
   Property::Map emptyMap;
 
-  for( VisualIndices::iterator iter = mRegisteredVisualIndices.begin(); iter != mRegisteredVisualIndices.end() ; ++iter )
+  for(VisualIndices::iterator iter = mRegisteredVisualIndices.begin(); iter != mRegisteredVisualIndices.end(); ++iter)
   {
-    Visual::Base visual = GetVisual(*iter);
-    Property::Value value = mLayouts[*iter];
-    Property::Map* map = NULL;
+    Visual::Base    visual = GetVisual(*iter);
+    Property::Value value  = mLayouts[*iter];
+    Property::Map*  map    = NULL;
 
-    if( value.GetType() != Property::NONE )
+    if(value.GetType() != Property::NONE)
     {
       map = value.GetMap();
     }
-    if( map == NULL )
+    if(map == NULL)
     {
       map = &emptyMap;
     }
 
-    visual.SetTransformAndSize( *map, size );
+    visual.SetTransformAndSize(*map, size);
   }
 }
 
-void Impl::DummyControl::SetRelayoutCallback( RelayoutCallbackFunc callback  )
+void Impl::DummyControl::SetRelayoutCallback(RelayoutCallbackFunc callback)
 {
   mRelayoutCallback = callback;
 }
@@ -326,25 +380,23 @@ Vector3 Impl::DummyControl::GetNaturalSize()
 {
   Vector2 currentSize;
 
-  for( auto elem : mRegisteredVisualIndices )
+  for(auto elem : mRegisteredVisualIndices)
   {
-    Vector2 naturalSize;
+    Vector2      naturalSize;
     Visual::Base visual = GetVisual(elem);
-    visual.GetNaturalSize( naturalSize );
-    currentSize.width = std::max( naturalSize.width, currentSize.width );
-    currentSize.height = std::max( naturalSize.height, currentSize.height );
+    visual.GetNaturalSize(naturalSize);
+    currentSize.width  = std::max(naturalSize.width, currentSize.width);
+    currentSize.height = std::max(naturalSize.height, currentSize.height);
   }
 
-  return Vector3( currentSize );
+  return Vector3(currentSize);
 }
 
-
-
-DummyControl DummyControl::New( bool override )
+DummyControl DummyControl::New(bool override)
 {
   DummyControl control;
 
-  if (override)
+  if(override)
   {
     control = Impl::DummyControl::New();
   }
@@ -356,13 +408,13 @@ DummyControl DummyControl::New( bool override )
   return control;
 }
 
-DummyControl::DummyControl( DummyControlImpl& implementation )
-: Control( implementation )
+DummyControl::DummyControl(DummyControlImpl& implementation)
+: Control(implementation)
 {
 }
 
-DummyControl::DummyControl( Dali::Internal::CustomActor* internal )
-: Control( internal )
+DummyControl::DummyControl(Dali::Internal::CustomActor* internal)
+: Control(internal)
 {
   VerifyCustomActorPointer<DummyControlImpl>(internal);
 }
index 6f79c36..2908ad1 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEST_DUMMY_CONTROL_H
 
 /*
- * Copyright (c) 2020 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 Toolkit
 {
-
 class DummyControlImpl;
 class TransitionData;
 
@@ -47,7 +45,7 @@ public:
   enum PropertyRange
   {
     PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1, ///< @SINCE_1_0.0
-    PROPERTY_END_INDEX =   PROPERTY_START_INDEX + 1000              ///< Reserve property index
+    PROPERTY_END_INDEX   = PROPERTY_START_INDEX + 1000              ///< Reserve property index
   };
 
   struct Property
@@ -66,17 +64,15 @@ public:
   DummyControl(const DummyControl& control);
   ~DummyControl();
 
-  static DummyControl New( bool override = false );
-
-  static DummyControl DownCast( BaseHandle handle );
+  static DummyControl New(bool override = false);
 
+  static DummyControl DownCast(BaseHandle handle);
 
   DummyControl& operator=(const DummyControl& control);
 
 public: // Not intended for application developers
-
-  DummyControl( DummyControlImpl& implementation );
-  DummyControl( Dali::Internal::CustomActor* internal );
+  DummyControl(DummyControlImpl& implementation);
+  DummyControl(Dali::Internal::CustomActor* internal);
 };
 
 /**
@@ -86,40 +82,57 @@ public: // Not intended for application developers
 class DummyControlImpl : public Toolkit::Internal::Control
 {
 public:
-
   static DummyControl New();
 
 public:
-  inline void EnableGestureDetection(GestureType::Value type) { Internal::Control::EnableGestureDetection(type); }
-  inline void DisableGestureDetection(GestureType::Value type) { Internal::Control::DisableGestureDetection(type); }
-  inline PinchGestureDetector GetPinchGestureDetector() const { return Internal::Control::GetPinchGestureDetector(); }
-  inline PanGestureDetector GetPanGestureDetector() const { return Internal::Control::GetPanGestureDetector(); }
-  inline TapGestureDetector GetTapGestureDetector() const { return Internal::Control::GetTapGestureDetector(); }
-  inline LongPressGestureDetector GetLongPressGestureDetector() const { return Internal::Control::GetLongPressGestureDetector(); }
-
-  void RegisterVisual( Property::Index index, Toolkit::Visual::Base visual);
-  void RegisterVisual( Property::Index index, Toolkit::Visual::Base visual, bool enabled );
-  void UnregisterVisual( Property::Index index );
-  void EnableVisual( Property::Index index, bool enabled );
-  bool IsVisualEnabled( Property::Index index );
-  int GetVisualCount();
-  Toolkit::Visual::Base GetVisual( Property::Index index );
-  Animation CreateTransition( const Toolkit::TransitionData& transition );
-  void DoAction( Dali::Property::Index index, Dali::Property::Index action, const Dali::Property::Value attributes );
-
-  static void SetProperty( BaseObject* object, Dali::Property::Index index, const Dali::Property::Value& value );
-
-  static Property::Value GetProperty( BaseObject* object, Dali::Property::Index propertyIndex );
+  inline void EnableGestureDetection(GestureType::Value type)
+  {
+    Internal::Control::EnableGestureDetection(type);
+  }
+  inline void DisableGestureDetection(GestureType::Value type)
+  {
+    Internal::Control::DisableGestureDetection(type);
+  }
+  inline PinchGestureDetector GetPinchGestureDetector() const
+  {
+    return Internal::Control::GetPinchGestureDetector();
+  }
+  inline PanGestureDetector GetPanGestureDetector() const
+  {
+    return Internal::Control::GetPanGestureDetector();
+  }
+  inline TapGestureDetector GetTapGestureDetector() const
+  {
+    return Internal::Control::GetTapGestureDetector();
+  }
+  inline LongPressGestureDetector GetLongPressGestureDetector() const
+  {
+    return Internal::Control::GetLongPressGestureDetector();
+  }
+
+  void                  RegisterVisual(Property::Index index, Toolkit::Visual::Base visual);
+  void                  RegisterVisual(Property::Index index, Toolkit::Visual::Base visual, bool enabled);
+  void                  RegisterVisual(Property::Index index, Toolkit::Visual::Base visual, int depthIndex);
+  void                  UnregisterVisual(Property::Index index);
+  void                  EnableVisual(Property::Index index, bool enabled);
+  bool                  IsVisualEnabled(Property::Index index);
+  int                   GetVisualCount();
+  Toolkit::Visual::Base GetVisual(Property::Index index);
+  Animation             CreateTransition(const Toolkit::TransitionData& transition);
+  void                  DoAction(Dali::Property::Index index, Dali::Property::Index action, const Dali::Property::Value attributes);
+
+  static void SetProperty(BaseObject* object, Dali::Property::Index index, const Dali::Property::Value& value);
+
+  static Property::Value GetProperty(BaseObject* object, Dali::Property::Index propertyIndex);
 
   // Used to test signal connections
-  void CustomSlot1( Actor actor );
+  void CustomSlot1(Actor actor);
 
-  bool mCustomSlot1Called;
+  bool                                 mCustomSlot1Called;
   typedef std::vector<Property::Index> VisualIndices;
-  VisualIndices mRegisteredVisualIndices;
+  VisualIndices                        mRegisteredVisualIndices;
 
 protected:
-
   DummyControlImpl();
 
   ~DummyControlImpl() override;
@@ -127,7 +140,6 @@ protected:
 
 namespace Impl
 {
-
 /**
  * Cannot create an instance of Internal::Control, so use this dummy class for the implementation.
  * This class DOES override Internal::Control's behaviour.
@@ -135,38 +147,34 @@ namespace Impl
 class DummyControl : public Toolkit::DummyControlImpl
 {
 public:
-
-  typedef std::function<void( Size )> RelayoutCallbackFunc;
+  typedef std::function<void(Size)> RelayoutCallbackFunc;
 
   static Toolkit::DummyControl New();
 
-  void SetLayout( Property::Index visualIndex, Property::Map& map );
+  void SetLayout(Property::Index visualIndex, Property::Map& map);
 
-  void SetRelayoutCallback( RelayoutCallbackFunc callback );
+  void SetRelayoutCallback(RelayoutCallbackFunc callback);
 
 private:
-
   DummyControl();
 
   ~DummyControl() override;
 
 private: // From Internal::Control
-
   void OnInitialize() override;
   bool OnAccessibilityActivated() override;
-  bool OnAccessibilityValueChange( bool isIncrease ) override;
+  bool OnAccessibilityValueChange(bool isIncrease) override;
 
-  void OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change ) override;
-  void OnPinch(const PinchGesture& pinch) override;
-  void OnPan(const PanGesture& pan) override;
-  void OnTap(const TapGesture& tap) override;
-  void OnLongPress(const LongPressGesture& longPress) override;
+  void    OnStyleChange(Toolkit::StyleManager styleManager, StyleChange::Type change) override;
+  void    OnPinch(const PinchGesture& pinch) override;
+  void    OnPan(const PanGesture& pan) override;
+  void    OnTap(const TapGesture& tap) override;
+  void    OnLongPress(const LongPressGesture& longPress) override;
   Vector3 GetNaturalSize() override;
-  bool OnKeyEvent(const KeyEvent& event) override;
+  bool    OnKeyEvent(const KeyEvent& event) override;
 
 private: // From CustomActorImpl
-
-  void OnSceneConnection( int depth ) override;
+  void OnSceneConnection(int depth) override;
   void OnSceneDisconnection() override;
   void OnChildAdd(Actor& child) override;
   void OnChildRemove(Actor& child) override;
@@ -174,39 +182,37 @@ private: // From CustomActorImpl
   void OnSizeAnimation(Animation& animation, const Vector3& targetSize) override;
   void OnKeyInputFocusGained() override;
   void OnKeyInputFocusLost() override;
-  void OnRelayout( const Vector2& size, RelayoutContainer& container ) override;
+  void OnRelayout(const Vector2& size, RelayoutContainer& container) override;
 
-  DALI_INTERNAL DummyControl( const DummyControl& );
-  DALI_INTERNAL DummyControl& operator=( const DummyControl& );
+  DALI_INTERNAL DummyControl(const DummyControl&);
+  DALI_INTERNAL DummyControl& operator=(const DummyControl&);
 
 public:
-
-  bool initializeCalled;
-  bool activatedCalled;
-  bool onAccValueChangeCalled;
-  bool themeChangeCalled;
-  bool fontChangeCalled;
-  bool pinchCalled;
-  bool panCalled;
-  bool tapCalled;
-  bool longPressCalled;
-  bool stageConnectionCalled;
-  bool stageDisconnectionCalled;
-  bool childAddCalled;
-  bool childRemoveCalled;
-  bool sizeSetCalled;
-  bool sizeAnimationCalled;
-  bool hoverEventCalled;
-  bool wheelEventCalled;
-  bool keyEventCalled;
-  bool keyInputFocusGained;
-  bool keyInputFocusLost;
+  bool       initializeCalled;
+  bool       activatedCalled;
+  bool       onAccValueChangeCalled;
+  bool       themeChangeCalled;
+  bool       fontChangeCalled;
+  bool       pinchCalled;
+  bool       panCalled;
+  bool       tapCalled;
+  bool       longPressCalled;
+  bool       stageConnectionCalled;
+  bool       stageDisconnectionCalled;
+  bool       childAddCalled;
+  bool       childRemoveCalled;
+  bool       sizeSetCalled;
+  bool       sizeAnimationCalled;
+  bool       hoverEventCalled;
+  bool       wheelEventCalled;
+  bool       keyEventCalled;
+  bool       keyInputFocusGained;
+  bool       keyInputFocusLost;
   static int constructorCount;
   static int destructorCount;
 
-  Property::Map mLayouts;
+  Property::Map        mLayouts;
   RelayoutCallbackFunc mRelayoutCallback;
-
 };
 
 } // namespace Impl
index 49c344a..6a69f93 100644 (file)
@@ -71,6 +71,8 @@ public:
   void RemoveIdle(CallbackBase* callback);
   void RunIdles();
 
+  void RequestUpdateOnce();
+
   static Integration::Scene GetScene(Dali::Window window);
 
   Dali::RenderSurfaceInterface& GetSurface();
index 4d77310..40c73ae 100644 (file)
@@ -139,6 +139,19 @@ void Adaptor::RunIdles()
   mReturnCallbacks.Swap(reusedCallbacks);
 }
 
+void Adaptor::RequestUpdateOnce()
+{
+  if(mTestApplication)
+  {
+    auto scene = mTestApplication->GetScene();
+    if(scene)
+    {
+      tet_printf("Adaptor::RequestUpdateOnce()\n");
+      scene.KeepRendering(0.0f);
+    }
+  }
+}
+
 Dali::RenderSurfaceInterface& Adaptor::GetSurface()
 {
   DALI_ASSERT_ALWAYS(!mWindows.empty());
index 39d04e3..b8e1a03 100644 (file)
@@ -65,6 +65,11 @@ public:
   Dali::Clipboard::DataReceivedSignalType& DataReceivedSignal();
 
   /**
+   * @copydoc Dali::Clipboard::HasType()
+   */
+  bool HasType(const std::string& mimeType);
+
+  /**
    * @copydoc Dali::Clipboard::SetData()
    */
   bool SetData(const Dali::Clipboard::ClipData& clipData);
@@ -152,6 +157,11 @@ Dali::Clipboard::DataReceivedSignalType& Clipboard::DataReceivedSignal()
   return mDataReceivedSignal;
 }
 
+bool Clipboard::HasType(const std::string& mimeType)
+{
+  return mMimeType == mimeType ? true : false;
+}
+
 bool Clipboard::SetData(const Dali::Clipboard::ClipData& clipData)
 {
   mMimeType = clipData.GetMimeType();
index 7ad3187..4685e6d 100644 (file)
@@ -131,6 +131,13 @@ public:
   DataReceivedSignalType& DataReceivedSignal();
 
   /**
+   * @brief Check if there is data in the clipboard with a given mime type.
+   * @param[in] mimeType mime type to search for.
+   * @return bool true if there is data, otherwise false.
+   */
+  bool HasType(const std::string& mimeType);
+
+  /**
    * @brief Send the given data to the clipboard.
    * @param[in] clipData data to send to the clipboard
    * @return bool true if the internal clipboard sending was successful.
index 4535413..ba02bef 100644 (file)
@@ -481,7 +481,7 @@ int UtcDaliAnimatedImageVisualGetPropertyMap04(void)
 
   value = resultMap.Find(Toolkit::DevelImageVisual::Property::TOTAL_FRAME_NUMBER, "totalFrameNumber");
   DALI_TEST_CHECK(value);
-  DALI_TEST_EQUALS(value->Get<int>(), 4, TEST_LOCATION);
+  DALI_TEST_EQUALS(value->Get<int>(), -1, TEST_LOCATION);
 
   value = resultMap.Find(Toolkit::DevelVisual::Property::BORDERLINE_WIDTH, "borderlineWidth");
   DALI_TEST_CHECK(value);
@@ -1994,7 +1994,6 @@ int UtcDaliAnimatedImageVisualDesiredSize(void)
   END_TEST;
 }
 
-
 int UtcDaliAnimatedImageVisualControlVisibilityChanged(void)
 {
   ToolkitTestApplication application;
@@ -2150,4 +2149,53 @@ int UtcDaliAnimatedImageVisualWindowVisibilityChanged(void)
   DALI_TEST_EQUALS(value->Get<int>(), 0, TEST_LOCATION);
 
   END_TEST;
-}
\ No newline at end of file
+}
+
+int UtcDaliAnimatedImageVisualFrameCountBeforeLoadingFinished(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliAnimatedImageVisualFrameCountBeforeLoadingFinished");
+
+  Property::Map propertyMap;
+  propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_IMAGE)
+    .Add(ImageVisual::Property::URL, TEST_GIF_FILE_NAME)
+    .Add(ImageVisual::Property::SYNCHRONOUS_LOADING, false);
+
+  Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap);
+  DALI_TEST_CHECK(visual);
+
+  Property::Map resultMap1;
+  visual.CreatePropertyMap(resultMap1);
+  Property::Value* value1 = resultMap1.Find(DevelImageVisual::Property::TOTAL_FRAME_NUMBER);
+  DALI_TEST_CHECK(value1);
+  DALI_TEST_EQUALS(value1->Get<int>(), -1, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  DummyControl      actor     = DummyControl::New(true);
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+  Property::Map resultMap2;
+  visual.CreatePropertyMap(resultMap2);
+  Property::Value* value2 = resultMap2.Find(DevelImageVisual::Property::TOTAL_FRAME_NUMBER);
+  DALI_TEST_CHECK(value2);
+  DALI_TEST_EQUALS(value2->Get<int>(), -1, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  Vector2 controlSize(20.f, 30.f);
+  actor.SetProperty(Actor::Property::SIZE, controlSize);
+
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 2 - load & render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+  Property::Map resultMap3;
+  visual.CreatePropertyMap(resultMap3);
+  Property::Value* value3 = resultMap3.Find(DevelImageVisual::Property::TOTAL_FRAME_NUMBER);
+  DALI_TEST_CHECK(value3);
+  DALI_TEST_EQUALS(value3->Get<int>(), 4, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  END_TEST;
+}
index 72a4966..55891b8 100644 (file)
@@ -69,6 +69,100 @@ void VisualEventSignal(Control control, Dali::Property::Index visualIndex, Dali:
   }
 }
 
+/**
+ * @brief Retry function to get playrange until expect values comes.
+ * @note This function might consume EventThreadTrigger.
+ *
+ * @param[in] dummyControl The control for test.
+ * @param[in] expectStartFrame Expect start frame.
+ * @param[in] expectEndFrame Expect end frame.
+ * @param[in] retrialFrames Retry required frame value list.
+ * @param[in] testLocation Location info of UTC. It will be used when UTC failed.
+ */
+void CheckAndRetryPlayRange(DummyControl dummyControl, int expectStartFrame, int expectEndFrame, std::vector<std::pair<int, int>> retrialFrames, const char* testLocation)
+{
+  int tryCount    = 0;
+  int tryCountMax = 25;
+  while(++tryCount <= tryCountMax)
+  {
+    Property::Map resultMap = dummyControl.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+
+    Property::Value* value = resultMap.Find(DevelImageVisual::Property::PLAY_RANGE, Property::ARRAY);
+    DALI_TEST_CHECK(value);
+
+    Property::Array* result = value->GetArray();
+    DALI_TEST_CHECK(result);
+    DALI_TEST_EQUALS(result->Count(), 2, TEST_LOCATION);
+
+    bool tryAgain = false;
+    for(auto& framePair : retrialFrames)
+    {
+      if(result->GetElementAt(0).Get<int>() == framePair.first && result->GetElementAt(1).Get<int>() == framePair.second)
+      {
+        tryAgain = true;
+        break;
+      }
+    }
+    if(tryAgain)
+    {
+      tet_printf("Retry to get value again! [%d]\n", tryCount);
+      // Dummy sleep 1 second.
+      Test::WaitForEventThreadTrigger(1, 1);
+      continue;
+    }
+
+    DALI_TEST_EQUALS(result->GetElementAt(0).Get<int>(), expectStartFrame, testLocation);
+    DALI_TEST_EQUALS(result->GetElementAt(1).Get<int>(), expectEndFrame, testLocation);
+    break;
+  }
+  DALI_TEST_CHECK(tryCount <= tryCountMax);
+}
+
+/**
+ * @brief Retry function to get current frame until expect values comes.
+ * @note This function might consume EventThreadTrigger.
+ *
+ * @param[in] dummyControl The control for test.
+ * @param[in] expectCurrentFrame Expect current frame.
+ * @param[in] retrialFrames Retry required frame value list.
+ * @param[in] testLocation Location info of UTC. It will be used when UTC failed.
+ */
+void CheckAndRetryCurrentFrame(DummyControl dummyControl, int expectCurrentFrame, std::vector<int> retrialFrames, const char* testLocation)
+{
+  int tryCount    = 0;
+  int tryCountMax = 25;
+  while(++tryCount <= tryCountMax)
+  {
+    Property::Map resultMap = dummyControl.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+
+    Property::Value* value = resultMap.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER, Property::INTEGER);
+    DALI_TEST_CHECK(value);
+
+    int32_t result = value->Get<int32_t>();
+
+    bool tryAgain = false;
+    for(auto& frame : retrialFrames)
+    {
+      if(result == frame)
+      {
+        tryAgain = true;
+        break;
+      }
+    }
+    if(tryAgain)
+    {
+      tet_printf("Retry to get value again! [%d]\n", tryCount);
+      // Dummy sleep 1 second.
+      Test::WaitForEventThreadTrigger(1, 1);
+      continue;
+    }
+
+    DALI_TEST_EQUALS(result, expectCurrentFrame, testLocation);
+    break;
+  }
+  DALI_TEST_CHECK(tryCount <= tryCountMax);
+}
+
 } // namespace
 
 int UtcDaliVisualFactoryGetAnimatedVectorImageVisual01(void)
@@ -174,8 +268,17 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual03(void)
   // Trigger count is 2 - load & render a frame
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
+  // There might be 1 event triggered if start frame is not 0, and render frame spend long time.
+  // if ForceRenderOnce triggered before render complete, renderer count could be zero.
+  // Consume it if required.
+  if(actor.GetRendererCount() == 0)
+  {
+    tet_printf("Warning! render frame trigger not comes yet. Let we wait one more time.\n");
+    Test::WaitForEventThreadTrigger(1, 1);
+  }
+
   // renderer is added to actor
-  DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
   Renderer renderer = actor.GetRendererAt(0u);
   DALI_TEST_CHECK(renderer);
 
@@ -208,13 +311,14 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual04(void)
     .Add("stopBehavior", DevelImageVisual::StopBehavior::FIRST_FRAME)
     .Add("loopingMode", DevelImageVisual::LoopingMode::AUTO_REVERSE)
     .Add("redrawInScalingDown", false)
+    .Add("enableFrameCache", false)
+    .Add("notifyAfterRasterization", false)
     .Add("cornerRadius", cornerRadius)
     .Add("borderlineWidth", borderlineWidth)
     .Add("borderlineColor", borderlineColor)
     .Add("borderlineOffset", borderlineOffset)
     .Add("desiredWidth", desiredWidth)
-    .Add("desiredHeight", desiredHeight)
-    .Add("useFixedCache", false);
+    .Add("desiredHeight", desiredHeight);
 
   Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap);
   DALI_TEST_CHECK(visual);
@@ -231,8 +335,17 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual04(void)
   // Trigger count is 1 - render a frame
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
+  // There might be 1 event triggered if start frame is not 0, and render frame spend long time.
+  // if ForceRenderOnce triggered before render complete, renderer count could be zero.
+  // Consume it if required.
+  if(actor.GetRendererCount() == 0)
+  {
+    tet_printf("Warning! render frame trigger not comes yet. Let we wait one more time.\n");
+    Test::WaitForEventThreadTrigger(1, 1);
+  }
+
   // renderer is added to actor
-  DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
 
   Renderer renderer = actor.GetRendererAt(0u);
   DALI_TEST_CHECK(renderer);
@@ -270,6 +383,14 @@ int UtcDaliVisualFactoryGetAnimatedVectorImageVisual04(void)
   DALI_TEST_CHECK(value);
   DALI_TEST_CHECK(value->Get<bool>() == false);
 
+  value = resultMap.Find(DevelImageVisual::Property::ENABLE_FRAME_CACHE, Property::BOOLEAN);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<bool>() == false);
+
+  value = resultMap.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, Property::BOOLEAN);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<bool>() == false);
+
   value = resultMap.Find(DevelVisual::Property::CORNER_RADIUS, Property::VECTOR4);
   DALI_TEST_CHECK(value);
   DALI_TEST_EQUALS(value->Get<Vector4>(), Vector4(cornerRadius, cornerRadius, cornerRadius, cornerRadius), TEST_LOCATION);
@@ -395,6 +516,10 @@ int UtcDaliAnimatedVectorImageVisualGetPropertyMap01(void)
   DALI_TEST_CHECK(value);
   DALI_TEST_CHECK(value->Get<bool>() == false); // Check default value
 
+  value = resultMap.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, Property::BOOLEAN);
+  DALI_TEST_CHECK(value);
+  DALI_TEST_CHECK(value->Get<bool>() == false); // Check default value
+
   value = resultMap.Find(DevelImageVisual::Property::REDRAW_IN_SCALING_DOWN, Property::BOOLEAN);
   DALI_TEST_CHECK(value);
   DALI_TEST_CHECK(value->Get<bool>() == true); // Check default value
@@ -703,7 +828,7 @@ int UtcDaliAnimatedVectorImageVisualLoopCount(void)
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
   // renderer is added to actor
-  DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
   Renderer renderer = actor.GetRendererAt(0u);
   DALI_TEST_CHECK(renderer);
 
@@ -747,8 +872,17 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void)
   // Trigger count is 2 - load & render a frame
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
+  // There might be 1 event triggered if start frame is not 0, and render frame spend long time.
+  // if ForceRenderOnce triggered before render complete, renderer count could be zero.
+  // Consume it if required.
+  if(actor.GetRendererCount() == 0)
+  {
+    tet_printf("Warning! render frame trigger not comes yet. Let we wait one more time.\n");
+    Test::WaitForEventThreadTrigger(1, 1);
+  }
+
   // renderer is added to actor
-  DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
   Renderer renderer = actor.GetRendererAt(0u);
   DALI_TEST_CHECK(renderer);
 
@@ -767,7 +901,7 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void)
   // Set invalid play range
   array.Clear();
   array.PushBack(1);
-  array.PushBack(100);
+  array.PushBack(totalFrameNumber + 100);
 
   attributes.Clear();
   attributes.Add(DevelImageVisual::Property::PLAY_RANGE, array);
@@ -781,15 +915,8 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void)
 
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
-  map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
-  value = map.Find(DevelImageVisual::Property::PLAY_RANGE);
-
-  result = value->GetArray();
-  result->GetElementAt(0).Get(resultStartFrame);
-  result->GetElementAt(1).Get(resultEndFrame);
-
-  DALI_TEST_EQUALS(resultStartFrame, 1, TEST_LOCATION);
-  DALI_TEST_EQUALS(resultEndFrame, totalFrameNumber - 1, TEST_LOCATION); // Should be clamped
+  // Should be clamped.
+  CheckAndRetryPlayRange(actor, 1, totalFrameNumber - 1, {{startFrame, endFrame}}, TEST_LOCATION);
 
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PAUSE, Property::Map());
 
@@ -798,17 +925,14 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void)
 
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 3);
 
-  // To make event trigger
-  actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f));
-
   application.SendNotification();
   application.Render();
 
+  // Jump to action when paused, will make one or more event trigger
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
-  map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
-  value = map.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER);
-  DALI_TEST_EQUALS(value->Get<int>(), 3, TEST_LOCATION);
+  // Test whether current frame is 3.
+  CheckAndRetryCurrentFrame(actor, 3, {0, 1}, TEST_LOCATION);
 
   array.Clear();
   array.PushBack(0);
@@ -819,23 +943,16 @@ int UtcDaliAnimatedVectorImageVisualPlayRange(void)
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, attributes);
 
   // To make event trigger
-  actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+  actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f));
 
   application.SendNotification();
   application.Render();
 
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
-  map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
-  value = map.Find(DevelImageVisual::Property::PLAY_RANGE);
-
-  result = value->GetArray();
-  result->GetElementAt(0).Get(resultStartFrame);
-  result->GetElementAt(1).Get(resultEndFrame);
-
-  DALI_TEST_EQUALS(0, resultStartFrame, TEST_LOCATION);
-  DALI_TEST_EQUALS(2, resultEndFrame, TEST_LOCATION);
+  CheckAndRetryPlayRange(actor, 0, 2, {{1, totalFrameNumber - 1}}, TEST_LOCATION);
 
+  map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
   value = map.Find(DevelImageVisual::Property::CURRENT_FRAME_NUMBER);
   DALI_TEST_EQUALS(value->Get<int>(), 2, TEST_LOCATION); // CURRENT_FRAME_NUMBER should be changed also.
 
@@ -878,8 +995,17 @@ int UtcDaliAnimatedVectorImageVisualPlayRangeMarker(void)
   // Trigger count is 2 - load & render a frame
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
+  // There might be 1 event triggered if start frame is not 0, and render frame spend long time.
+  // if ForceRenderOnce triggered before render complete, renderer count could be zero.
+  // Consume it if required.
+  if(actor.GetRendererCount() == 0)
+  {
+    tet_printf("Warning! render frame trigger not comes yet. Let we wait one more time.\n");
+    Test::WaitForEventThreadTrigger(1, 1);
+  }
+
   // renderer is added to actor
-  DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
   Renderer renderer = actor.GetRendererAt(0u);
   DALI_TEST_CHECK(renderer);
 
@@ -1008,7 +1134,7 @@ int UtcDaliAnimatedVectorImageVisualMarkerInfo(void)
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
   // renderer is added to actor
-  DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
   Renderer renderer = actor.GetRendererAt(0u);
   DALI_TEST_CHECK(renderer);
 
@@ -1100,10 +1226,10 @@ int UtcDaliAnimatedVectorImageVisualMarkerInfoFromInvalid(void)
   END_TEST;
 }
 
-int UtcDaliAnimatedVectorImageVisualUsedFixedCache(void)
+int UtcDaliAnimatedVectorImageVisualEnableFrameCache(void)
 {
   ToolkitTestApplication application;
-  tet_infoline("UtcDaliAnimatedVectorImageVisualUsedFixedCache");
+  tet_infoline("UtcDaliAnimatedVectorImageVisualEnableFrameCache");
 
   Property::Map propertyMap;
   propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE)
@@ -1117,13 +1243,12 @@ int UtcDaliAnimatedVectorImageVisualUsedFixedCache(void)
   DummyControl      actor     = DummyControl::New(true);
   DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
   dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
-  //actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
   application.GetScene().Add(actor);
 
   application.SendNotification();
   application.Render();
 
-  // Trigger count is 1 - render a frame
+  // Trigger count is 1 - load
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   Vector2 controlSize(200.f, 200.f);
@@ -1132,7 +1257,7 @@ int UtcDaliAnimatedVectorImageVisualUsedFixedCache(void)
   application.SendNotification();
   application.Render();
 
-  // Trigger count is 1 - load
+  // Trigger count is 1 - render a frame
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   // renderer is added to actor
@@ -1147,10 +1272,10 @@ int UtcDaliAnimatedVectorImageVisualUsedFixedCache(void)
   END_TEST;
 }
 
-int UtcDaliAnimatedVectorImageVisualUsedFixedCacheFailed(void)
+int UtcDaliAnimatedVectorImageVisualEnableFrameCacheFailed(void)
 {
   ToolkitTestApplication application;
-  tet_infoline("UtcDaliAnimatedVectorImageVisualUsedFixedCacheFailed");
+  tet_infoline("UtcDaliAnimatedVectorImageVisualEnableFrameCacheFailed");
 
   Property::Map propertyMap;
   propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE)
@@ -1194,6 +1319,100 @@ int UtcDaliAnimatedVectorImageVisualUsedFixedCacheFailed(void)
   END_TEST;
 }
 
+int UtcDaliAnimatedVectorImageVisualNotifyAfterRasterization(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliAnimatedVectorImageVisualNotifyAfterRasterization");
+
+  Property::Map propertyMap;
+  propertyMap.Add(Toolkit::Visual::Property::TYPE, DevelVisual::ANIMATED_VECTOR_IMAGE)
+    .Add(ImageVisual::Property::URL, TEST_VECTOR_IMAGE_FILE_NAME)
+    .Add(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, true)
+    .Add(ImageVisual::Property::SYNCHRONOUS_LOADING, false);
+
+  Visual::Base visual = VisualFactory::Get().CreateVisual(propertyMap);
+  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 - load
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  Vector2 controlSize(200.f, 200.f);
+  actor.SetProperty(Actor::Property::SIZE, controlSize);
+
+  application.SendNotification();
+  application.Render();
+
+  // Trigger count is 1 - render a frame
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  // Play animation
+  Property::Map attributes;
+  DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::PLAY, attributes);
+
+  application.SendNotification();
+  application.Render();
+
+  // There might be 1 event triggered if render frame spend long time.
+  // if ForceRenderOnce triggered before render complete, renderer count could be zero.
+  // Consume it if required.
+  if(actor.GetRendererCount() == 0)
+  {
+    tet_printf("Warning! render frame trigger not comes yet. Let we wait one more time.\n");
+    Test::WaitForEventThreadTrigger(1, 1);
+  }
+
+  // renderer is added to actor
+  DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+  Renderer renderer = actor.GetRendererAt(0u);
+  DALI_TEST_CHECK(renderer);
+
+  // Check renderer behavior
+  DALI_TEST_CHECK(renderer.GetProperty<int>(DevelRenderer::Property::RENDERING_BEHAVIOR) == DevelRenderer::Rendering::IF_REQUIRED);
+
+  Property::Map    map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+  Property::Value* value = map.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION);
+  DALI_TEST_CHECK(value->Get<bool>() == true);
+
+  propertyMap.Clear();
+  propertyMap.Add(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, false);
+  DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, propertyMap);
+
+  application.SendNotification();
+  application.Render();
+
+  // Check renderer behavior again
+  DALI_TEST_CHECK(renderer.GetProperty<int>(DevelRenderer::Property::RENDERING_BEHAVIOR) == DevelRenderer::Rendering::CONTINUOUSLY);
+
+  map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+  value = map.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION);
+  DALI_TEST_CHECK(value->Get<bool>() == false);
+
+  propertyMap.Clear();
+  propertyMap.Add(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, true);
+  DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelVisual::Action::UPDATE_PROPERTY, propertyMap);
+
+  application.SendNotification();
+  application.Render();
+
+  // Check renderer behavior again
+  DALI_TEST_CHECK(renderer.GetProperty<int>(DevelRenderer::Property::RENDERING_BEHAVIOR) == DevelRenderer::Rendering::IF_REQUIRED);
+
+  map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
+  value = map.Find(DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION);
+  DALI_TEST_CHECK(value->Get<bool>() == true);
+
+  END_TEST;
+}
+
 int UtcDaliAnimatedVectorImageVisualAnimationFinishedSignal(void)
 {
   ToolkitTestApplication application;
@@ -1278,12 +1497,10 @@ int UtcDaliAnimatedVectorImageVisualJumpTo(void)
 
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 2);
 
-  // To make event trigger
-  actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
-
   application.SendNotification();
   application.Render();
 
+  // Trigger count is 1 - Jump to during stopped
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   Property::Map    map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
@@ -1303,7 +1520,7 @@ int UtcDaliAnimatedVectorImageVisualJumpTo(void)
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 3);
 
   // To make event trigger
-  actor.SetProperty(Actor::Property::SIZE, Vector2(20.0f, 20.0f));
+  actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
 
   application.SendNotification();
   application.Render();
@@ -1334,16 +1551,16 @@ int UtcDaliAnimatedVectorImageVisualJumpTo(void)
 
   // Wait for animation finish
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+  // Note : AnimationFinished will occure force-render, and it might required another trigger. Test one more trigger now.
+  Test::WaitForEventThreadTrigger(1, 1);
 
   // Jump to 3
   DevelControl::DoAction(actor, DummyControl::Property::TEST_VISUAL, Dali::Toolkit::DevelAnimatedVectorImageVisual::Action::JUMP_TO, 3);
 
-  // To make event trigger
-  actor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
-
   application.SendNotification();
   application.Render();
 
+  // Trigger count is 1 - Jump to during stopped.
   DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
 
   map   = actor.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
@@ -1417,8 +1634,8 @@ int UtcDaliAnimatedVectorImageVisualUpdateProperty(void)
   Property::Array* result = value->GetArray();
   DALI_TEST_CHECK(result);
 
-  DALI_TEST_CHECK(result->GetElementAt(0).Get<int>() == startFrame);
-  DALI_TEST_CHECK(result->GetElementAt(1).Get<int>() == endFrame);
+  DALI_TEST_EQUALS(result->GetElementAt(0).Get<int>(), startFrame, TEST_LOCATION);
+  DALI_TEST_EQUALS(result->GetElementAt(1).Get<int>(), endFrame, TEST_LOCATION);
 
   playRange.Clear();
   playRange.PushBack(0);
@@ -1446,8 +1663,8 @@ int UtcDaliAnimatedVectorImageVisualUpdateProperty(void)
   result = value->GetArray();
   DALI_TEST_CHECK(result);
 
-  DALI_TEST_CHECK(result->GetElementAt(0).Get<int>() == 0);
-  DALI_TEST_CHECK(result->GetElementAt(1).Get<int>() == 2);
+  // Ensure that vector data sended well.
+  CheckAndRetryPlayRange(actor, 0, 2, {{startFrame, endFrame}}, TEST_LOCATION);
 
   attributes.Clear();
 
@@ -1473,8 +1690,8 @@ int UtcDaliAnimatedVectorImageVisualUpdateProperty(void)
   result = value->GetArray();
   DALI_TEST_CHECK(result);
 
-  DALI_TEST_CHECK(result->GetElementAt(0).Get<int>() == startFrame);
-  DALI_TEST_CHECK(result->GetElementAt(1).Get<int>() == endFrame);
+  // Ensure that vector data sended well.
+  CheckAndRetryPlayRange(actor, startFrame, endFrame, {{0, 2}}, TEST_LOCATION);
 
   // Play and update property
   attributes.Clear();
@@ -2388,45 +2605,6 @@ int UtcDaliAnimatedVectorImageVisualFlushAction(void)
 
   application.GetScene().Add(dummyControl);
 
-  // Retry function to get playrange until expect values comes.
-  auto CheckAndRetryPlayRange = [&](int expectStartFrame, int expectEndFrame, std::vector<std::pair<int, int>> retrialFrames) {
-    int tryCount    = 0;
-    int tryCountMax = 30;
-    while(++tryCount <= tryCountMax)
-    {
-      Property::Map resultMap = dummyControl.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
-
-      Property::Value* value = resultMap.Find(DevelImageVisual::Property::PLAY_RANGE, Property::ARRAY);
-      DALI_TEST_CHECK(value);
-
-      Property::Array* result = value->GetArray();
-      DALI_TEST_CHECK(result);
-      DALI_TEST_EQUALS(result->Count(), 2, TEST_LOCATION);
-
-      bool tryAgain = false;
-      for(auto& framePair : retrialFrames)
-      {
-        if(result->GetElementAt(0).Get<int>() == framePair.first && result->GetElementAt(1).Get<int>() == framePair.second)
-        {
-          tryAgain = true;
-          break;
-        }
-      }
-      if(tryAgain)
-      {
-        tet_printf("Retry to get value again! [%d]\n", tryCount);
-        // Dummy sleep 1 second.
-        Test::WaitForEventThreadTrigger(1, 1);
-        continue;
-      }
-
-      DALI_TEST_EQUALS(result->GetElementAt(0).Get<int>(), expectStartFrame, TEST_LOCATION);
-      DALI_TEST_EQUALS(result->GetElementAt(1).Get<int>(), expectEndFrame, TEST_LOCATION);
-      break;
-    }
-    DALI_TEST_CHECK(tryCount <= tryCountMax);
-  };
-
   tet_printf("Pause lottie first.\n");
 
   Property::Map attributes;
@@ -2445,7 +2623,7 @@ int UtcDaliAnimatedVectorImageVisualFlushAction(void)
   } while(totalFrameCount == 0);
 
   // Ensure that vector data sended well.
-  CheckAndRetryPlayRange(startFrame, endFrame, {{0, 0}, {0, totalFrameCount - 1}});
+  CheckAndRetryPlayRange(dummyControl, startFrame, endFrame, {{0, 0}, {0, totalFrameCount - 1}}, TEST_LOCATION);
 
   resultMap = dummyControl.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
 
@@ -2490,7 +2668,7 @@ int UtcDaliAnimatedVectorImageVisualFlushAction(void)
   application.Render(16);
 
   // Ensure that vector data sended well.
-  CheckAndRetryPlayRange(changedStartFrame2, changedEndFrame2, {{changedStartFrame1, changedEndFrame1}, {startFrame, endFrame}});
+  CheckAndRetryPlayRange(dummyControl, changedStartFrame2, changedEndFrame2, {{changedStartFrame1, changedEndFrame1}, {startFrame, endFrame}}, TEST_LOCATION);
 
   resultMap = dummyControl.GetProperty<Property::Map>(DummyControl::Property::TEST_VISUAL);
 
index 0bd455b..319d4d4 100644 (file)
@@ -1384,6 +1384,93 @@ int UtcDaliImageVisualCustomWrapModePixelArea(void)
   END_TEST;
 }
 
+
+int UtcDaliImageVisualCustomWrapModePixelArea02(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("Request image visual with a Property::Map, test custom wrap mode and pixel area");
+
+  static std::vector<UniformData> customUniforms =
+    {
+      UniformData("pixelArea", Property::Type::VECTOR4),
+      UniformData("wrapMode", Property::Type::VECTOR2),
+    };
+
+  TestGraphicsController& graphics = application.GetGraphicsController();
+  graphics.AddCustomUniforms(customUniforms);
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK(factory);
+
+  // Test wrap mode with atlasing. Image with a size smaller than 512*512 will be uploaded as a part of the atlas.
+  const int     width  = 34;
+  const int     height = 34;
+  const Vector4 pixelArea(-0.5f, -0.5f, 2.f, 2.f);
+
+  Property::Map propertyMap;
+  propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE);
+  propertyMap.Insert(ImageVisual::Property::URL, TEST_SMALL_IMAGE_FILE_NAME);
+  propertyMap.Insert(ImageVisual::Property::DESIRED_WIDTH, width);
+  propertyMap.Insert(ImageVisual::Property::DESIRED_HEIGHT, height);
+  propertyMap.Insert(ImageVisual::Property::SYNCHRONOUS_LOADING, false);
+  propertyMap.Insert(ImageVisual::Property::PIXEL_AREA, pixelArea);
+  propertyMap.Insert(ImageVisual::Property::WRAP_MODE_U, WrapMode::MIRRORED_REPEAT);
+  propertyMap.Insert(ImageVisual::Property::WRAP_MODE_V, WrapMode::CLAMP_TO_EDGE);
+
+  Visual::Base visual = factory.CreateVisual(propertyMap);
+  DALI_TEST_CHECK(visual);
+
+  TestGlAbstraction& gl           = application.GetGlAbstraction();
+  TraceCallStack&    textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+  TraceCallStack& texParameterTrace = gl.GetTexParameterTrace();
+  texParameterTrace.Enable(true);
+
+  DummyControl      actor     = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual);
+  actor.SetProperty(Actor::Property::SIZE, Vector2(2000, 2000));
+  actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+  application.GetScene().Add(actor);
+
+  // loading started
+  application.SendNotification();
+  application.Render();
+
+  // Wait image load complete.
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+
+  DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
+
+  // Following gl function should not be called
+  std::stringstream out;
+  out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_S << ", " << GL_MIRRORED_REPEAT;
+  DALI_TEST_CHECK(texParameterTrace.FindMethodAndParams("TexParameteri", out.str()));
+  out.str("");
+  out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_T << ", " << GL_CLAMP_TO_EDGE;
+  DALI_TEST_CHECK(texParameterTrace.FindMethodAndParams("TexParameteri", out.str()));
+
+  // test the uniforms which used to handle the wrap mode
+  Renderer renderer = actor.GetRendererAt(0u);
+  DALI_TEST_CHECK(renderer);
+
+  Property::Value pixelAreaValue = renderer.GetProperty(renderer.GetPropertyIndex("pixelArea"));
+  DALI_TEST_EQUALS(pixelAreaValue.Get<Vector4>(), pixelArea, TEST_LOCATION);
+  Vector4 pixelAreaUniform;
+  DALI_TEST_CHECK(gl.GetUniformValue<Vector4>("pixelArea", pixelAreaUniform));
+  DALI_TEST_EQUALS(pixelArea, pixelAreaUniform, Math::MACHINE_EPSILON_100, TEST_LOCATION);
+
+  actor.Unparent();
+  DALI_TEST_CHECK(actor.GetRendererCount() == 0u);
+
+  END_TEST;
+}
+
 int UtcDaliImageVisualCustomWrapModeNoAtlas(void)
 {
   ToolkitTestApplication application;
index bc75ce0..6a5745c 100644 (file)
@@ -117,6 +117,9 @@ const char* const PROPERTY_NAME_ENABLE_GRAB_HANDLE_POPUP        = "enableGrabHan
 const char* const PROPERTY_NAME_INPUT_METHOD_SETTINGS           = "inputMethodSettings";
 const char* const PROPERTY_NAME_INPUT_FILTER                    = "inputFilter";
 
+const char* const PROPERTY_NAME_REMOVE_FRONT_INSET    = "removeFrontInset";
+const char* const PROPERTY_NAME_REMOVE_BACK_INSET     = "removeBackInset";
+
 const Vector4       PLACEHOLDER_TEXT_COLOR(0.8f, 0.8f, 0.8f, 0.8f);
 const Dali::Vector4 LIGHT_BLUE(0.75f, 0.96f, 1.f, 1.f); // The text highlight color.
 
@@ -634,6 +637,8 @@ int UtcDaliTextEditorGetPropertyP(void)
   DALI_TEST_CHECK(editor.GetPropertyIndex(PROPERTY_NAME_STRIKETHROUGH) == DevelTextEditor::Property::STRIKETHROUGH);
   DALI_TEST_CHECK(editor.GetPropertyIndex(PROPERTY_NAME_INPUT_STRIKETHROUGH) == DevelTextEditor::Property::INPUT_STRIKETHROUGH);
   DALI_TEST_CHECK(editor.GetPropertyIndex(PROPERTY_NAME_SELECTION_POPUP_STYLE) == DevelTextEditor::Property::SELECTION_POPUP_STYLE);
+  DALI_TEST_CHECK(editor.GetPropertyIndex(PROPERTY_NAME_REMOVE_FRONT_INSET) == DevelTextEditor::Property::REMOVE_FRONT_INSET);
+  DALI_TEST_CHECK(editor.GetPropertyIndex(PROPERTY_NAME_REMOVE_BACK_INSET) == DevelTextEditor::Property::REMOVE_BACK_INSET);
 
   END_TEST;
 }
@@ -1037,6 +1042,8 @@ int UtcDaliTextEditorSetPropertyP(void)
 
   outlineMapSet["color"] = Color::RED;
   outlineMapSet["width"] = 2.0f;
+  outlineMapSet["offset"] = Vector2(0.0f, 0.0f);
+  outlineMapSet["blurRadius"] = 0.0f;
 
   editor.SetProperty(TextEditor::Property::OUTLINE, outlineMapSet);
 
@@ -1265,6 +1272,18 @@ int UtcDaliTextEditorSetPropertyP(void)
   editor.SetProperty(DevelTextEditor::Property::MIN_LINE_SIZE, 50.f);
   DALI_TEST_EQUALS(editor.GetProperty<float>(DevelTextEditor::Property::MIN_LINE_SIZE), 50.0f, Math::MACHINE_EPSILON_1000, TEST_LOCATION);
 
+  // Check Remove Front/Back Inset Property
+  DALI_TEST_CHECK(editor.GetProperty<bool>(DevelTextEditor::Property::REMOVE_FRONT_INSET));
+  editor.SetProperty(DevelTextEditor::Property::REMOVE_FRONT_INSET, false);
+  DALI_TEST_CHECK(!editor.GetProperty<bool>(DevelTextEditor::Property::REMOVE_FRONT_INSET));
+
+  DALI_TEST_CHECK(editor.GetProperty<bool>(DevelTextEditor::Property::REMOVE_BACK_INSET));
+  editor.SetProperty(DevelTextEditor::Property::REMOVE_BACK_INSET, false);
+  DALI_TEST_CHECK(!editor.GetProperty<bool>(DevelTextEditor::Property::REMOVE_BACK_INSET));
+
+  application.SendNotification();
+  application.Render();
+
   END_TEST;
 }
 
@@ -6626,4 +6645,31 @@ int utcDaliTextEditorGetTextBoundingRectangle(void)
   TestTextGeometryUtils::CheckRectGeometryResult(textBoundingRectangle, expectedTextBoundingRectangle);
 
   END_TEST;
-}
\ No newline at end of file
+}
+
+int utcDaliTextEditorRemoveFrontInset(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextEditorRemoveFrontInset");
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK(editor);
+  application.GetScene().Add(editor);
+  application.SendNotification();
+  application.Render();
+  DevelTextEditor::SetRemoveFrontInset(editor, false);
+  DALI_TEST_CHECK(!DevelTextEditor::IsRemoveFrontInset(editor));
+  END_TEST;
+}
+int utcDaliTextEditorRemoveBackInset(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextEditorRemoveBackInset");
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK(editor);
+  application.GetScene().Add(editor);
+  application.SendNotification();
+  application.Render();
+  DevelTextEditor::SetRemoveBackInset(editor, false);
+  DALI_TEST_CHECK(!DevelTextEditor::IsRemoveBackInset(editor));
+  END_TEST;
+}
index ccc6bb3..d098f99 100644 (file)
@@ -115,6 +115,9 @@ const char* const PROPERTY_NAME_ENABLE_FONT_SIZE_SCALE          = "enableFontSiz
 const char* const PROPERTY_NAME_GRAB_HANDLE_COLOR               = "grabHandleColor";
 const char* const PROPERTY_NAME_INPUT_FILTER                    = "inputFilter";
 
+const char* const PROPERTY_NAME_REMOVE_FRONT_INSET    = "removeFrontInset";
+const char* const PROPERTY_NAME_REMOVE_BACK_INSET     = "removeBackInset";
+
 const Vector4       PLACEHOLDER_TEXT_COLOR(0.8f, 0.8f, 0.8f, 0.8f);
 const Dali::Vector4 LIGHT_BLUE(0.75f, 0.96f, 1.f, 1.f); // The text highlight color.
 
@@ -643,6 +646,8 @@ int UtcDaliTextFieldGetPropertyP(void)
   DALI_TEST_CHECK(field.GetPropertyIndex(PROPERTY_NAME_STRIKETHROUGH) == DevelTextField::Property::STRIKETHROUGH);
   DALI_TEST_CHECK(field.GetPropertyIndex(PROPERTY_NAME_INPUT_STRIKETHROUGH) == DevelTextField::Property::INPUT_STRIKETHROUGH);
   DALI_TEST_CHECK(field.GetPropertyIndex(PROPERTY_NAME_SELECTION_POPUP_STYLE) == DevelTextField::Property::SELECTION_POPUP_STYLE);
+  DALI_TEST_CHECK(field.GetPropertyIndex(PROPERTY_NAME_REMOVE_FRONT_INSET) == DevelTextField::Property::REMOVE_FRONT_INSET);
+  DALI_TEST_CHECK(field.GetPropertyIndex(PROPERTY_NAME_REMOVE_BACK_INSET) == DevelTextField::Property::REMOVE_BACK_INSET);
 
   END_TEST;
 }
@@ -1103,6 +1108,8 @@ int UtcDaliTextFieldSetPropertyP(void)
 
   outlineMapSet["color"] = Color::RED;
   outlineMapSet["width"] = 2.0f;
+  outlineMapSet["offset"] = Vector2(0.0f, 0.0f);
+  outlineMapSet["blurRadius"] = 0.0f;
 
   field.SetProperty(TextField::Property::OUTLINE, outlineMapSet);
 
@@ -1267,6 +1274,19 @@ int UtcDaliTextFieldSetPropertyP(void)
   application.SendNotification();
   application.Render();
 
+  // Check Remove Front/Back Inset Property
+  DALI_TEST_CHECK(field.GetProperty<bool>(DevelTextField::Property::REMOVE_FRONT_INSET));
+  field.SetProperty(DevelTextField::Property::REMOVE_FRONT_INSET, false);
+  DALI_TEST_CHECK(!field.GetProperty<bool>(DevelTextField::Property::REMOVE_FRONT_INSET));
+
+  DALI_TEST_CHECK(field.GetProperty<bool>(DevelTextField::Property::REMOVE_BACK_INSET));
+  field.SetProperty(DevelTextField::Property::REMOVE_BACK_INSET, false);
+  DALI_TEST_CHECK(!field.GetProperty<bool>(DevelTextField::Property::REMOVE_BACK_INSET));
+
+  application.SendNotification();
+  application.Render();
+
+
   END_TEST;
 }
 
@@ -3244,7 +3264,56 @@ int utcDaliTextFieldEvent08(void)
     event.AddPoint(GetPointUpInside(position));
     application.ProcessEvent(event);
   }
-  DALI_TEST_EQUALS(field.GetProperty<std::string>(TextEditor::Property::TEXT), std::string("testTextFieldEvent"), TEST_LOCATION);
+  DALI_TEST_EQUALS(field.GetProperty<std::string>(TextField::Property::TEXT), std::string("testTextFieldEvent"), TEST_LOCATION);
+
+  Dali::Clipboard::ClipData htmlData("application/xhtml+xml", "testTextFieldEventHtml");
+  clipboard.SetData(htmlData);
+
+  field.SetProperty(TextField::Property::TEXT, "");
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Long Press
+  TestGenerateLongPress(application, 1.0f, 25.0f, 20);
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  Wait(application, 500);
+
+  TestEndLongPress(application, 1.0f, 25.0f, 520);
+
+  // Long Press
+  TestGenerateLongPress(application, 1.0f, 25.0f, 600);
+
+  // Render and notify
+  application.Render();
+
+  Wait(application, 500);
+
+  stage = application.GetScene();
+  layer = stage.GetRootLayer();
+  actor = layer.FindChildByName("optionPaste");
+
+  if(actor)
+  {
+    Vector3 worldPosition = actor.GetCurrentProperty<Vector3>(Actor::Property::WORLD_POSITION);
+    Vector2 halfStageSize = stage.GetSize() / 2.0f;
+    Vector2 position(worldPosition.x + halfStageSize.width, worldPosition.y + halfStageSize.height);
+
+    Dali::Integration::TouchEvent event;
+    event = Dali::Integration::TouchEvent();
+    event.AddPoint(GetPointDownInside(position));
+    application.ProcessEvent(event);
+
+    event = Dali::Integration::TouchEvent();
+    event.AddPoint(GetPointUpInside(position));
+    application.ProcessEvent(event);
+  }
+  DALI_TEST_EQUALS(field.GetProperty<std::string>(TextField::Property::TEXT), std::string("testTextFieldEventHtml"), TEST_LOCATION);
 
   END_TEST;
 }
@@ -6083,4 +6152,40 @@ int utcDaliTextFieldDecoratorColor(void)
   application.Render();
 
   END_TEST;
-}
\ No newline at end of file
+}
+
+int utcDaliTextFieldRemoveFrontInset(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextFieldRemoveFrontInset");
+
+  TextField field = TextField::New();
+  DALI_TEST_CHECK(field);
+
+  application.GetScene().Add(field);
+  application.SendNotification();
+  application.Render();
+
+  DevelTextField::SetRemoveFrontInset(field, false);
+  DALI_TEST_CHECK(!DevelTextField::IsRemoveFrontInset(field));
+
+  END_TEST;
+}
+
+int utcDaliTextFieldRemoveBackInset(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextFieldRemoveBackInset");
+
+  TextField field = TextField::New();
+  DALI_TEST_CHECK(field);
+
+  application.GetScene().Add(field);
+  application.SendNotification();
+  application.Render();
+
+  DevelTextField::SetRemoveBackInset(field, false);
+  DALI_TEST_CHECK(!DevelTextField::IsRemoveBackInset(field));
+
+  END_TEST;
+}
index dd0b690..576bd0f 100644 (file)
@@ -952,6 +952,8 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
 
   outlineMapSet["color"] = Color::RED;
   outlineMapSet["width"] = 2.0f;
+  outlineMapSet["offset"] = Vector2(2.0f, 2.0f);
+  outlineMapSet["blurRadius"] = 3.0f;
   label.SetProperty(TextLabel::Property::OUTLINE, outlineMapSet);
 
   outlineMapGet = label.GetProperty<Property::Map>(TextLabel::Property::OUTLINE);
@@ -961,11 +963,14 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   outlineMapSet.Clear();
   outlineMapSet[Toolkit::DevelText::Outline::Property::COLOR] = Color::BLUE;
   outlineMapSet[Toolkit::DevelText::Outline::Property::WIDTH] = 3.0f;
+  outlineMapSet[Toolkit::DevelText::Outline::Property::OFFSET] = Vector2(3.0f, 3.0f);
+  outlineMapSet[Toolkit::DevelText::Outline::Property::BLUR_RADIUS] = 4.0f;
+
   label.SetProperty(TextLabel::Property::OUTLINE, outlineMapSet);
 
   outlineMapGet = label.GetProperty<Property::Map>(TextLabel::Property::OUTLINE);
   DALI_TEST_EQUALS(outlineMapGet.Count(), outlineMapSet.Count(), TEST_LOCATION);
-  std::vector<std::string> outlineIndicesConversionTable = {"color", "width"};
+  std::vector<std::string> outlineIndicesConversionTable = {"color", "width", "offset", "blurRadius"};
   DALI_TEST_EQUALS(DaliTestCheckMaps(outlineMapGet, outlineMapSet, outlineIndicesConversionTable), true, TEST_LOCATION);
 
   // Check the background property
@@ -1817,6 +1822,8 @@ int UtcDaliToolkitTextlabelTextStyle01(void)
 
   outlineMapSet["color"] = Color::BLUE;
   outlineMapSet["width"] = 2.0f;
+  outlineMapSet["offset"] = "2 2";
+  outlineMapSet["blurRadius"] = "3";
   label.SetProperty(TextLabel::Property::OUTLINE, outlineMapSet);
 
   application.SendNotification();
index 5f7d114..e2659ff 100644 (file)
@@ -1290,7 +1290,7 @@ int UtcDaliVisualGetPropertyMap10(void)
   propertyMap.Insert("underline", underlineMapSet.Add("enable", true).Add("color", Color::GREEN).Add("height", 1).Add("type", Text::Underline::Type::SOLID).Add("dashWidth", 2).Add("dashGap", 1));
 
   Property::Map outlineMapSet;
-  propertyMap.Insert("outline", outlineMapSet.Add("color", Color::YELLOW).Add("width", 1));
+  propertyMap.Insert("outline", outlineMapSet.Add("color", Color::YELLOW).Add("width", 1).Add("offset", Vector2(2.0f, 2.0f)).Add("blurRadius", 3.0f));
 
   Property::Map backgroundMapSet;
   propertyMap.Insert("textBackground", backgroundMapSet.Add("enable", true).Add("color", Color::CYAN));
@@ -3762,11 +3762,11 @@ int UtcDaliRegisterVisualOrder(void)
   dummyImpl.RegisterVisual(DummyControl::Property::FOCUS_VISUAL, focusVisual);
   DALI_TEST_CHECK(focusVisual.GetDepthIndex() > foregroundVisual.GetDepthIndex());
 
-  tet_infoline("Set depth index on a new visual before registering, the depth index should not have been changed");
+  tet_infoline("Set depth index on a new visual before registering, the depth index should not have been changed, and be clampled");
   Visual::Base labelVisual = factory.CreateVisual(propertyMap);
-  labelVisual.SetDepthIndex(-2000);
+  labelVisual.SetDepthIndex(static_cast<int>(Toolkit::DepthIndex::MINIMUM_DEPTH_INDEX) - 100);
   dummyImpl.RegisterVisual(DummyControl::Property::LABEL_VISUAL, labelVisual);
-  DALI_TEST_EQUALS(labelVisual.GetDepthIndex(), -2000, TEST_LOCATION);
+  DALI_TEST_EQUALS(labelVisual.GetDepthIndex(), static_cast<int>(Toolkit::DepthIndex::MINIMUM_DEPTH_INDEX), TEST_LOCATION);
 
   tet_infoline("Replace visual, the depth index should be the same as what was previously set");
   const int    testVisual2DepthIndex  = testVisual2.GetDepthIndex();
@@ -3775,11 +3775,11 @@ int UtcDaliRegisterVisualOrder(void)
   dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL2, testVisual2Replacement);
   DALI_TEST_EQUALS(testVisual2Replacement.GetDepthIndex(), testVisual2DepthIndex, TEST_LOCATION);
 
-  tet_infoline("Replace visual and set a depth index on the replacement, the depth index of the replacement should be honoured");
+  tet_infoline("Replace visual and set a depth index on the replacement, the depth index of the replacement should be honoured, and be clampled");
   Visual::Base anotherTestVisual2Replacement = factory.CreateVisual(propertyMap);
-  anotherTestVisual2Replacement.SetDepthIndex(2000);
+  anotherTestVisual2Replacement.SetDepthIndex(static_cast<int>(Toolkit::DepthIndex::MAXIMUM_DEPTH_INDEX) + 100);
   dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL2, anotherTestVisual2Replacement);
-  DALI_TEST_EQUALS(anotherTestVisual2Replacement.GetDepthIndex(), 2000, TEST_LOCATION);
+  DALI_TEST_EQUALS(anotherTestVisual2Replacement.GetDepthIndex(), static_cast<int>(Toolkit::DepthIndex::MAXIMUM_DEPTH_INDEX), TEST_LOCATION);
 
   dummyControl.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
   application.GetScene().Add(dummyControl);
@@ -3806,7 +3806,7 @@ int UtcDaliRegisterVisualOrder02(void)
 
   dummyControl.SetProperty(Control::Property::BACKGROUND, propertyMap);
 
-  const int TEST_VISUAL_1_DEPTH_INDEX = 0;
+  const int TEST_VISUAL_1_DEPTH_INDEX = static_cast<int>(Toolkit::DepthIndex::CONTENT);
   tet_printf("Register visual, should have depth index of %d\n", TEST_VISUAL_1_DEPTH_INDEX);
   Visual::Base testVisual1 = factory.CreateVisual(propertyMap);
   dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, testVisual1);
@@ -3815,7 +3815,14 @@ int UtcDaliRegisterVisualOrder02(void)
   tet_printf("Register another visual, should have a depth index greater than previous(%d)\n", TEST_VISUAL_1_DEPTH_INDEX);
   Visual::Base testVisual2 = factory.CreateVisual(propertyMap);
   dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL2, testVisual2);
-  DALI_TEST_CHECK(testVisual2.GetDepthIndex() > testVisual1.GetDepthIndex());
+  DALI_TEST_GREATER(testVisual2.GetDepthIndex(), testVisual1.GetDepthIndex(), TEST_LOCATION);
+
+  const int TEST_VISUAL_2_DEPTH_INDEX = testVisual2.GetDepthIndex();
+
+  tet_printf("Register other visual, should have a depth index greater than previous(%d)\n", TEST_VISUAL_2_DEPTH_INDEX);
+  Visual::Base testVisual3 = factory.CreateVisual(propertyMap);
+  dummyImpl.RegisterVisual(DummyControl::Property::FOREGROUND_VISUAL, testVisual3, Toolkit::DepthIndex::AUTO_INDEX);
+  DALI_TEST_GREATER(testVisual3.GetDepthIndex(), testVisual2.GetDepthIndex(), TEST_LOCATION);
 
   dummyControl.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
   application.GetScene().Add(dummyControl);
index 8c9b9b3..7fc62c1 100644 (file)
@@ -306,6 +306,7 @@ SceneView::SceneView()
   mSkybox(),
   mSkyboxOrientation(Quaternion()),
   mSkyboxIntensity(1.0f),
+  mLightObservers(),
   mShaderManager(new Scene3D::Loader::ShaderManager())
 {
 }
@@ -437,7 +438,7 @@ void SceneView::RegisterSceneItem(Scene3D::Internal::LightObserver* item)
   {
     item->NotifyImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor, mSpecularMipmapLevels);
     item->NotifyShadowMapTexture(mShadowTexture);
-    mItems.push_back(item);
+    mLightObservers.PushBack(item);
   }
 }
 
@@ -445,13 +446,10 @@ void SceneView::UnregisterSceneItem(Scene3D::Internal::LightObserver* item)
 {
   if(item)
   {
-    for(uint32_t i = 0; i < mItems.size(); ++i)
+    auto iter = mLightObservers.Find(item);
+    if(iter != mLightObservers.End())
     {
-      if(mItems[i] == item)
-      {
-        mItems.erase(mItems.begin() + i);
-        break;
-      }
+      mLightObservers.Erase(iter);
     }
   }
 }
@@ -566,7 +564,7 @@ void SceneView::SetImageBasedLightSource(const std::string& diffuseUrl, const st
 void SceneView::SetImageBasedLightScaleFactor(float scaleFactor)
 {
   mIblScaleFactor = scaleFactor;
-  for(auto&& item : mItems)
+  for(auto&& item : mLightObservers)
   {
     if(item)
     {
@@ -693,7 +691,7 @@ void SceneView::RemoveShadow(Scene3D::Light light)
   mShadowLight.Reset();
 
   mShadowTexture.Reset();
-  for(auto&& item : mItems)
+  for(auto&& item : mLightObservers)
   {
     if(item)
     {
@@ -1020,7 +1018,7 @@ void SceneView::OnSceneConnection(int depth)
 
 void SceneView::OnSceneDisconnection()
 {
-  mItems.clear();
+  mLightObservers.Clear();
 
   Window window = mWindow.GetHandle();
   if(window)
@@ -1369,7 +1367,7 @@ void SceneView::OnIblLoadComplete()
 
 void SceneView::NotifyImageBasedLightTextureChange()
 {
-  for(auto&& item : mItems)
+  for(auto&& item : mLightObservers)
   {
     if(item)
     {
@@ -1411,7 +1409,7 @@ void SceneView::UpdateShadowMapBuffer(uint32_t shadowMapSize)
     DevelFrameBuffer::AttachDepthTexture(mShadowFrameBuffer, mShadowTexture);
     mShadowMapRenderTask.SetFrameBuffer(mShadowFrameBuffer);
 
-    for(auto&& item : mItems)
+    for(auto&& item : mLightObservers)
     {
       if(item)
       {
index 3d8c639..29661ef 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali-toolkit/internal/visuals/image/image-visual.h>
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali/integration-api/adaptor-framework/scene-holder.h>
+#include <dali/integration-api/ordered-set.h>
 #include <dali/public-api/actors/camera-actor.h>
 #include <dali/public-api/actors/layer.h>
 #include <dali/public-api/adaptor-framework/window.h>
@@ -434,21 +435,22 @@ private:
 
   /////////////////////////////////////////////////////////////
   // FrameBuffer and Rendertask to render child objects as a 3D Scene
-  Dali::WeakHandle<Dali::Window>                 mWindow;
-  Integration::SceneHolder                       mSceneHolder;
-  CameraActor                                    mDefaultCamera;
-  CameraActor                                    mSelectedCamera;
-  std::vector<CameraActor>                       mCameras;
-  std::vector<Scene3D::Internal::LightObserver*> mItems;
-  Dali::FrameBuffer                              mFrameBuffer;
-  Dali::Texture                                  mTexture;
-  Dali::RenderTask                               mRenderTask;
-  Layer                                          mRootLayer;
-  int32_t                                        mWindowOrientation;
-  Dali::Actor                                    mSkybox;
-  Quaternion                                     mSkyboxOrientation;
-  float                                          mSkyboxIntensity{1.0f};
-  uint8_t                                        mFrameBufferMultiSamplingLevel{0u};
+  Dali::WeakHandle<Dali::Window> mWindow;
+  Integration::SceneHolder       mSceneHolder;
+  CameraActor                    mDefaultCamera;
+  CameraActor                    mSelectedCamera;
+  std::vector<CameraActor>       mCameras;
+  Dali::FrameBuffer              mFrameBuffer;
+  Dali::Texture                  mTexture;
+  Dali::RenderTask               mRenderTask;
+  Layer                          mRootLayer;
+  int32_t                        mWindowOrientation;
+  Dali::Actor                    mSkybox;
+  Quaternion                     mSkyboxOrientation;
+  float                          mSkyboxIntensity{1.0f};
+  uint8_t                        mFrameBufferMultiSamplingLevel{0u};
+
+  Dali::Integration::OrderedSet<Scene3D::Internal::LightObserver, false> mLightObservers; ///< The set of items to be notified when light properties change. (not owned)
 
   bool     mWindowSizeChanged{false};
   uint32_t mWindowWidth{0};
index c0a873d..5218700 100644 (file)
@@ -1,3 +1,4 @@
+#define MORPH defined(MORPH_POSITION) || defined(MORPH_NORMAL) || defined(MORPH_TANGENT)
 
 #define ADD_EXTRA_SKINNING_ATTRIBUTES
 #define ADD_EXTRA_WEIGHTS
index 8788ade..7e6981b 100644 (file)
 
 #include <dali/devel-api/actors/actor-devel.h>
 #include <dali/devel-api/adaptor-framework/window-devel.h>
+#include <dali/public-api/object/property-map.h>
 #include <dali/public-api/object/type-info.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/visuals/image/image-visual.h>
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/control.h>
 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
@@ -39,7 +41,9 @@ namespace Dali::Toolkit::DevelControl
 {
 namespace
 {
-static std::string GetLocaleText(std::string string, const char* domain = "dali-toolkit")
+constexpr const char* ATTR_IMG_SRC_KEY = "imgSrc";
+
+std::string GetLocaleText(std::string string, const char* domain = "dali-toolkit")
 {
 #ifdef DGETTEXT_ENABLED
   /*TODO: currently non-localized string is used as a key for translation lookup. In case the lookup key formatting is forced
@@ -50,7 +54,7 @@ static std::string GetLocaleText(std::string string, const char* domain = "dali-
 #endif
 }
 
-static Dali::Actor CreateHighlightIndicatorActor()
+Dali::Actor CreateHighlightIndicatorActor()
 {
   std::string focusBorderImagePath(AssetManager::GetDaliImagePath());
   focusBorderImagePath += "/keyboard_focus.9.png";
@@ -65,6 +69,45 @@ static Dali::Actor CreateHighlightIndicatorActor()
 
   return actor;
 }
+
+std::string FetchImageSrcFromMap(const Dali::Property::Map& imageMap)
+{
+  auto urlVal = imageMap.Find(Toolkit::ImageVisual::Property::URL);
+  if(urlVal)
+  {
+    if(urlVal->GetType() == Dali::Property::STRING)
+    {
+      return urlVal->Get<std::string>();
+    }
+    else if(urlVal->GetType() == Dali::Property::ARRAY)
+    {
+      auto urlArray = urlVal->GetArray();
+      if(urlArray && !urlArray->Empty())
+      {
+        // Returns first element if url is an array
+        return (*urlArray)[0].Get<std::string>();
+      }
+    }
+  }
+  return {};
+}
+
+std::string FetchImageSrc(const Toolkit::ImageView& imageView)
+{
+  const auto imageUrl = imageView.GetProperty<std::string>(Toolkit::ImageView::Property::IMAGE);
+  if(!imageUrl.empty())
+  {
+    return imageUrl;
+  }
+
+  const auto imageMap = imageView.GetProperty<Dali::Property::Map>(Toolkit::ImageView::Property::IMAGE);
+  if(!imageMap.Empty())
+  {
+    return FetchImageSrcFromMap(imageMap);
+  }
+  return {};
+}
+
 } // unnamed namespace
 
 ControlAccessible::ControlAccessible(Dali::Actor self)
@@ -192,7 +235,7 @@ Dali::Accessibility::States ControlAccessible::CalculateStates()
   states[State::FOCUSABLE]     = self.GetProperty<bool>(Actor::Property::KEYBOARD_FOCUSABLE);
   states[State::FOCUSED]       = Toolkit::KeyboardFocusManager::Get().GetCurrentFocusActor() == self;
   states[State::HIGHLIGHTABLE] = self.GetProperty<bool>(Toolkit::DevelControl::Property::ACCESSIBILITY_HIGHLIGHTABLE);
-  states[State::HIGHLIGHTED]   = GetCurrentlyHighlightedActor() == self;
+  states[State::HIGHLIGHTED]   = IsHighlighted();
   states[State::ENABLED]       = true;
   states[State::SENSITIVE]     = (Dali::DevelActor::IsHittable(self) && Dali::DevelActor::GetTouchRequired(self));
   states[State::VISIBLE]       = self.GetProperty<bool>(Actor::Property::VISIBLE);
@@ -235,6 +278,15 @@ Dali::Accessibility::Attributes ControlAccessible::GetAttributes() const
     result.emplace(automationIdKey, std::move(automationId));
   }
 
+  if(auto imageView = Toolkit::ImageView::DownCast(Self()))
+  {
+    auto imageSrc = FetchImageSrc(imageView);
+    if(!imageSrc.empty())
+    {
+      result.emplace(ATTR_IMG_SRC_KEY, std::move(imageSrc));
+    }
+  }
+
   // Add "class" if not present already
   if(result.find(classKey) == result.end())
   {
@@ -373,18 +425,16 @@ bool ControlAccessible::GrabHighlight()
 
 bool ControlAccessible::ClearHighlight()
 {
-  Dali::Actor self = Self();
-
   if(!Dali::Accessibility::IsUp())
   {
     return false;
   }
 
-  if(GetCurrentlyHighlightedActor() == self)
+  if(IsHighlighted())
   {
     UnregisterPropertySetSignal();
     UnregisterPositionPropertyNotification();
-    self.Remove(mCurrentHighlightActor.GetHandle());
+    Self().Remove(mCurrentHighlightActor.GetHandle());
     mCurrentHighlightActor = {};
     SetCurrentlyHighlightedActor({});
     EmitHighlighted(false);
index 3aa0c9f..e66c4ee 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_DEVEL_CONTROL_DEPTH_INDEX_RANGES_H
 
 /*
- * Copyright (c) 2020 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.
@@ -30,25 +30,41 @@ namespace DepthIndex
 // The negative value for background effect and background has been
 // chosen so that newer controls can have content without setting
 // depth index, and go in front of native controls with a background.
-// This backround negative value means that the highest possible value
-// is SIBLING_ORDER_MULTIPLIER-BACKGROUND_EFFECT-1.  The divisor of
-// 100 ensures the range fits within the sibling order range, and has
-// enough gaps to allow Control Authors to use other intermediate depths.
+// The lowest possible value is MINIMUM_DEPTH_INDEX, and highest possible
+// value is MAXIMUM_DEPTH_INDEX. The divisor of 10 ensures the range fits
+// within the sibling order range, and has enough gaps to allow Control
+// Authors to use other intermediate depths.
+//
+// Note : AUTO_INDEX is special value. It means that the depth index will be
+// automatically assigned when we register visual into the control.
+// Other values will be clamped to the range.
 
 enum Ranges
 {
-  BACKGROUND_EFFECT = -2 * DevelLayer::SIBLING_ORDER_MULTIPLIER / 100,
-  BACKGROUND        = -1 * DevelLayer::SIBLING_ORDER_MULTIPLIER / 100,
-  CONTENT           = 0,
-  DECORATION        = 1 * DevelLayer::SIBLING_ORDER_MULTIPLIER / 100,
-  FOREGROUND_EFFECT = 2 * DevelLayer::SIBLING_ORDER_MULTIPLIER / 100
+  MINIMUM_DEPTH_INDEX = -5 * DevelLayer::SIBLING_ORDER_MULTIPLIER / 10 + 1,
+  BACKGROUND_EFFECT   = -2 * DevelLayer::SIBLING_ORDER_MULTIPLIER / 10,
+  BACKGROUND          = -1 * DevelLayer::SIBLING_ORDER_MULTIPLIER / 10,
+  CONTENT             = 0,
+  DECORATION          = 1 * DevelLayer::SIBLING_ORDER_MULTIPLIER / 10,
+  FOREGROUND_EFFECT   = 2 * DevelLayer::SIBLING_ORDER_MULTIPLIER / 10,
+  MAXIMUM_DEPTH_INDEX = 5 * DevelLayer::SIBLING_ORDER_MULTIPLIER / 10,
+
+  AUTO_INDEX = MINIMUM_DEPTH_INDEX - 1, ///< Special value to indicate that the depth index should be automatically calculated.
+                                        ///  If visual replaced by another visual, the depth index of the new visual will be set to previous visual.
+                                        ///  Otherwise, depth index will be set as the maximum depth index + 1
+                                        ///  what given control already has, or CONTENT if no visuals.
 };
 
 static_assert((unsigned int)DevelLayer::ACTOR_DEPTH_MULTIPLIER > (unsigned int)DevelLayer::SIBLING_ORDER_MULTIPLIER);
+static_assert(MINIMUM_DEPTH_INDEX < BACKGROUND_EFFECT);
 static_assert(BACKGROUND_EFFECT < BACKGROUND);
 static_assert(BACKGROUND < CONTENT);
 static_assert(CONTENT < DECORATION);
 static_assert(DECORATION < FOREGROUND_EFFECT);
+static_assert(FOREGROUND_EFFECT < MAXIMUM_DEPTH_INDEX);
+
+// AUTO_INDEX should not be inside of the valid range.
+static_assert(!(MINIMUM_DEPTH_INDEX <= AUTO_INDEX && AUTO_INDEX <= MAXIMUM_DEPTH_INDEX));
 
 } // namespace DepthIndex
 
index fe2548f..465041a 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_CONTROL_DEVEL_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.
@@ -236,8 +236,7 @@ enum
  *
  * @note Derived class should not call visual.SetOnScene(actor). It is the responsibility of the base class to connect/disconnect registered visual to stage.
  *       Use below API with enabled set to false if derived class wishes to control when visual is staged.
- * @note If the depth-index is not set on the visual, then it is set to be above the currently registered visuals.
- * @note If replacing a visual, then the depth-index of the visual being replaced is used for the visual.
+ * @note depth-index be used to Dali::Toolkit::DepthIndex::Ranges::AUTO_INDEX.
  */
 DALI_TOOLKIT_API void RegisterVisual(Internal::Control& control, Dali::Property::Index index, Toolkit::Visual::Base& visual);
 
@@ -247,7 +246,9 @@ DALI_TOOLKIT_API void RegisterVisual(Internal::Control& control, Dali::Property:
  * @param[in] control The control
  * @param[in] index The Property index of the visual, used to reference visual
  * @param[in] visual The visual to register
- * @param[in] depthIndex The visual's depth-index is set to this
+ * @param[in] depthIndex The visual's depth-index is set to this. If the depth-index is set to DepthIndex::Ranges::AUTO_INDEX,
+ *                       the actual depth-index of visual will be determind automatically (Use previous visuals depth-index, or placed on top of all other visuals.)
+ *                       Otherwise, the visual's depth-index is set to clamped value, between DepthIndex::Ranges::MINIMUM_DEPTH_INDEX and DepthIndex::Ranges::MAXIMUM_DEPTH_INDEX.
  *
  * @note Derived class should not call visual.SetOnScene(actor). It is the responsibility of the base class to connect/disconnect registered visual to stage.
  *       Use below API with enabled set to false if derived class wishes to control when visual is staged.
@@ -265,8 +266,7 @@ DALI_TOOLKIT_API void RegisterVisual(Internal::Control& control, Dali::Property:
  * @param[in] visual The visual to register
  * @param[in] enabled false if derived class wants to control when visual is set on stage.
  *
- * @note If the depth-index is not set on the visual, then it is set to be above the currently registered visuals.
- * @note If replacing a visual, then the depth-index of the visual being replaced is used for the visual.
+ * @note depth-index be used to Dali::Toolkit::DepthIndex::Ranges::AUTO_INDEX.
  *
  * @see EnableVisual()
  */
@@ -279,7 +279,9 @@ DALI_TOOLKIT_API void RegisterVisual(Internal::Control& control, Dali::Property:
  * @param[in] index The Property index of the visual, used to reference visual
  * @param[in] visual The visual to register
  * @param[in] enabled false if derived class wants to control when visual is set on stage.
- * @param[in] depthIndex The visual's depth-index is set to this
+ * @param[in] depthIndex The visual's depth-index is set to this. If the depth-index is set to DepthIndex::Ranges::AUTO_INDEX,
+ *                       the actual depth-index of visual will be determind automatically (Use previous visuals depth-index, or placed on top of all other visuals.)
+ *                       Otherwise, the visual's depth-index is set to clamped value, between DepthIndex::Ranges::MINIMUM_DEPTH_INDEX and DepthIndex::Ranges::MAXIMUM_DEPTH_INDEX.
  *
  * @see EnableVisual()
  * @see Visual::Base::GetDepthIndex()
index eeef11f..84a80b7 100644 (file)
@@ -115,6 +115,26 @@ void PasteText(TextEditor textEditor)
   GetImpl(textEditor).PasteText();
 }
 
+void SetRemoveFrontInset(TextEditor textEditor, const bool remove)
+{
+  GetImpl(textEditor).SetRemoveFrontInset(remove);
+}
+
+bool IsRemoveFrontInset(TextEditor textEditor)
+{
+  return GetImpl(textEditor).IsRemoveFrontInset();
+}
+
+void SetRemoveBackInset(TextEditor textEditor, const bool remove)
+{
+  GetImpl(textEditor).SetRemoveBackInset(remove);
+}
+
+bool IsRemoveBackInset(TextEditor textEditor)
+{
+  return GetImpl(textEditor).IsRemoveBackInset();
+}
+
 } // namespace DevelTextEditor
 
 } // namespace Toolkit
index 9aab35f..1831327 100644 (file)
@@ -325,6 +325,18 @@ enum Type
    * @see Dali::Toolkit::TextSelectionPopup::Property
    */
   SELECTION_POPUP_STYLE,
+
+  /**
+   * @brief Whether to trim the xBearing of first glyph of the text.
+   * @details Name "removeFrontInset", type Property::BOOLEAN.
+   */
+  REMOVE_FRONT_INSET,
+
+  /**
+   * @brief Whether to trim the advance of last glyph of the text.
+   * @details Name "removeBackInset", type Property::BOOLEAN.
+   */
+  REMOVE_BACK_INSET,
 };
 
 } // namespace Property
@@ -575,6 +587,39 @@ DALI_TOOLKIT_API std::string CutText(TextEditor textEditor);
  */
 DALI_TOOLKIT_API void PasteText(TextEditor textEditor);
 
+/**
+ * @brief Set removing front inset to text label.
+ *
+ * @param[in] textEditor The instance of TextLabel.
+ * @param[in] remove Whether front inset of text label has to be removed or not.
+ */
+DALI_TOOLKIT_API void SetRemoveFrontInset(TextEditor textEditor, const bool remove);
+
+/**
+ * @brief Whether front inset of text label is removed or not.
+ *
+ * @param[in] textEditor The instance of TextLabel.
+ * @return True if the front inset of text label is removed.
+ */
+DALI_TOOLKIT_API bool IsRemoveFrontInset(TextEditor textEditor);
+
+/**
+ * @brief Set removing back inset to text label.
+ *
+ * @param[in] textEditor The instance of TextLabel.
+ * @param[in] remove Whether back inset of text label has to be removed or not.
+ */
+DALI_TOOLKIT_API void SetRemoveBackInset(TextEditor textEditor, const bool remove);
+
+/**
+ * @brief Whether back inset of text label is removed or not.
+ *
+ * @param[in] textEditor The instance of TextLabel.
+ * @return True if the back inset of text label is removed.
+ */
+DALI_TOOLKIT_API bool IsRemoveBackInset(TextEditor textEditor);
+
+
 } // namespace DevelTextEditor
 
 } // namespace Toolkit
index 2105756..7f19475 100644 (file)
@@ -105,6 +105,26 @@ void PasteText(TextField textField)
   GetImpl(textField).PasteText();
 }
 
+void SetRemoveFrontInset(TextField textField, const bool remove)
+{
+  GetImpl(textField).SetRemoveFrontInset(remove);
+}
+
+bool IsRemoveFrontInset(TextField textField)
+{
+  return GetImpl(textField).IsRemoveFrontInset();
+}
+
+void SetRemoveBackInset(TextField textField, const bool remove)
+{
+  GetImpl(textField).SetRemoveBackInset(remove);
+}
+
+bool IsRemoveBackInset(TextField textField)
+{
+  return GetImpl(textField).IsRemoveBackInset();
+}
+
 } // namespace DevelTextField
 
 } // namespace Toolkit
index a061819..8d368ee 100644 (file)
@@ -249,6 +249,18 @@ enum
    * @see Dali::Toolkit::TextSelectionPopup::Property
    */
   SELECTION_POPUP_STYLE,
+
+  /**
+   * @brief Whether to trim the xBearing of first glyph of the text.
+   * @details Name "removeFrontInset", type Property::BOOLEAN.
+   */
+  REMOVE_FRONT_INSET,
+
+  /**
+   * @brief Whether to trim the advance of last glyph of the text.
+   * @details Name "removeBackInset", type Property::BOOLEAN.
+   */
+  REMOVE_BACK_INSET,
 };
 
 } // namespace Property
@@ -474,6 +486,38 @@ DALI_TOOLKIT_API std::string CutText(TextField textField);
  */
 DALI_TOOLKIT_API void PasteText(TextField textField);
 
+/**
+ * @brief Set removing front inset to TextField.
+ *
+ * @param[in] textField The instance of TextField.
+ * @param[in] remove Whether front inset of TextField has to be removed or not.
+ */
+DALI_TOOLKIT_API void SetRemoveFrontInset(TextField textField, const bool remove);
+
+/**
+ * @brief Whether front inset of TextField is removed or not.
+ *
+ * @param[in] textField The instance of TextField.
+ * @return True if the front inset of TextField is removed.
+ */
+DALI_TOOLKIT_API bool IsRemoveFrontInset(TextField textField);
+
+/**
+ * @brief Set removing back inset to TextField.
+ *
+ * @param[in] textField The instance of TextField.
+ * @param[in] remove Whether back inset of TextField has to be removed or not.
+ */
+DALI_TOOLKIT_API void SetRemoveBackInset(TextField textField, const bool remove);
+
+/**
+ * @brief Whether back inset of TextField is removed or not.
+ *
+ * @param[in] textField The instance of TextField.
+ * @return True if the back inset of TextField is removed.
+ */
+DALI_TOOLKIT_API bool IsRemoveBackInset(TextField textField);
+
 } // namespace DevelTextField
 
 } // namespace Toolkit
index e3641f6..687897b 100644 (file)
@@ -137,7 +137,21 @@ enum
    * @details Name "width", type Property::STRING or Property::FLOAT i.e. "1.0" or 1.f
    * @note Optional. If not provided then the outline is not enabled.
    */
-  WIDTH
+  WIDTH,
+
+  /**
+   * @brief The offset in pixels of the outline.
+   * @details Name "offset", type Property::STRING or Property::VECTOR2. i.e "3.0 3.0" or Vector2( 3.f, 3.f )
+   * @note Optional. If not provided then the outline is not enabled.
+   */
+  OFFSET,
+
+  /**
+   * @brief The radius of the Gaussian blur for the outline.
+   * @details Name "blurRadius", type Property::STRING or Property::FLOAT. i.e "5.0" or 5.f
+   * @note Optional. If not provided then the outline is not enabled.
+   */
+  BLUR_RADIUS
 };
 
 } // namespace Property
index 14538fd..2a43766 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXT_RANGE_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -144,16 +144,6 @@ public: //Methods
 
 } // namespace Toolkit
 
-// Allow Range to be treated as a POD type
-template<>
-struct TypeTraits<Dali::Toolkit::Text::Range> : public BasicTypes<Dali::Toolkit::Text::Range>
-{
-  enum
-  {
-    IS_TRIVIAL_TYPE = true
-  };
-};
-
 } // namespace Dali
 
 #endif // DALI_TOOLKIT_TEXT_RANGE_H
index e3f7f29..5769965 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXT_BASE_SPAN_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -122,16 +122,6 @@ public: // Not intended for application developers
 
 } // namespace Toolkit
 
-// Allow BaseSpan to be treated as a POD type
-template<>
-struct TypeTraits<Dali::Toolkit::Text::BaseSpan> : public BasicTypes<Dali::Toolkit::Text::BaseSpan>
-{
-  enum
-  {
-    IS_TRIVIAL_TYPE = true
-  };
-};
-
 } // namespace Dali
 
 #endif // DALI_TOOLKIT_TEXT_BASE_SPAN_H
index 3b03dbe..dc31868 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef DALI_TOOLKIT_VISUAL_BASE_H
 #define DALI_TOOLKIT_VISUAL_BASE_H
 /*
- * Copyright (c) 2020 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.
@@ -167,14 +167,20 @@ public:
    * @brief Set the depth index of this visual.
    *
    * Depth-index controls draw-order for overlapping visuals.
-   * Visuals with higher depth indices are rendered in front of other visual with smaller values
+   * Visuals with higher depth indices are rendered in front of other visual with smaller values.
+   *
+   * @note The value of index will be clamped between DepthIndex::Ranges::MINIMUM_DEPTH_INDEX and
+   * DepthIndex::Ranges::MAXIMUM_DEPTH_INDEX.
+   * @note If we call this API at least 1 time, we cannot set as DepthIndex::AUTO_INDEX after.
    *
    * @param[in] index The depth index of this visual.
    */
   void SetDepthIndex(int index);
 
   /**
-   * @brief Get the depth index of this visual
+   * @brief Get the depth index of this visual which clamped between
+   * DepthIndex::Ranges::MINIMUM_DEPTH_INDEX and DepthIndex::Ranges::MAXIMUM_DEPTH_INDEX.
+   * Or DepthIndex::Ranges::AUTO_INDEX if we never set depth index before.
    *
    * @return The depth index of this visual.
    */
index a5e135c..90e868e 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_DEVEL_API_VISUALS_IMAGE_VISUAL_PROPERTIES_DEVEL_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.
@@ -193,13 +193,24 @@ enum Type
 
   /**
    * @brief Whether to AnimatedVectorImageVisual fixed cache or not.
-   * @details Name "EnableFrameCache", type Property::BOOLEAN.
+   * @details Name "enableFrameCache", type Property::BOOLEAN.
    * If this property is true, AnimatedVectorImageVisual enable frame cache for loading and keeps loaded frame
    * until the visual is removed. It reduces CPU cost when the animated image will be looping.
    * But it can spend a lot of memory if the resource has high resolution image or many frame count.
-   * @note It is used in the AnimatedImageVisual. The default is false
+   * @note It is used in the AnimatedVectorImageVisual. The default is false
    */
-  ENABLE_FRAME_CACHE = ORIENTATION_CORRECTION + 16
+  ENABLE_FRAME_CACHE = ORIENTATION_CORRECTION + 16,
+
+  /**
+   * @brief Whether notify AnimatedVectorImageVisual to render thread after every rasterization or not.
+   * @details Name "notifyAfterRasterization", type Property::BOOLEAN.
+   * If this property is true, AnimatedVectorImageVisual send notify to render thread after every rasterization.
+   * If false, AnimatedVectorImageVisual set Renderer's Behaviour as Continouly (mean, always update the render thread.)
+   *
+   * This flag is useful if given resource has low fps, so we don't need to render every frame.
+   * @note It is used in the AnimatedVectorImageVisual. The default is false.
+   */
+  NOTIFY_AFTER_RASTERIZATION = ORIENTATION_CORRECTION + 17
 };
 
 } //namespace Property
index aa23c76..3f7e73e 100644 (file)
@@ -162,9 +162,17 @@ void TreeNodeManipulator::RemoveChildren()
 {
   DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
 
-  DeleteNodesWithoutSelf otherDeletor(mNode);
+  CollectNodes collector;
 
-  DepthFirst(mNode, otherDeletor);
+  DepthFirst(mNode, collector);
+
+  for(CollectNodes::iterator iter = collector.nodes.begin(); iter != collector.nodes.end(); ++iter)
+  {
+    if(*iter != mNode)
+    {
+      delete *iter;
+    }
+  }
 
   mNode->mFirstChild = NULL;
   mNode->mLastChild  = NULL;
index 24599a5..b231302 100644 (file)
@@ -215,29 +215,6 @@ struct CollectNodes
 };
 
 /*
- * Delete nodes immediately, instead of self
- */
-struct DeleteNodesWithoutSelf
-{
-  DeleteNodesWithoutSelf(TreeNode* self)
-  : mSelf(self){};
-
-  /*
-   * Call operator to delete object if given node is not self
-   */
-  void operator()(TreeNode*& n)
-  {
-    DALI_ASSERT_DEBUG(n && "Operation on NULL JSON node");
-    if(mSelf != n)
-    {
-      delete n;
-    }
-  }
-
-  const TreeNode* mSelf; ///< self node what we should not remove.
-};
-
-/*
  * Depth first walk of nodes applying given operation (unary_function)
  */
 template<typename Operation>
index 574ef08..b000325 100644 (file)
@@ -99,10 +99,10 @@ Dali::Accessibility::States CheckBoxButton::CheckBoxButtonAccessible::CalculateS
 void CheckBoxButton::OnStateChange(State newState)
 {
   // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
-  if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+  if(newState == SELECTED_STATE || newState == UNSELECTED_STATE)
   {
     auto* accessible = GetAccessibleObject();
-    if(DALI_LIKELY(accessible))
+    if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
     {
       accessible->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
     }
index dea0ee0..70e7261 100644 (file)
@@ -207,10 +207,10 @@ Dali::Accessibility::States PushButton::PushButtonAccessible::CalculateStates()
 void PushButton::OnStateChange(State newState)
 {
   // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
-  if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+  if(newState == SELECTED_STATE || newState == UNSELECTED_STATE)
   {
     auto* accessible = GetAccessibleObject();
-    if(DALI_LIKELY(accessible))
+    if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
     {
       accessible->EmitStateChanged(Dali::Accessibility::State::PRESSED, newState == SELECTED_STATE ? 1 : 0, 0);
 
index 9aace1a..d352f2b 100644 (file)
@@ -107,10 +107,10 @@ void RadioButton::OnStateChange(State newState)
   }
 
   // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
-  if((Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor() == Self()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+  if(newState == SELECTED_STATE || newState == UNSELECTED_STATE)
   {
     auto* accessible = GetAccessibleObject();
-    if(DALI_LIKELY(accessible))
+    if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
     {
       accessible->EmitStateChanged(Dali::Accessibility::State::CHECKED, newState == SELECTED_STATE ? 1 : 0, 0);
     }
index deab292..5dd9b87 100644 (file)
@@ -325,7 +325,7 @@ void ToggleButton::PrepareVisual(Property::Index index, Toolkit::Visual::Base& v
     DevelControl::UnregisterVisual(*this, index);
   }
 
-  DevelControl::RegisterVisual(*this, index, visual, enabled);
+  DevelControl::RegisterVisual(*this, index, visual, enabled, DepthIndex::CONTENT);
 }
 
 void ToggleButton::RelayoutVisual(Property::Index index, const Vector2& size)
@@ -412,10 +412,10 @@ Property::Index ToggleButton::ToggleButtonAccessible::GetDescriptionPropertyInde
 void ToggleButton::OnStateChange(State newState)
 {
   // TODO: replace it with OnPropertySet hook once Button::Property::SELECTED will be consistently used
-  if((Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor()) && (newState == SELECTED_STATE || newState == UNSELECTED_STATE))
+  if(newState == SELECTED_STATE || newState == UNSELECTED_STATE)
   {
     auto* accessible = GetAccessibleObject();
-    if(DALI_LIKELY(accessible))
+    if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
     {
       accessible->EmitStateChanged(Dali::Accessibility::State::CHECKED, mCurrentToggleIndex ? 1 : 0, 0);
       accessible->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::DESCRIPTION);
index e67be8e..5488957 100644 (file)
@@ -798,6 +798,10 @@ void Control::Impl::RegisterVisual(Property::Index index, Toolkit::Visual::Base&
     requiredDepthIndex = depthIndex;
   }
 
+  // Change the depth index value automatically if the visual has DepthIndex to AUTO_INDEX
+  // or if RegisterVisual set DepthIndex to AUTO_INDEX.
+  const bool requiredDepthIndexChanged = (requiredDepthIndex == DepthIndex::AUTO_INDEX);
+
   // Visual replacement, existing visual should only be removed from stage when replacement ready.
   if(!mVisuals.Empty())
   {
@@ -839,11 +843,11 @@ void Control::Impl::RegisterVisual(Property::Index index, Toolkit::Visual::Base&
           mVisuals.Erase(registeredVisualsiter);
         }
 
-        // If we've not set the depth-index value and the new visual does not have a depth index applied to it, then use the previously set depth-index for this index
-        if((depthIndexValueSet == DepthIndexValue::NOT_SET) &&
-           (visual.GetDepthIndex() == 0))
+        // If the visual have a depth index as AUTO_INDEX and the new visual does not have a depth index applied to it, then use the previously set depth-index for this index
+        if(requiredDepthIndexChanged)
         {
           requiredDepthIndex = currentDepthIndex;
+          DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Use replaced visual index. VisualDepthIndex AUTO_INDEX set as: %d\n", requiredDepthIndex);
         }
       }
 
@@ -866,12 +870,10 @@ void Control::Impl::RegisterVisual(Property::Index index, Toolkit::Visual::Base&
 
   if(!visualReplaced) // New registration entry
   {
-    // If we've not set the depth-index value, we have more than one visual and the visual does not have a depth index, then set it to be the highest
-    if((depthIndexValueSet == DepthIndexValue::NOT_SET) &&
-       (mVisuals.Size() > 0) &&
-       (visual.GetDepthIndex() == 0))
+    // If we have more than one visual and the visual have a depth index as AUTO_INDEX, then set it to be the highest
+    if((mVisuals.Size() > 0) && requiredDepthIndexChanged)
     {
-      int maxDepthIndex = std::numeric_limits<int>::min();
+      int maxDepthIndex = static_cast<int>(DepthIndex::CONTENT) - 1; // Start at DepthIndex::CONTENT if maxDepth index belongs to a background or no visuals have been added yet.
 
       RegisteredVisualContainer::ConstIterator       iter;
       const RegisteredVisualContainer::ConstIterator endIter = mVisuals.End();
@@ -883,13 +885,20 @@ void Control::Impl::RegisterVisual(Property::Index index, Toolkit::Visual::Base&
           maxDepthIndex = visualDepthIndex;
         }
       }
-      ++maxDepthIndex;                                 // Add one to the current maximum depth index so that our added visual appears on top
-      requiredDepthIndex = std::max(0, maxDepthIndex); // Start at zero if maxDepth index belongs to a background
+      requiredDepthIndex = ++maxDepthIndex; // Add one to the current maximum depth index so that our added visual appears on top.
+      DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Use top of all visuals. VisualDepthIndex AUTO_INDEX set as: %d\n", requiredDepthIndex);
     }
   }
 
   if(visual)
   {
+    // If required depth index still DepthIndex::AUTO_INDEX, Make it as DepthIndex::CONTENT now
+    if(requiredDepthIndex == static_cast<int>(DepthIndex::AUTO_INDEX))
+    {
+      requiredDepthIndex = static_cast<int>(DepthIndex::CONTENT);
+      DALI_LOG_INFO(gLogFilter, Debug::Verbose, "Some strange cases. VisualDepthIndex AUTO_INDEX set as: %d\n", requiredDepthIndex);
+    }
+
     // Set determined depth index
     visual.SetDepthIndex(requiredDepthIndex);
 
index b2109ee..ed38e3f 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_CONTROL_DATA_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.
  */
 
 // EXTERNAL INCLUDES
-#include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali/devel-api/adaptor-framework/accessibility.h>
 #include <dali/public-api/object/property-notification.h>
 #include <dali/public-api/object/type-registry.h>
 #include <string>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-base.h>
 #include <dali-toolkit/internal/builder/dictionary.h>
 #include <dali-toolkit/internal/builder/style.h>
@@ -501,12 +502,14 @@ private:
    * @param[in,out] visual The visual to register, which can be altered in this function
    * @param[in] enabled false if derived class wants to control when visual is set on stage
    * @param[in] depthIndexValueSet Set to true if the depthIndex has actually been set manually
-   * @param[in] depthIndex The visual's depth-index is set to this
+   * @param[in] depthIndex The visual's depth-index is set to this. If the depth-index is set to DepthIndex::Ranges::AUTO_INDEX,
+   *                       the actual depth-index of visual will be determind automatically (Use previous visuals depth-index, or placed on top of all other visuals.)
+   *                       Otherwise, the visual's depth-index is set to clamped value, between DepthIndex::Ranges::MINIMUM_DEPTH_INDEX and DepthIndex::Ranges::MAXIMUM_DEPTH_INDEX.
    *
    * @note Registering a visual with an index that already has a registered visual will replace it. The replacement will
    *       occur once the replacement visual is ready (loaded).
    */
-  void RegisterVisual(Property::Index index, Toolkit::Visual::Base& visual, VisualState::Type enabled, DepthIndexValue::Type depthIndexValueSet, int depthIndex = 0);
+  void RegisterVisual(Property::Index index, Toolkit::Visual::Base& visual, VisualState::Type enabled, DepthIndexValue::Type depthIndexValueSet, int depthIndex = static_cast<int>(Toolkit::DepthIndex::AUTO_INDEX));
 
   /**
    * @brief Emits the resource ready signal.
index 01b84f7..be66265 100644 (file)
@@ -151,6 +151,7 @@ void DrawableView::OnSceneConnection(int depth)
   // the designed behaviour of GlView so signal is connected regardless
   if(window)
   {
+    mPlacementWindow = window;
     DevelWindow::VisibilityChangedSignal(window).Connect(this, &DrawableView::OnWindowVisibilityChanged);
   }
 }
@@ -160,6 +161,13 @@ void DrawableView::OnSceneDisconnection()
   Control::OnSceneDisconnection();
 
   mNativeRenderer->Terminate();
+
+  Window window = mPlacementWindow.GetHandle();
+  if(window)
+  {
+    DevelWindow::VisibilityChangedSignal(window).Disconnect(this, &DrawableView::OnWindowVisibilityChanged);
+    mPlacementWindow.Reset();
+  }
 }
 
 void DrawableView::AddRenderer()
index 57611cc..7a72c15 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/devel-api/actors/actor-devel.h>
 #include <dali/devel-api/adaptor-framework/native-image-source-queue.h>
 #include <dali/public-api/adaptor-framework/window.h>
+#include <dali/public-api/object/weak-handle.h>
 #include <dali/public-api/rendering/geometry.h>
 #include <dali/public-api/rendering/shader.h>
 #include <dali/public-api/signals/render-callback.h>
@@ -142,6 +143,7 @@ private:
   bool OnRenderCallback(const RenderCallbackInput& renderCallbackInput);
 
 private:
+  WeakHandle<Window>                   mPlacementWindow;
   Dali::Toolkit::GlView::RenderingMode mRenderingMode;
 
   bool mDepth;
index 61ab62e..11fe19d 100644 (file)
@@ -176,7 +176,7 @@ void GlView::OnInitialize()
   }
 
   //Adding VisibilityChange Signal.
-  Dali::DevelActor::VisibilityChangedSignal(self).Connect(this, &GlView::OnControlVisibilityChanged);
+  self.InheritedVisibilityChangedSignal().Connect(this, &GlView::OnControlInheritedVisibilityChanged);
 }
 
 void GlView::OnSizeSet(const Vector3& targetSize)
@@ -207,21 +207,18 @@ Shader GlView::CreateShader()
   return Shader::New(SHADER_GL_VIEW_VERT, fragmentShader, Shader::Hint::NONE, "GL_VIEW");
 }
 
-void GlView::OnControlVisibilityChanged(Dali::Actor actor, bool visible, Dali::DevelActor::VisibilityChange::Type type)
+void GlView::OnControlInheritedVisibilityChanged(Dali::Actor actor, bool visible)
 {
   Actor self = Self();
-  if(self.GetProperty<bool>(Actor::Property::CONNECTED_TO_SCENE))
+  if(mRenderThread)
   {
-    if(mRenderThread)
+    if(visible && DevelWindow::Get(self).IsVisible())
+    {
+      mRenderThread->Resume();
+    }
+    else
     {
-      if(visible && DevelWindow::Get(self).IsVisible())
-      {
-        mRenderThread->Resume();
-      }
-      else
-      {
-        mRenderThread->Pause();
-      }
+      mRenderThread->Pause();
     }
   }
 }
@@ -250,24 +247,19 @@ void GlView::OnSceneConnection(int depth)
 
   if(window)
   {
+    mPlacementWindow = window;
     DevelWindow::VisibilityChangedSignal(window).Connect(this, &GlView::OnWindowVisibilityChanged);
   }
-
-  if(mRenderThread)
-  {
-    if(self.GetProperty<bool>(Actor::Property::VISIBLE) && window.IsVisible())
-    {
-      mRenderThread->Resume();
-    }
-  }
 }
 
 void GlView::OnSceneDisconnection()
 {
   Control::OnSceneDisconnection();
-  if(mRenderThread)
+  Window window = mPlacementWindow.GetHandle();
+  if(window)
   {
-    mRenderThread->Pause();
+    DevelWindow::VisibilityChangedSignal(window).Disconnect(this, &GlView::OnWindowVisibilityChanged);
+    mPlacementWindow.Reset();
   }
 }
 
index e70cd99..0d80925 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/devel-api/actors/actor-devel.h>
 #include <dali/devel-api/adaptor-framework/native-image-source-queue.h>
 #include <dali/public-api/adaptor-framework/window.h>
+#include <dali/public-api/object/weak-handle.h>
 #include <dali/public-api/rendering/geometry.h>
 #include <dali/public-api/rendering/shader.h>
 
@@ -115,9 +116,9 @@ private:
   GlView& operator=(const GlView& GlView);
 
   /**
-   * Callback when the visibility of the GlView is changed
+   * Callback when the inherited visibility of the GlView is changed
    */
-  void OnControlVisibilityChanged(Dali::Actor actor, bool visible, Dali::DevelActor::VisibilityChange::Type type);
+  void OnControlInheritedVisibilityChanged(Dali::Actor actor, bool visible);
 
   /**
    * Callback when the visibility of the window is changed
@@ -147,6 +148,7 @@ private:
   Dali::NativeImageSourceQueue::ColorFormat GetColorFormat(Dali::Toolkit::GlView::ColorFormat format);
 
 private:
+  WeakHandle<Window>                   mPlacementWindow;
   std::unique_ptr<GlViewRenderThread>  mRenderThread;
   Dali::NativeImageSourceQueuePtr      mNativeImageQueue;
   Dali::Toolkit::GlView::RenderingMode mRenderingMode;
index 7f11261..a59ac36 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -25,6 +25,7 @@
 #include <dali/public-api/object/type-registry.h>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
@@ -45,13 +46,13 @@ namespace
 {
 const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
 
-constexpr float FULL_OPACITY = 1.0f;
-constexpr float LOW_OPACITY  = 0.2f;
+constexpr float FULL_OPACITY            = 1.0f;
+constexpr float LOW_OPACITY             = 0.2f;
 constexpr float TRANSITION_EFFECT_SPEED = 0.3f;
 
-constexpr int PLACEHOLDER_DEPTH_INDEX = -2;
-constexpr int PREVIOUS_VISUAL_DEPTH_INDEX  = -1;
-constexpr int CURRENT_VISUAL_DEPTH_INDEX = 0;
+constexpr int PLACEHOLDER_DEPTH_INDEX     = -2;
+constexpr int PREVIOUS_VISUAL_DEPTH_INDEX = -1;
+constexpr int CURRENT_VISUAL_DEPTH_INDEX  = 0;
 
 BaseHandle Create()
 {
@@ -173,7 +174,7 @@ void ImageView::SetImage(const Property::Map& map)
       visualImpl.SetCustomShader(mShaderMap);
     }
 
-    DevelControl::RegisterVisual(*this, Toolkit::ImageView::Property::IMAGE, visual);
+    DevelControl::RegisterVisual(*this, Toolkit::ImageView::Property::IMAGE, visual, DepthIndex::CONTENT);
   }
   else
   {
@@ -210,8 +211,6 @@ void ImageView::SetImage(const std::string& url, ImageDimensions size)
     mPreviousVisual = mVisual;
   }
 
-  
-
   // Don't bother comparing if we had a visual previously, just drop old visual and create new one
   mUrl       = url;
   mImageSize = size;
@@ -239,7 +238,7 @@ void ImageView::SetImage(const std::string& url, ImageDimensions size)
       visualImpl.SetCustomShader(mShaderMap);
     }
 
-    DevelControl::RegisterVisual(*this, Toolkit::ImageView::Property::IMAGE, visual);
+    DevelControl::RegisterVisual(*this, Toolkit::ImageView::Property::IMAGE, visual, DepthIndex::CONTENT);
   }
   else
   {
@@ -563,7 +562,7 @@ void ImageView::ApplyFittingMode(const Vector2& size)
   bool zeroPadding = (padding == Extents());
 
   Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(
-  Self().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
+    Self().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
   if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
   {
     std::swap(padding.start, padding.end);
@@ -707,7 +706,7 @@ void ImageView::TransitionImageWithEffect()
       Dali::KeyFrames fadeinKeyFrames = Dali::KeyFrames::New();
       fadeinKeyFrames.Add(0.0f, LOW_OPACITY);
       fadeinKeyFrames.Add(1.0f, destinationAlpha);
-      mTransitionAnimation.AnimateBetween(DevelControl::GetVisualProperty(handle, Toolkit::ImageView::Property::IMAGE, Toolkit::Visual::Property::OPACITY), fadeinKeyFrames,  AlphaFunction::EASE_IN_OUT);
+      mTransitionAnimation.AnimateBetween(DevelControl::GetVisualProperty(handle, Toolkit::ImageView::Property::IMAGE, Toolkit::Visual::Property::OPACITY), fadeinKeyFrames, AlphaFunction::EASE_IN_OUT);
       imageVisual.SetDepthIndex(imageVisual.GetDepthIndex() + CURRENT_VISUAL_DEPTH_INDEX);
     }
 
index 2432fb1..29302e1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -19,6 +19,7 @@
 #include <dali-toolkit/internal/controls/progress-bar/progress-bar-impl.h>
 
 // EXTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-base.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
@@ -77,7 +78,7 @@ struct ProgressDepthIndex
   // Enum to make sure the visual order
   enum
   {
-    TRACK_VISUAL,
+    TRACK_VISUAL = Toolkit::DepthIndex::CONTENT,
     SECONDARY_PROGRESS_VISUAL,
     PROGRESS_VISUAL,
     LABEL_VISUAL,
@@ -271,13 +272,11 @@ void ProgressBar::SetProgressValue(float value)
 
     Toolkit::ProgressBar self = Toolkit::ProgressBar::DownCast(Self());
     mValueChangedSignal.Emit(self, mProgressValue, mSecondaryProgressValue);
-    if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
+
+    auto accessible = GetAccessibleObject();
+    if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
     {
-      auto accessible = GetAccessibleObject();
-      if(DALI_LIKELY(accessible))
-      {
-        accessible->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
-      }
+      accessible->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
     }
     RelayoutRequest();
   }
index bf177fa..fe49f3c 100644 (file)
@@ -363,13 +363,11 @@ void ScrollBar::OnScrollPositionIntervalReached(PropertyNotification& source)
   if(scrollableHandle)
   {
     mScrollPositionIntervalReachedSignal.Emit(scrollableHandle.GetCurrentProperty<float>(mPropertyScrollPosition));
-    if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
+
+    auto accessible = GetAccessibleObject();
+    if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
     {
-      auto accessible = GetAccessibleObject();
-      if(DALI_LIKELY(accessible))
-      {
-        accessible->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
-      }
+      accessible->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
     }
   }
 }
index 5de904f..20b498c 100644 (file)
@@ -953,13 +953,11 @@ void Slider::SetValue(float value)
 {
   mValue = value;
   DisplayValue(mValue, true);
-  if(Self() == Dali::Accessibility::Accessible::GetCurrentlyHighlightedActor())
+
+  auto accessible = GetAccessibleObject();
+  if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
   {
-    auto accessible = GetAccessibleObject();
-    if(DALI_LIKELY(accessible))
-    {
-      accessible->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
-    }
+    accessible->Emit(Dali::Accessibility::ObjectPropertyChangeEvent::VALUE);
   }
 }
 
index a3dde6b..43a5884 100644 (file)
@@ -162,6 +162,8 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "characterSpacin
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "relativeLineSize",                     FLOAT,     RELATIVE_LINE_SIZE                  )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "verticalAlignment",                    STRING,    VERTICAL_ALIGNMENT                  )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "selectionPopupStyle",                  MAP,       SELECTION_POPUP_STYLE               )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "removeFrontInset",                     BOOLEAN,   REMOVE_FRONT_INSET                  )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextEditor, "removeBackInset",                      BOOLEAN,   REMOVE_BACK_INSET                   )
 
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "textChanged",           SIGNAL_TEXT_CHANGED           )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextEditor, "inputStyleChanged",     SIGNAL_INPUT_STYLE_CHANGED    )
@@ -962,7 +964,7 @@ void TextEditor::RequestTextRelayout()
 void TextEditor::TextInserted(unsigned int position, unsigned int length, const std::string& content)
 {
   auto accessible = GetAccessibleObject();
-  if(DALI_LIKELY(accessible))
+  if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
   {
     accessible->EmitTextInserted(position, length, content);
   }
@@ -971,7 +973,7 @@ void TextEditor::TextInserted(unsigned int position, unsigned int length, const
 void TextEditor::TextDeleted(unsigned int position, unsigned int length, const std::string& content)
 {
   auto accessible = GetAccessibleObject();
-  if(DALI_LIKELY(accessible))
+  if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
   {
     accessible->EmitTextDeleted(position, length, content);
   }
@@ -980,7 +982,7 @@ void TextEditor::TextDeleted(unsigned int position, unsigned int length, const s
 void TextEditor::CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition)
 {
   auto accessible = GetAccessibleObject();
-  if(DALI_LIKELY(accessible))
+  if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
   {
     accessible->EmitTextCursorMoved(newPosition);
   }
@@ -1356,6 +1358,26 @@ void TextEditor::OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type typ
   mController->ChangedLayoutDirection();
 }
 
+void TextEditor::SetRemoveFrontInset(bool remove)
+{
+  mController->SetRemoveFrontInset(remove);
+}
+
+bool TextEditor::IsRemoveFrontInset() const
+{
+  return mController->IsRemoveFrontInset();
+}
+
+void TextEditor::SetRemoveBackInset(bool remove)
+{
+  mController->SetRemoveBackInset(remove);
+}
+
+bool TextEditor::IsRemoveBackInset() const
+{
+  return mController->IsRemoveBackInset();
+}
+
 TextEditor::TextEditor(ControlBehaviour additionalBehaviour)
 : Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT | additionalBehaviour)),
   mAnimationPeriod(0.0f, 0.0f),
index 0eb9f6f..982a159 100644 (file)
@@ -440,6 +440,34 @@ public:
    */
   void AnchorClicked(const std::string& href) override;
 
+  /**
+   * @brief Set removing front inset to TextEditor.
+   *
+   * @param[in] remove Whether front inset of TextEditor has to be removed or not.
+   */
+  void SetRemoveFrontInset(const bool remove);
+
+  /**
+   * @brief Whether front inset of TextEditor is removed or not.
+   *
+   * @return True if the front inset of TextEditor is removed.
+   */
+  bool IsRemoveFrontInset() const;
+
+  /**
+   * @brief Set removing back inset to TextEditor.
+   *
+   * @param[in] remove Whether back inset of TextEditor has to be removed or not.
+   */
+  void SetRemoveBackInset(const bool remove);
+
+  /**
+   * @brief Whether back inset of TextEditor is removed or not.
+   *
+   * @return True if the back inset of TextEditor is removed.
+   */
+  bool IsRemoveBackInset() const;
+
 private: // Implementation
   /**
    * @copydoc Dali::Toolkit::Text::Controller::(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
index 067023a..984be66 100644 (file)
@@ -751,6 +751,18 @@ void TextEditor::PropertyHandler::SetProperty(Toolkit::TextEditor textEditor, Pr
       }
       break;
     }
+    case Toolkit::DevelTextEditor::Property::REMOVE_FRONT_INSET:
+    {
+      const bool remove = value.Get<bool>();
+      impl.mController->SetRemoveFrontInset(remove);
+      break;
+    }
+    case Toolkit::DevelTextEditor::Property::REMOVE_BACK_INSET:
+    {
+      const bool remove = value.Get<bool>();
+      impl.mController->SetRemoveBackInset(remove);
+      break;
+    }
   }
 }
 
@@ -1180,6 +1192,16 @@ Property::Value TextEditor::PropertyHandler::GetProperty(Toolkit::TextEditor tex
       value = map;
       break;
     }
+    case Toolkit::DevelTextEditor::Property::REMOVE_FRONT_INSET:
+    {
+      value = impl.mController->IsRemoveFrontInset();
+      break;
+    }
+    case Toolkit::DevelTextEditor::Property::REMOVE_BACK_INSET:
+    {
+      value = impl.mController->IsRemoveBackInset();
+      break;
+    }
   } //switch
   return value;
 }
index 4d68826..8336b14 100644 (file)
@@ -147,6 +147,8 @@ DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "strikethrough",
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "inputStrikethrough",               MAP,       INPUT_STRIKETHROUGH                 )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "characterSpacing",                 FLOAT,     CHARACTER_SPACING                   )
 DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "selectionPopupStyle",              MAP,       SELECTION_POPUP_STYLE               )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "removeFrontInset",                 BOOLEAN,   REMOVE_FRONT_INSET                  )
+DALI_DEVEL_PROPERTY_REGISTRATION(Toolkit,           TextField, "removeBackInset",                  BOOLEAN,   REMOVE_BACK_INSET                   )
 
 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "textChanged",           SIGNAL_TEXT_CHANGED           )
 DALI_SIGNAL_REGISTRATION(Toolkit, TextField, "maxLengthReached",      SIGNAL_MAX_LENGTH_REACHED     )
@@ -888,7 +890,7 @@ void TextField::SetEditable(bool editable)
 void TextField::TextInserted(unsigned int position, unsigned int length, const std::string& content)
 {
   auto accessible = GetAccessibleObject();
-  if(DALI_LIKELY(accessible))
+  if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
   {
     accessible->EmitTextInserted(position, length, content);
   }
@@ -897,7 +899,7 @@ void TextField::TextInserted(unsigned int position, unsigned int length, const s
 void TextField::TextDeleted(unsigned int position, unsigned int length, const std::string& content)
 {
   auto accessible = GetAccessibleObject();
-  if(DALI_LIKELY(accessible))
+  if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
   {
     accessible->EmitTextDeleted(position, length, content);
   }
@@ -906,7 +908,7 @@ void TextField::TextDeleted(unsigned int position, unsigned int length, const st
 void TextField::CursorPositionChanged(unsigned int oldPosition, unsigned int newPosition)
 {
   auto accessible = GetAccessibleObject();
-  if(DALI_LIKELY(accessible))
+  if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
   {
     accessible->EmitTextCursorMoved(newPosition);
   }
@@ -1204,6 +1206,26 @@ void TextField::SetSpannedText(const Text::Spanned& spannedText)
   mController->SetSpannedText(spannedText);
 }
 
+void TextField::SetRemoveFrontInset(bool remove)
+{
+  mController->SetRemoveFrontInset(remove);
+}
+
+bool TextField::IsRemoveFrontInset() const
+{
+  return mController->IsRemoveFrontInset();
+}
+
+void TextField::SetRemoveBackInset(bool remove)
+{
+  mController->SetRemoveBackInset(remove);
+}
+
+bool TextField::IsRemoveBackInset() const
+{
+  return mController->IsRemoveBackInset();
+}
+
 std::string TextField::TextFieldAccessible::GetName() const
 {
   if(IsHiddenInput())
index 215fd10..ed1a008 100644 (file)
@@ -412,6 +412,34 @@ public:
    */
   void SetSpannedText(const Text::Spanned& spannedText);
 
+  /**
+   * @brief Set removing front inset to TextField.
+   *
+   * @param[in] remove Whether front inset of TextField has to be removed or not.
+   */
+  void SetRemoveFrontInset(const bool remove);
+
+  /**
+   * @brief Whether front inset of TextField is removed or not.
+   *
+   * @return True if the front inset of TextField is removed.
+   */
+  bool IsRemoveFrontInset() const;
+
+  /**
+   * @brief Set removing back inset to TextField.
+   *
+   * @param[in] remove Whether back inset of TextField has to be removed or not.
+   */
+  void SetRemoveBackInset(const bool remove);
+
+  /**
+   * @brief Whether back inset of TextField is removed or not.
+   *
+   * @return True if the back inset of TextField is removed.
+   */
+  bool IsRemoveBackInset() const;
+
 private: // Implementation
   /**
    * @copydoc Dali::Toolkit::Text::Controller::(InputMethodContext& inputMethodContext, const InputMethodContext::EventData& inputMethodContextEvent)
index 45af9b7..5151ef1 100644 (file)
@@ -709,6 +709,18 @@ void TextField::PropertyHandler::SetProperty(Toolkit::TextField textField, Prope
       }
       break;
     }
+    case Toolkit::DevelTextField::Property::REMOVE_FRONT_INSET:
+    {
+      const bool remove = value.Get<bool>();
+      impl.mController->SetRemoveFrontInset(remove);
+      break;
+    }
+    case Toolkit::DevelTextField::Property::REMOVE_BACK_INSET:
+    {
+      const bool remove = value.Get<bool>();
+      impl.mController->SetRemoveBackInset(remove);
+      break;
+    }
   }
 }
 
@@ -1096,6 +1108,17 @@ Property::Value TextField::PropertyHandler::GetProperty(Toolkit::TextField textF
       value = map;
       break;
     }
+    case Toolkit::DevelTextField::Property::REMOVE_FRONT_INSET:
+    {
+      value = impl.mController->IsRemoveFrontInset();
+      break;
+    }
+    case Toolkit::DevelTextField::Property::REMOVE_BACK_INSET:
+    {
+      value = impl.mController->IsRemoveBackInset();
+      break;
+    }
+
   } //switch
   return value;
 }
index 5309e89..3063429 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -71,7 +71,7 @@ const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::DevelText::DEFAULT
  * The alignment depends on the alignment value of the text label (Use Text::VerticalAlignment enumerations).
  */
 const float VERTICAL_ALIGNMENT_TABLE[Text::VerticalAlignment::BOTTOM + 1] =
-{
+  {
     0.0f, // VerticalAlignment::TOP
     0.5f, // VerticalAlignment::CENTER
     1.0f  // VerticalAlignment::BOTTOM
@@ -89,7 +89,7 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT
 #endif
 
 const Scripting::StringEnum AUTO_SCROLL_STOP_MODE_TABLE[] =
-{
+  {
     {"IMMEDIATE", Toolkit::TextLabel::AutoScrollStopMode::IMMEDIATE},
     {"FINISH_LOOP", Toolkit::TextLabel::AutoScrollStopMode::FINISH_LOOP},
 };
@@ -944,7 +944,7 @@ void TextLabel::OnInitialize()
   propertyMap.Add(Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT);
 
   mVisual = Toolkit::VisualFactory::Get().CreateVisual(propertyMap);
-  DevelControl::RegisterVisual(*this, Toolkit::TextLabel::Property::TEXT, mVisual);
+  DevelControl::RegisterVisual(*this, Toolkit::TextLabel::Property::TEXT, mVisual, DepthIndex::CONTENT);
 
   TextVisual::SetAnimatableTextColorProperty(mVisual, Toolkit::TextLabel::Property::TEXT_COLOR);
 
@@ -1106,10 +1106,13 @@ void TextLabel::OnSceneDisconnection()
       mLastAutoScrollEnabled = false;
     }
 
-    const Toolkit::TextLabel::AutoScrollStopMode::Type stopMode = mTextScroller->GetStopMode();
-    mTextScroller->SetStopMode(Toolkit::TextLabel::AutoScrollStopMode::IMMEDIATE);
-    mTextScroller->StopScrolling();
-    mTextScroller->SetStopMode(stopMode);
+    if(mTextScroller->IsScrolling())
+    {
+      const Toolkit::TextLabel::AutoScrollStopMode::Type stopMode = mTextScroller->GetStopMode();
+      mTextScroller->SetStopMode(Toolkit::TextLabel::AutoScrollStopMode::IMMEDIATE);
+      mTextScroller->StopScrolling();
+      mTextScroller->SetStopMode(stopMode);
+    }
   }
   Control::OnSceneDisconnection();
 }
@@ -1118,6 +1121,12 @@ void TextLabel::OnRelayout(const Vector2& size, RelayoutContainer& container)
 {
   DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel::OnRelayout\n");
 
+  if(mTextScroller && mTextScroller->IsStop())
+  {
+    // When auto scroll is playing, it triggers a relayout only when an update is absolutely necessary.
+    return;
+  }
+
   Actor self = Self();
 
   Extents padding;
@@ -1286,12 +1295,8 @@ void TextLabel::ScrollingFinished()
 {
   // Pure Virtual from TextScroller Interface
   DALI_LOG_INFO(gLogFilter, Debug::General, "TextLabel::ScrollingFinished\n");
-
-  if(mController->IsAutoScrollEnabled() || !mController->IsMultiLineEnabled())
-  {
-    mController->SetAutoScrollEnabled(false);
-    RequestTextRelayout();
-  }
+  mController->SetAutoScrollEnabled(false);
+  RequestTextRelayout();
 }
 
 void TextLabel::OnLayoutDirectionChanged(Actor actor, LayoutDirection::Type type)
index c121cc7..9edac2d 100644 (file)
@@ -41,6 +41,7 @@
 #include <dali/public-api/object/type-registry.h>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/controls/web-view/web-back-forward-list.h>
 #include <dali-toolkit/devel-api/controls/web-view/web-settings.h>
@@ -867,7 +868,7 @@ void WebView::OnFrameRendered()
 
     if(mVisual)
     {
-      DevelControl::RegisterVisual(*this, Toolkit::WebView::Property::URL, mVisual);
+      DevelControl::RegisterVisual(*this, Toolkit::WebView::Property::URL, mVisual, DepthIndex::CONTENT);
       EnableBlendMode(!mVideoHoleEnabled);
     }
   }
index 8044923..99cc227 100644 (file)
@@ -768,13 +768,13 @@ bool Controller::EventHandler::DeleteEvent(Controller& controller, int keyCode)
   else if((controller.mImpl->mEventData->mPrimaryCursorPosition > 0) && (keyCode == Dali::DALI_KEY_BACKSPACE))
   {
     // Remove the character before the current cursor position
-    removed = TextUpdater::RemoveText(controller, -1, 1, UPDATE_INPUT_STYLE);
+    removed = TextUpdater::RemoveText(controller, -1, 1, UPDATE_INPUT_STYLE, false);
   }
   else if((controller.mImpl->mEventData->mPrimaryCursorPosition < controller.mImpl->mModel->mLogicalModel->mText.Count()) &&
           (keyCode == Dali::DevelKey::DALI_KEY_DELETE))
   {
     // Remove the character after the current cursor position
-    removed = TextUpdater::RemoveText(controller, 0, 1, UPDATE_INPUT_STYLE);
+    removed = TextUpdater::RemoveText(controller, 0, 1, UPDATE_INPUT_STYLE, false);
   }
 
   if(removed)
@@ -825,7 +825,8 @@ InputMethodContext::CallbackData Controller::EventHandler::OnInputMethodContextE
       const bool textDeleted = TextUpdater::RemoveText(controller,
                                                        inputMethodContextEvent.cursorOffset,
                                                        inputMethodContextEvent.numberOfChars,
-                                                       DONT_UPDATE_INPUT_STYLE);
+                                                       DONT_UPDATE_INPUT_STYLE,
+                                                       false);
 
       if(textDeleted)
       {
index f70d8af..10a76f1 100644 (file)
@@ -53,6 +53,7 @@ constexpr float MAX_FLOAT = std::numeric_limits<float>::max();
 
 const char* EMPTY_STRING         = "";
 const char* MIME_TYPE_TEXT_PLAIN = "text/plain;charset=utf-8";
+const char* MIME_TYPE_HTML       = "application/xhtml+xml";
 
 } // namespace
 
@@ -1161,6 +1162,12 @@ bool Controller::Impl::CopyStringToClipboard(const std::string& source)
   return false;
 }
 
+bool Controller::Impl::IsClipboardEmpty()
+{
+  bool result(Clipboard::IsAvailable() && EnsureClipboardCreated() && (mClipboard.HasType(MIME_TYPE_TEXT_PLAIN) || mClipboard.HasType(MIME_TYPE_HTML)));
+  return !result;
+}
+
 void Controller::Impl::SendSelectionToClipboard(bool deleteAfterSending)
 {
   std::string selectedText;
index 56ca85b..cc6a818 100644 (file)
@@ -616,12 +616,6 @@ struct Controller::Impl
     return mClipboard != nullptr ? true : false;
   }
 
-  bool IsClipboardEmpty()
-  {
-    bool result(Clipboard::IsAvailable() && EnsureClipboardCreated() && mClipboard.NumberOfItems());
-    return !result; // If NumberOfItems greater than 0, return false
-  }
-
   bool IsClipboardVisible()
   {
     bool result(Clipboard::IsAvailable() && EnsureClipboardCreated() && mClipboard.IsVisible());
@@ -629,6 +623,14 @@ struct Controller::Impl
   }
 
   /**
+   * @brief Whether the clipboard is empty or not.
+   * Checks the types that the text controller can paste and returns the result.
+   *
+   * @return Return whether or not the clipboard is empty.
+   */
+  bool IsClipboardEmpty();
+
+  /**
    * @copydoc Controller::GetLayoutDirection()
    */
   Dali::LayoutDirection::Type GetLayoutDirection(Dali::Actor& actor) const;
index 2ceee77..59da80a 100644 (file)
@@ -208,7 +208,8 @@ void Controller::TextUpdater::InsertText(Controller& controller, const std::stri
     removedPrevious = RemoveText(controller,
                                  -static_cast<int>(eventData->mPrimaryCursorPosition - eventData->mPreEditStartPosition),
                                  eventData->mPreEditLength,
-                                 DONT_UPDATE_INPUT_STYLE);
+                                 DONT_UPDATE_INPUT_STYLE,
+                                 true);
 
     eventData->mPrimaryCursorPosition = eventData->mPreEditStartPosition;
     eventData->mPreEditLength         = 0u;
@@ -495,7 +496,8 @@ bool Controller::TextUpdater::RemoveText(
   Controller&          controller,
   int                  cursorOffset,
   int                  numberOfCharacters,
-  UpdateInputStyleType type)
+  UpdateInputStyleType type,
+  bool                 isDeletingPreEdit)
 {
   bool removed   = false;
   bool removeAll = false;
@@ -608,7 +610,10 @@ bool Controller::TextUpdater::RemoveText(
       if(removeAll)
       {
         impl.ClearPreEditFlag();
-        textUpdateInfo.mNumberOfCharactersToAdd = 0;
+        if(!isDeletingPreEdit)
+        {
+          textUpdateInfo.mNumberOfCharactersToAdd = 0;
+        }
       }
 
       // Updates the text style runs by removing characters. Runs with no characters are removed.
index 47403f6..319697f 100644 (file)
@@ -63,9 +63,10 @@ struct Controller::TextUpdater
    * @param[in] cursorOffset Start position from the current cursor position to start deleting characters.
    * @param[in] numberOfCharacters The number of characters to delete from the cursorOffset.
    * @param[in] type Whether to update the input style.
+   * @param[in] isDeletingPreEdit Whether to remove pre-edit when inserting text.
    * @return True if the remove was successful.
    */
-  static bool RemoveText(Controller& controller, int cursorOffset, int numberOfCharacters, UpdateInputStyleType type);
+  static bool RemoveText(Controller& controller, int cursorOffset, int numberOfCharacters, UpdateInputStyleType type, bool isDeletingPreEdit);
 
   /**
    * @brief Checks if text is selected and if so removes it.
index d17e187..cb126dc 100644 (file)
@@ -48,6 +48,7 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT
 
 const char* EMPTY_STRING         = "";
 const char* MIME_TYPE_TEXT_PLAIN = "text/plain;charset=utf-8";
+const char* MIME_TYPE_HTML       = "application/xhtml+xml";
 
 template<typename Type>
 void EnsureCreated(Type*& object)
@@ -994,6 +995,17 @@ float Controller::GetDashedUnderlineGap() const
   return mImpl->mModel->mVisualModel->GetDashedUnderlineGap();
 }
 
+void Controller::SetOutlineOffset(const Vector2& outlineOffset)
+{
+  mImpl->mModel->mVisualModel->SetOutlineOffset(outlineOffset);
+  mImpl->RequestRelayout();
+}
+
+const Vector2& Controller::GetOutlineOffset() const
+{
+  return mImpl->mModel->mVisualModel->GetOutlineOffset();
+}
+
 void Controller::SetOutlineColor(const Vector4& color)
 {
   mImpl->mModel->mVisualModel->SetOutlineColor(color);
@@ -1016,6 +1028,20 @@ uint16_t Controller::GetOutlineWidth() const
   return mImpl->mModel->mVisualModel->GetOutlineWidth();
 }
 
+void Controller::SetOutlineBlurRadius(const float& outlineBlurRadius)
+{
+  if(fabsf(GetOutlineBlurRadius() - outlineBlurRadius) > Math::MACHINE_EPSILON_1)
+  {
+    mImpl->mModel->mVisualModel->SetOutlineBlurRadius(outlineBlurRadius);
+    mImpl->RequestRelayout();
+  }
+}
+
+const float& Controller::GetOutlineBlurRadius() const
+{
+  return mImpl->mModel->mVisualModel->GetOutlineBlurRadius();
+}
+
 void Controller::SetBackgroundColor(const Vector4& color)
 {
   mImpl->mModel->mVisualModel->SetBackgroundColor(color);
@@ -1728,11 +1754,27 @@ void Controller::PasteClipboardItemEvent(uint32_t id, const char* mimeType, cons
   mImpl->mClipboard.DataReceivedSignal().Disconnect(this, &Controller::PasteClipboardItemEvent);
 
   // If the id is 0u, it is an invalid response.
+  if(id == 0u)
+  {
+    return;
+  }
+
   // text-controller allows only plain text type.
-  if(id != 0u && !strncmp(mimeType, MIME_TYPE_TEXT_PLAIN, strlen(MIME_TYPE_TEXT_PLAIN)))
+  if(!strncmp(mimeType, MIME_TYPE_TEXT_PLAIN, strlen(MIME_TYPE_TEXT_PLAIN)))
   {
     EventHandler::PasteClipboardItemEvent(*this, data);
   }
+  else if(!strncmp(mimeType, MIME_TYPE_HTML, strlen(MIME_TYPE_HTML)))
+  {
+    // This does not mean that text controls can parse html.
+    // This is temporary code, as text controls do not support html type data.
+    // Simply remove the tags inside the angle brackets.
+    // Once multiple types and data can be stored in the clipboard, this code should be removed.
+    std::regex reg("<[^>]*>");
+    std::string result = regex_replace(data, reg, "");
+
+    EventHandler::PasteClipboardItemEvent(*this, result.c_str());
+  }
 }
 
 void Controller::PasteText()
@@ -1742,8 +1784,11 @@ void Controller::PasteText()
     // Connect the signal before calling GetData() of the clipboard.
     mImpl->mClipboard.DataReceivedSignal().Connect(this, &Controller::PasteClipboardItemEvent);
 
+    // If there is no plain text type data on the clipboard, request html type data.
+    std::string mimeType = mImpl->mClipboard.HasType(MIME_TYPE_TEXT_PLAIN) ? MIME_TYPE_TEXT_PLAIN : MIME_TYPE_HTML;
+
     // Request clipboard service to retrieve an item.
-    uint id = mImpl->mClipboard.GetData(MIME_TYPE_TEXT_PLAIN);
+    uint id = mImpl->mClipboard.GetData(mimeType);
     if(id == 0u)
     {
       // If the return id is 0u, the signal is not emitted, we must disconnect signal here.
index b8ff325..9acab81 100644 (file)
@@ -1280,6 +1280,20 @@ public: // Default style & Input style
   float GetDashedUnderlineGap() const;
 
   /**
+   * @brief Set the outline offset.
+   *
+   * @param[in] outlineOffset The outline offset.
+   */
+  void SetOutlineOffset(const Vector2& outlineOffset);
+
+  /**
+   * @brief Retrieve the outline offset.
+   *
+   * @return The outline offset.
+   */
+  const Vector2& GetOutlineOffset() const;
+
+  /**
    * @brief Set the outline color.
    *
    * @param[in] color color of outline.
@@ -1308,6 +1322,20 @@ public: // Default style & Input style
   uint16_t GetOutlineWidth() const;
 
   /**
+   * @brief Set the outline blur radius.
+   *
+   * @param[in] outlineBlurRadius The outline blur radius, 0,0 indicates no blur.
+   */
+  void SetOutlineBlurRadius(const float& outlineBlurRadius);
+
+  /**
+   * @brief Retrieve the outline blur radius.
+   *
+   * @return The outline blur radius.
+   */
+  const float& GetOutlineBlurRadius() const;
+
+  /**
    * @brief Set the background color.
    *
    * @param[in] color color of background.
index 5ccaad0..787bcfa 100644 (file)
@@ -450,6 +450,7 @@ struct AtlasRenderer::Impl
     const bool       underlineEnabled = view.IsUnderlineEnabled();
     const uint16_t   outlineWidth     = view.GetOutlineWidth();
     const Vector4&   outlineColor(view.GetOutlineColor());
+    const Vector2&   outlineOffset(view.GetOutlineOffset());
     const bool       isOutline            = 0u != outlineWidth;
     const GlyphInfo* hyphens              = view.GetHyphens();
     const Length*    hyphenIndices        = view.GetHyphenIndices();
@@ -656,7 +657,7 @@ struct AtlasRenderer::Impl
 
         if(0u != slot.mImageId) // invalid slot id, glyph has failed to be added to atlas
         {
-          Vector2 positionPlusOutlineOffset = position;
+          Vector2 positionPlusOutlineOffset = position + outlineOffset;
           if(isOutline)
           {
             // Add an offset to the text.
index 1c31199..7d095b4 100644 (file)
@@ -996,6 +996,13 @@ PixelData Typesetter::Render(const Vector2& size, Toolkit::DevelText::TextDirect
       // Create the image buffer for outline
       Devel::PixelBuffer outlineImageBuffer = CreateImageBuffer(bufferWidth, bufferHeight, Typesetter::STYLE_OUTLINE, ignoreHorizontalAlignment, pixelFormat, penX, penY, startIndexOfGlyphs, endIndexOfGlyphs);
 
+      const float& blurRadius = mModel->GetOutlineBlurRadius();
+
+      if(blurRadius > Math::MACHINE_EPSILON_1)
+      {
+        outlineImageBuffer.ApplyGaussianBlur(blurRadius);
+      }
+
       // Combine the two buffers
       CombineImageBuffer(imageBuffer, outlineImageBuffer, bufferWidth, bufferHeight, true);
     }
@@ -1149,11 +1156,15 @@ Devel::PixelBuffer Typesetter::CreateImageBuffer(const uint32_t bufferWidth, con
 
     if(style == Typesetter::STYLE_OUTLINE)
     {
+      const Vector2& outlineOffset = mModel->GetOutlineOffset();
+
       glyphData.horizontalOffset -= outlineWidth;
+      glyphData.horizontalOffset += outlineOffset.x;
       if(lineIndex == 0u)
       {
         // Only need to add the vertical outline offset for the first line
         glyphData.verticalOffset -= outlineWidth;
+        glyphData.verticalOffset += outlineOffset.y;
       }
     }
     else if(style == Typesetter::STYLE_SHADOW)
index 3799fc9..3404be2 100644 (file)
@@ -285,6 +285,11 @@ void ViewModel::GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRun
   mModel->GetUnderlineRuns(underlineRuns, index, numberOfRuns);
 }
 
+const Vector2& ViewModel::GetOutlineOffset() const
+{
+  return mModel->GetOutlineOffset();
+}
+
 const Vector4& ViewModel::GetOutlineColor() const
 {
   return mModel->GetOutlineColor();
@@ -295,6 +300,11 @@ uint16_t ViewModel::GetOutlineWidth() const
   return mModel->GetOutlineWidth();
 }
 
+const float& ViewModel::GetOutlineBlurRadius() const
+{
+  return mModel->GetOutlineBlurRadius();
+}
+
 const Vector4& ViewModel::GetBackgroundColor() const
 {
   return mModel->GetBackgroundColor();
index 4de580d..9adcb65 100644 (file)
@@ -247,6 +247,11 @@ public:
   void GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const override;
 
   /**
+   * @copydoc ModelInterface::GetOutlineOffset()
+   */
+  const Vector2& GetOutlineOffset() const override;
+
+  /**
    * @copydoc ModelInterface::GetOutlineColor()
    */
   const Vector4& GetOutlineColor() const override;
@@ -257,6 +262,11 @@ public:
   uint16_t GetOutlineWidth() const override;
 
   /**
+   * @copydoc ModelInterface::GetOutlineBlurRadius()
+   */
+  const float& GetOutlineBlurRadius() const override;
+
+  /**
    * @copydoc ModelInterface::GetBackgroundColor()
    */
   const Vector4& GetBackgroundColor() const override;
index f89846e..ffbef1e 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_TEXT_SPANS_CONTAINER_IMPL_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -121,16 +121,6 @@ private:
 
 } // namespace Toolkit
 
-// Allow SpanRangesContainer to be treated as a POD type
-template<>
-struct TypeTraits<Dali::Toolkit::Text::Internal::SpanRangesContainer> : public Dali::BasicTypes<Dali::Toolkit::Text::Internal::SpanRangesContainer>
-{
-  enum
-  {
-    IS_TRIVIAL_TYPE = true
-  };
-};
-
 } // namespace Dali
 
 #endif // DALI_TOOLKIT_INTERNAL_TEXT_SPANS_CONTAINER_IMPL_H
index 0b56043..40b388a 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_TEXT_SPANNABLE_IMPL_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -102,16 +102,6 @@ inline const Internal::Spannable& GetImplementation(const Dali::Toolkit::Text::S
 
 } // namespace Toolkit
 
-// Allow Spannable to be treated as a POD type
-template<>
-struct TypeTraits<Dali::Toolkit::Text::Internal::Spannable> : public Dali::BasicTypes<Dali::Toolkit::Text::Internal::Spannable>
-{
-  enum
-  {
-    IS_TRIVIAL_TYPE = true
-  };
-};
-
 } // namespace Dali
 
 #endif // DALI_TOOLKIT_INTERNAL_TEXT_SPANNABLE_IMPL_H
index 5ecb823..5dccab4 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_TEXT_SPANNABLE_STRING_IMPL_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -144,16 +144,6 @@ inline const Internal::SpannableString& GetImplementation(const Dali::Toolkit::T
 
 } // namespace Toolkit
 
-// Allow SpannableString to be treated as a POD type
-template<>
-struct TypeTraits<Dali::Toolkit::Text::Internal::SpannableString> : public Dali::BasicTypes<Dali::Toolkit::Text::Internal::SpannableString>
-{
-  enum
-  {
-    IS_TRIVIAL_TYPE = true
-  };
-};
-
 } // namespace Dali
 
 #endif // DALI_TOOLKIT_INTERNAL_TEXT_SPANNABLE_STRING_IMPL_H
index 4e5a8c7..e6c18cd 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_TEXT_SPANNED_IMPL_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -103,16 +103,6 @@ inline const Internal::Spanned& GetImplementation(const Dali::Toolkit::Text::Spa
 
 } // namespace Toolkit
 
-// Allow Spanned to be treated as a POD type
-template<>
-struct TypeTraits<Dali::Toolkit::Text::Internal::Spanned> : public Dali::BasicTypes<Dali::Toolkit::Text::Internal::Spanned>
-{
-  enum
-  {
-    IS_TRIVIAL_TYPE = true
-  };
-};
-
 } // namespace Dali
 
 #endif // DALI_TOOLKIT_INTERNAL_TEXT_SPANNED_IMPL_H
index 5f01524..cd2f850 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_TEXT_BASE_SPAN_IMPL_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -116,16 +116,6 @@ inline const Internal::BaseSpan& GetImplementation(const Dali::Toolkit::Text::Ba
 
 } // namespace Toolkit
 
-// Allow BaseSpan to be treated as a POD type
-template<>
-struct TypeTraits<Dali::Toolkit::Text::Internal::BaseSpan> : public Dali::BasicTypes<Dali::Toolkit::Text::Internal::BaseSpan>
-{
-  enum
-  {
-    IS_TRIVIAL_TYPE = true
-  };
-};
-
 } // namespace Dali
 
 #endif // DALI_TOOLKIT_INTERNAL_TEXT_BASE_SPAN_IMPL_H
index d04883b..27312b7 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_TEXT_CHARACTER_SEQUENCE_IMPL_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -109,16 +109,6 @@ inline const Internal::CharacterSequence& GetImplementation(const Dali::Toolkit:
 
 } // namespace Toolkit
 
-// Allow AbstractStyleSpan to be treated as a POD type
-template<>
-struct TypeTraits<Dali::Toolkit::Text::Internal::CharacterSequence> : public Dali::BasicTypes<Dali::Toolkit::Text::Internal::CharacterSequence>
-{
-  enum
-  {
-    IS_TRIVIAL_TYPE = true
-  };
-};
-
 } // namespace Dali
 
 #endif // DALI_TOOLKIT_INTERNAL_TEXT_CHARACTER_SEQUENCE_IMPL_H
index 8b0f0d2..b4e6c1a 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_TEXT_RANGE_IMPL_H
 
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -126,16 +126,6 @@ inline const Internal::Range& GetImplementation(const Dali::Toolkit::Text::Range
 
 } // namespace Toolkit
 
-// Allow Range to be treated as a POD type
-template<>
-struct TypeTraits<Dali::Toolkit::Text::Internal::Range> : public Dali::BasicTypes<Dali::Toolkit::Text::Internal::Range>
-{
-  enum
-  {
-    IS_TRIVIAL_TYPE = true
-  };
-};
-
 } // namespace Dali
 
 #endif // DALI_TOOLKIT_INTERNAL_TEXT_RANGE_IMPL_H
index 2bf1398..be4cbfa 100644 (file)
@@ -229,7 +229,11 @@ bool ParseOutlineProperties(const Property::Map& underlinePropertiesMap,
                             bool&                colorDefined,
                             Vector4&             color,
                             bool&                widthDefined,
-                            uint16_t&            width)
+                            uint16_t&            width,
+                            bool&                offsetDefined,
+                            Vector2&             offset,
+                            bool&                blurRadiusDefined,
+                            float&               blurRadius)
 {
   const unsigned int numberOfItems = underlinePropertiesMap.Count();
 
@@ -250,6 +254,36 @@ bool ParseOutlineProperties(const Property::Map& underlinePropertiesMap,
       widthDefined = true;
       width        = static_cast<uint16_t>(valueGet.second.Get<float>());
     }
+    else if((DevelText::Outline::Property::OFFSET == valueGet.first.indexKey) || (OFFSET_KEY == valueGet.first.stringKey))
+    {
+      /// Offset key.
+      offsetDefined = true;
+
+      if(valueGet.second.GetType() == Dali::Property::STRING)
+      {
+        const std::string offsetStr = valueGet.second.Get<std::string>();
+        StringToVector2(offsetStr.c_str(), offsetStr.size(), offset);
+      }
+      else
+      {
+        offset = valueGet.second.Get<Vector2>();
+      }
+    }
+    else if((DevelText::Outline::Property::BLUR_RADIUS == valueGet.first.indexKey) || (BLUR_RADIUS_KEY == valueGet.first.stringKey))
+    {
+      /// Blur radius key.
+      blurRadiusDefined = true;
+
+      if(valueGet.second.GetType() == Dali::Property::STRING)
+      {
+        const std::string blurRadiusStr = valueGet.second.Get<std::string>();
+        blurRadius                      = StringToFloat(blurRadiusStr.c_str());
+      }
+      else
+      {
+        blurRadius = valueGet.second.Get<float>();
+      }
+    }
   }
 
   return 0u == numberOfItems;
@@ -752,10 +786,14 @@ bool SetOutlineProperties(ControllerPtr controller, const Property::Value& value
       {
         const Property::Map& propertiesMap = value.Get<Property::Map>();
 
-        bool     colorDefined = false;
+        bool     colorDefined  = false;
         Vector4  color;
-        bool     widthDefined = false;
-        uint16_t width        = 0u;
+        bool     widthDefined  = false;
+        uint16_t width         = 0u;
+        bool     offsetDefined = false;
+        Vector2  offset;
+        bool     blurRadiusDefined = false;
+        float    blurRadius;
 
         bool empty = true;
 
@@ -776,7 +814,11 @@ bool SetOutlineProperties(ControllerPtr controller, const Property::Value& value
                                          colorDefined,
                                          color,
                                          widthDefined,
-                                         width);
+                                         width,
+                                         offsetDefined,
+                                         offset,
+                                         blurRadiusDefined,
+                                         blurRadius);
 
           controller->OutlineSetByString(false);
         }
@@ -795,6 +837,18 @@ bool SetOutlineProperties(ControllerPtr controller, const Property::Value& value
             controller->SetOutlineWidth(width);
             update = true;
           }
+
+          if(offsetDefined && (controller->GetOutlineOffset() != offset))
+          {
+            controller->SetOutlineOffset(offset);
+            update = true;
+          }
+
+          if(blurRadiusDefined && (!Dali::Equals(controller->GetOutlineBlurRadius(), blurRadius)))
+          {
+            controller->SetOutlineBlurRadius(blurRadius);
+            update = true;
+          }
         }
         else
         {
@@ -835,12 +889,16 @@ void GetOutlineProperties(ControllerPtr controller, Property::Value& value, Effe
         }
         else
         {
-          const Vector4& color = controller->GetOutlineColor();
-          const uint16_t width = controller->GetOutlineWidth();
+          const Vector4& color      = controller->GetOutlineColor();
+          const uint16_t width      = controller->GetOutlineWidth();
+          const Vector2& offset     = controller->GetOutlineOffset();
+          const float&   blurRadius = controller->GetOutlineBlurRadius();
 
           Property::Map map;
           map.Insert(COLOR_KEY, color);
           map.Insert(WIDTH_KEY, static_cast<int>(width));
+          map.Insert(OFFSET_KEY, offset);
+          map.Insert(BLUR_RADIUS_KEY, blurRadius);
 
           value = map;
 
index bd34ff8..212ec0d 100644 (file)
@@ -322,6 +322,13 @@ public:
   virtual void GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const = 0;
 
   /**
+   * @brief Retrieves the outline offset.
+   *
+   * @return The outline offset.
+   */
+  virtual const Vector2& GetOutlineOffset() const = 0;
+
+  /**
    * @brief Retrieve the outline color.
    *
    * @return The outline color.
@@ -336,6 +343,13 @@ public:
   virtual uint16_t GetOutlineWidth() const = 0;
 
   /**
+   * @brief Retrieve the outline blur radius.
+   *
+   * @return The outline blur radius.
+   */
+  virtual const float& GetOutlineBlurRadius() const = 0;
+
+  /**
    * @brief Retrieves the background color.
    *
    * @return The background color.
index ae0dd7c..01c6f60 100644 (file)
@@ -227,6 +227,11 @@ void Model::GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRunInde
   mVisualModel->GetUnderlineRuns(underlineRuns, index, numberOfRuns);
 }
 
+const Vector2& Model::GetOutlineOffset() const
+{
+  return mVisualModel->GetOutlineOffset();
+}
+
 const Vector4& Model::GetOutlineColor() const
 {
   return mVisualModel->GetOutlineColor();
@@ -237,6 +242,11 @@ uint16_t Model::GetOutlineWidth() const
   return mVisualModel->GetOutlineWidth();
 }
 
+const float& Model::GetOutlineBlurRadius() const
+{
+  return mVisualModel->mOutlineBlurRadius;
+}
+
 const Vector4& Model::GetBackgroundColor() const
 {
   return mVisualModel->GetBackgroundColor();
index e738784..eb0d8a6 100644 (file)
@@ -245,6 +245,11 @@ public:
   void GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns, UnderlineRunIndex index, Length numberOfRuns) const override;
 
   /**
+   * @copydoc ModelInterface::GetOutlineOffset()
+   */
+  const Vector2& GetOutlineOffset() const override;
+
+  /**
    * @copydoc ModelInterface::GetOutlineColor()
    */
   const Vector4& GetOutlineColor() const override;
@@ -255,6 +260,11 @@ public:
   uint16_t GetOutlineWidth() const override;
 
   /**
+   * @copydoc ModelInterface::GetOutlineBlurRadius()
+   */
+  const float& GetOutlineBlurRadius() const override;
+
+  /**
    * @copydoc ModelInterface::GetBackgroundColor()
    */
   const Vector4& GetBackgroundColor() const override;
index 59bb09f..08e08c8 100644 (file)
@@ -144,18 +144,19 @@ void TextScroller::SetStopMode(TextLabel::AutoScrollStopMode::Type stopMode)
 
 void TextScroller::StopScrolling()
 {
-  if(mScrollAnimation && mScrollAnimation.GetState() == Animation::PLAYING)
+  if(IsScrolling())
   {
     switch(mStopMode)
     {
       case TextLabel::AutoScrollStopMode::IMMEDIATE:
       {
+        mIsStop = true;
         mScrollAnimation.Stop();
-        mScrollerInterface.ScrollingFinished();
         break;
       }
       case TextLabel::AutoScrollStopMode::FINISH_LOOP:
       {
+        mIsStop = true;
         mScrollAnimation.SetLoopCount(1); // As animation already playing this allows the current animation to finish instead of trying to stop mid-way
         break;
       }
@@ -171,6 +172,16 @@ void TextScroller::StopScrolling()
   }
 }
 
+bool TextScroller::IsStop()
+{
+  return mIsStop;
+}
+
+bool TextScroller::IsScrolling()
+{
+  return (mScrollAnimation && mScrollAnimation.GetState() == Animation::PLAYING);
+}
+
 TextLabel::AutoScrollStopMode::Type TextScroller::GetStopMode() const
 {
   return mStopMode;
@@ -183,7 +194,8 @@ TextScroller::TextScroller(ScrollerInterface& scrollerInterface)
   mLoopCount(1),
   mLoopDelay(0.0f),
   mWrapGap(0.0f),
-  mStopMode(TextLabel::AutoScrollStopMode::FINISH_LOOP)
+  mStopMode(TextLabel::AutoScrollStopMode::FINISH_LOOP),
+  mIsStop(false)
 {
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextScroller Default Constructor\n");
 }
@@ -195,7 +207,6 @@ TextScroller::~TextScroller()
 void TextScroller::SetParameters(Actor scrollingTextActor, Renderer renderer, TextureSet textureSet, const Size& controlSize, const Size& textureSize, const float wrapGap, CharacterDirection direction, HorizontalAlignment::Type horizontalAlignment, VerticalAlignment::Type verticalAlignment)
 {
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextScroller::SetParameters controlSize[%f,%f] textureSize[%f,%f] direction[%d]\n", controlSize.x, controlSize.y, textureSize.x, textureSize.y, direction);
-
   mRenderer = renderer;
 
   float animationProgress = 0.0f;
@@ -209,7 +220,7 @@ void TextScroller::SetParameters(Actor scrollingTextActor, Renderer renderer, Te
       if(mLoopCount > 0) // If not a ininity loop, then calculate remained loop
       {
         remainedLoop = mLoopCount - (mScrollAnimation.GetCurrentLoop());
-        remainedLoop = (remainedLoop <= 0 ? 1 : remainedLoop);
+        remainedLoop = mIsStop ? 1 : (remainedLoop <= 0 ? 1 : remainedLoop);
       }
     }
     mScrollAnimation.Clear();
@@ -269,6 +280,7 @@ void TextScroller::SetParameters(Actor scrollingTextActor, Renderer renderer, Te
 void TextScroller::AutoScrollAnimationFinished(Dali::Animation& animation)
 {
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextScroller::AutoScrollAnimationFinished\n");
+  mIsStop = false;
   mScrollerInterface.ScrollingFinished();
 
   // Revert to the original shader and texture after scrolling
@@ -282,7 +294,6 @@ void TextScroller::AutoScrollAnimationFinished(Dali::Animation& animation)
 void TextScroller::StartScrolling(Actor scrollingTextActor, float scrollAmount, float scrollDuration, int loopCount)
 {
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "TextScroller::StartScrolling scrollAmount[%f] scrollDuration[%f], loop[%d] speed[%d]\n", scrollAmount, scrollDuration, loopCount, mScrollSpeed);
-
   Shader shader    = mRenderer.GetShader();
   mScrollAnimation = Animation::New(scrollDuration);
   mScrollAnimation.AnimateTo(Property(shader, mScrollDeltaIndex), scrollAmount, TimePeriod(mLoopDelay, scrollDuration));
@@ -290,6 +301,8 @@ void TextScroller::StartScrolling(Actor scrollingTextActor, float scrollAmount,
   mScrollAnimation.SetLoopCount(loopCount);
   mScrollAnimation.FinishedSignal().Connect(this, &TextScroller::AutoScrollAnimationFinished);
   mScrollAnimation.Play();
+
+  mIsStop = false;
 }
 
 } // namespace Text
index b93c2d2..99a4936 100644 (file)
@@ -129,6 +129,16 @@ public:
   void StopScrolling();
 
   /**
+   * @brief Whether the stop scrolling has been triggered or not.
+   */
+  bool IsStop();
+
+  /**
+   * @brief Whether the scroll animation is playing or not.
+   */
+  bool IsScrolling();
+
+  /**
    * @brief Get the mode of scrolling stop
    * @return stopMode type when text scrolling is stoped.
    */
@@ -179,6 +189,7 @@ private:
   float                               mLoopDelay;   ///< Time delay of loop start
   float                               mWrapGap;     ///< Gap before text wraps around when scrolling
   TextLabel::AutoScrollStopMode::Type mStopMode;    ///< Stop mode of scrolling text, when loop count is 0.
+  bool                                mIsStop : 1;  ///< Whether the stop scrolling has been triggered or not.
 
 }; // TextScroller class
 
index 24fcfff..10ff4ff 100644 (file)
@@ -248,6 +248,13 @@ public:
                                 Length              numberOfRuns) const = 0;
 
   /**
+   * @brief Retrieves the outline offset.
+   *
+   * @return The outline offset.
+   */
+  virtual const Vector2& GetOutlineOffset() const = 0;
+
+  /**
    * @brief Retrieve the outline color.
    *
    * @return The outline color.
index d71000b..66d0af9 100644 (file)
@@ -845,6 +845,18 @@ void View::GetUnderlineRuns(UnderlinedGlyphRun* underlineRuns,
   }
 }
 
+const Vector2& View::GetOutlineOffset() const
+{
+// TODO : We should support outline offset to editable text.
+/*
+  if(mImpl->mVisualModel)
+  {
+    return mImpl->mVisualModel->GetOutlineOffset();
+  }
+*/
+  return Vector2::ZERO;
+}
+
 const Vector4& View::GetOutlineColor() const
 {
   if(mImpl->mVisualModel)
index 5bf55e1..9b12d03 100644 (file)
@@ -187,6 +187,11 @@ public:
                                 Length              numberOfRuns) const;
 
   /**
+   * @copydoc Dali::Toolkit::Text::ViewInterface::GetOutlineOffset()
+   */
+  const Vector2& GetOutlineOffset() const override;
+
+  /**
    * @copydoc Dali::Toolkit::Text::ViewInterface::GetOutlineColor()
    */
   const Vector4& GetOutlineColor() const override;
index c79e5a9..fd6b683 100644 (file)
@@ -381,11 +381,21 @@ void VisualModel::SetUnderlineColor(const Vector4& color)
   mUnderlineColorSet = true;
 }
 
+void VisualModel::SetOutlineOffset(const Vector2& outlineOffset)
+{
+  mOutlineOffset = outlineOffset;
+}
+
 void VisualModel::SetOutlineColor(const Vector4& color)
 {
   mOutlineColor = color;
 }
 
+void VisualModel::SetOutlineBlurRadius(const float& outlineBlurRadius)
+{
+  mOutlineBlurRadius = outlineBlurRadius;
+}
+
 void VisualModel::SetUnderlineEnabled(bool enabled)
 {
   mUnderlineEnabled = enabled;
@@ -506,11 +516,21 @@ const Vector4& VisualModel::GetUnderlineColor() const
   return mUnderlineColor;
 }
 
+const Vector2& VisualModel::GetOutlineOffset() const
+{
+  return mOutlineOffset;
+}
+
 const Vector4& VisualModel::GetOutlineColor() const
 {
   return mOutlineColor;
 }
 
+const float& VisualModel::GetOutlineBlurRadius() const
+{
+  return mOutlineBlurRadius;
+}
+
 bool VisualModel::IsUnderlineEnabled() const
 {
   return mUnderlineEnabled;
@@ -665,12 +685,14 @@ VisualModel::VisualModel()
   mStrikethroughColor(Color::BLACK),
   mControlSize(),
   mShadowOffset(),
+  mOutlineOffset(),
   mUnderlineHeight(0.0f),
   mStrikethroughHeight(0.0f),
   mUnderlineType(Text::Underline::SOLID),
   mDashedUnderlineWidth(2.0f),
   mDashedUnderlineGap(1.0f),
   mShadowBlurRadius(0.0f),
+  mOutlineBlurRadius(0.0f),
   mOutlineWidth(0u),
   mNaturalSize(),
   mLayoutSize(),
index 9dae2cf..edebaf6 100644 (file)
@@ -384,6 +384,13 @@ public:
   Length GetNumberOfUnderlineRuns() const;
 
   /**
+   * @brief Sets the text's outline offset.
+   *
+   * @param[in] outlineOffset The outline offset.
+   */
+  void SetOutlineOffset(const Vector2& outlineOffset);
+
+  /**
    * @brief Set the outline color.
    *
    * @param[in] color color of outline.
@@ -391,6 +398,13 @@ public:
   void SetOutlineColor(const Vector4& color);
 
   /**
+   * @brief Retrieves the text's outline offset.
+   *
+   * @return The text's outline offset.
+   */
+  const Vector2& GetOutlineOffset() const;
+
+  /**
    * @brief Retrieve the outline color.
    *
    * @return The outline color.
@@ -412,6 +426,20 @@ public:
   uint16_t GetOutlineWidth() const;
 
   /**
+   * @brief Set the outline blur radius.
+   *
+   * @param[in] outlineBlurRadius The outline blur radius, 0,0 indicates no blur.
+   */
+  void SetOutlineBlurRadius(const float& outlineBlurRadius);
+
+  /**
+   * @brief Retrieve the outline blur radius.
+   *
+   * @return The outline blur radius.
+   */
+  const float& GetOutlineBlurRadius() const;
+
+  /**
    * @brief Sets the text's background color.
    *
    * @param[in] color The text's background color.
@@ -673,12 +701,14 @@ public:
   Vector4                          mStrikethroughColor;     ///< Color of text background
   Size                             mControlSize;            ///< The size of the UI control.
   Vector2                          mShadowOffset;           ///< Offset for drop shadow, 0 indicates no shadow
+  Vector2                          mOutlineOffset;          ///< Offset for outline
   float                            mUnderlineHeight;        ///< Fixed height for underline to override font metrics.
   float                            mStrikethroughHeight;    ///< Fixed height for strikethrough to override font metrics.
   Text::Underline::Type            mUnderlineType;          ///< The type of the underline.
   float                            mDashedUnderlineWidth;   ///< The width of the dashes of the dashed underline.
   float                            mDashedUnderlineGap;     ///< The gap between the dashes of the dashed underline.
   float                            mShadowBlurRadius;       ///< Blur radius of shadow, 0 indicates no blur.
+  float                            mOutlineBlurRadius;      ///< Blur radius of outline, 0 indicates no blur.
   uint16_t                         mOutlineWidth;           ///< Width of outline.
   Vector<StrikethroughGlyphRun>    mStrikethroughRuns;      ///< Runs of glyphs that have strikethrough.
   Vector<CharacterSpacingGlyphRun> mCharacterSpacingRuns;   ///< Runs of glyphs that have character-spacing.
index ef2e759..f3b5028 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -102,7 +102,6 @@ TextureManager::MaskingData::MaskingData()
 TextureManager::TextureManager(bool loadYuvPlanes)
 : mTextureCacheManager(),
   mAsyncLoader(std::unique_ptr<TextureAsyncLoadingHelper>(new TextureAsyncLoadingHelper(*this))),
-  mLifecycleObservers(),
   mLoadQueue(),
   mLoadingQueueTextureId(INVALID_TEXTURE_ID),
   mRemoveQueue(),
@@ -120,11 +119,6 @@ TextureManager::~TextureManager()
     Adaptor::Get().UnregisterProcessor(*this, true);
     mRemoveProcessorRegistered = false;
   }
-
-  for(auto iter = mLifecycleObservers.Begin(), endIter = mLifecycleObservers.End(); iter != endIter; ++iter)
-  {
-    (*iter)->TextureManagerDestroyed();
-  }
 }
 
 TextureSet TextureManager::LoadAnimatedImageTexture(
@@ -872,29 +866,6 @@ void TextureManager::LoadImageSynchronously(
   }
 }
 
-void TextureManager::AddObserver(TextureManager::LifecycleObserver& observer)
-{
-  // make sure an observer doesn't observe the same object twice
-  // otherwise it will get multiple calls to ObjectDestroyed()
-  DALI_ASSERT_DEBUG(mLifecycleObservers.End() == std::find(mLifecycleObservers.Begin(), mLifecycleObservers.End(), &observer));
-  mLifecycleObservers.PushBack(&observer);
-}
-
-void TextureManager::RemoveObserver(TextureManager::LifecycleObserver& observer)
-{
-  // Find the observer...
-  auto endIter = mLifecycleObservers.End();
-  for(auto iter = mLifecycleObservers.Begin(); iter != endIter; ++iter)
-  {
-    if((*iter) == &observer)
-    {
-      mLifecycleObservers.Erase(iter);
-      break;
-    }
-  }
-  DALI_ASSERT_DEBUG(endIter != mLifecycleObservers.End());
-}
-
 void TextureManager::LoadOrQueueTexture(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer)
 {
   switch(textureInfo.loadState)
index fdae67a..f460893 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_TEXTURE_MANAGER_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.
@@ -85,17 +85,6 @@ public:
   using MaskingDataPointer = std::unique_ptr<MaskingData>;
 
   /**
-   * Class to provide lifecycle event on destruction of texture manager.
-   */
-  struct LifecycleObserver
-  {
-    /**
-     * Called shortly before the texture manager is destroyed.
-     */
-    virtual void TextureManagerDestroyed() = 0;
-  };
-
-  /**
    * Constructor.
    *
    * @param[in] loadYuvPlanes Whether we allow to load YuvPlanes or not. Default is false.
@@ -228,19 +217,6 @@ public:
     TextureManager::MultiplyOnLoad&    preMultiplyOnLoad);
 
   /**
-   * Add an observer to the object.
-   * @param[in] observer The observer to add.
-   */
-  void AddObserver(TextureManager::LifecycleObserver& observer);
-
-  /**
-   * Remove an observer from the object
-   * @pre The observer has already been added.
-   * @param[in] observer The observer to remove.
-   */
-  void RemoveObserver(TextureManager::LifecycleObserver& observer);
-
-  /**
    * @brief Returns the geometry associated with texture.
    * @param[in] textureId Id of the texture
    * @param[out] frontElements number of front elements
@@ -675,8 +651,7 @@ private:
 private:                                    // Member Variables:
   TextureCacheManager mTextureCacheManager; ///< Manager the life-cycle and caching of Textures
 
-  std::unique_ptr<TextureAsyncLoadingHelper> mAsyncLoader;        ///< The Asynchronous image loader used to provide all local async loads
-  Dali::Vector<LifecycleObserver*>           mLifecycleObservers; ///< Lifecycle observers of texture manager
+  std::unique_ptr<TextureAsyncLoadingHelper> mAsyncLoader; ///< The Asynchronous image loader used to provide all local async loads
 
   Dali::Vector<QueueElement> mLoadQueue;             ///< Queue of textures to load after NotifyObservers
   TextureManager::TextureId  mLoadingQueueTextureId; ///< TextureId when it is loading. it causes Load Textures to be queued.
index 6dac0e7..60c0579 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -19,8 +19,8 @@
 #include <dali-toolkit/internal/visuals/animated-image/animated-image-visual.h>
 
 // EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/window-devel.h>
 #include <dali/devel-api/adaptor-framework/image-loading.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
 #include <dali/integration-api/debug.h>
 #include <dali/public-api/rendering/decorated-visual-renderer.h>
 #include <memory>
@@ -344,7 +344,24 @@ void AnimatedImageVisual::DoCreatePropertyMap(Property::Map& map) const
   map.Insert(Toolkit::ImageVisual::Property::FRAME_DELAY, static_cast<int>(mFrameDelay));
   map.Insert(Toolkit::DevelImageVisual::Property::LOOP_COUNT, static_cast<int>(mLoopCount));
   map.Insert(Toolkit::DevelImageVisual::Property::CURRENT_FRAME_NUMBER, (mImageCache) ? static_cast<int32_t>(mImageCache->GetCurrentFrameIndex()) : -1);
-  map.Insert(Toolkit::DevelImageVisual::Property::TOTAL_FRAME_NUMBER, (mImageCache) ? static_cast<int32_t>((mAnimatedImageLoading) ? mAnimatedImageLoading.GetImageCount() : mImageCache->GetTotalFrameCount()) : -1);
+
+  // This returns -1 until the loading is finished.
+  int32_t frameCount = mFrameCount;
+  if(mImageCache && frameCount == 0)
+  {
+    frameCount = mImageCache->GetTotalFrameCount();
+
+    if(frameCount <= SINGLE_IMAGE_COUNT && mAnimatedImageLoading && mAnimatedImageLoading.HasLoadingSucceeded())
+    {
+      frameCount = mAnimatedImageLoading.GetImageCount();
+    }
+    else
+    {
+      frameCount = -1;
+    }
+  }
+
+  map.Insert(Toolkit::DevelImageVisual::Property::TOTAL_FRAME_NUMBER, static_cast<int>(frameCount));
 
   map.Insert(Toolkit::DevelImageVisual::Property::STOP_BEHAVIOR, mStopBehavior);
 
@@ -766,11 +783,12 @@ void AnimatedImageVisual::DoSetOnScene(Actor& actor)
   mPlacementActor  = actor;
   PrepareTextureSet();
 
-  DevelActor::VisibilityChangedSignal(actor).Connect(this, &AnimatedImageVisual::OnControlVisibilityChanged);
+  actor.InheritedVisibilityChangedSignal().Connect(this, &AnimatedImageVisual::OnControlInheritedVisibilityChanged);
 
   Window window = DevelWindow::Get(actor);
   if(window)
   {
+    mPlacementWindow = window;
     DevelWindow::VisibilityChangedSignal(window).Connect(this, &AnimatedImageVisual::OnWindowVisibilityChanged);
   }
 }
@@ -800,12 +818,13 @@ void AnimatedImageVisual::DoSetOffScene(Actor& actor)
   mCurrentFrameIndex = FIRST_FRAME_INDEX;
   mCurrentLoopIndex  = FIRST_LOOP;
 
-  DevelActor::VisibilityChangedSignal(actor).Disconnect(this, &AnimatedImageVisual::OnControlVisibilityChanged);
+  actor.InheritedVisibilityChangedSignal().Disconnect(this, &AnimatedImageVisual::OnControlInheritedVisibilityChanged);
 
-  Window window = DevelWindow::Get(actor);
+  Window window = mPlacementWindow.GetHandle();
   if(window)
   {
     DevelWindow::VisibilityChangedSignal(window).Disconnect(this, &AnimatedImageVisual::OnWindowVisibilityChanged);
+    mPlacementWindow.Reset();
   }
 }
 
@@ -1115,13 +1134,13 @@ void AnimatedImageVisual::CheckMaskTexture()
   }
 }
 
-void AnimatedImageVisual::OnControlVisibilityChanged(Actor actor, bool visible, DevelActor::VisibilityChange::Type type)
+void AnimatedImageVisual::OnControlInheritedVisibilityChanged(Actor actor, bool visible)
 {
   if(!visible && mActionStatus != DevelAnimatedImageVisual::Action::STOP)
   {
     mActionStatus = DevelAnimatedImageVisual::Action::STOP;
     DisplayNextFrame();
-    DALI_LOG_INFO(gAnimImgLogFilter, Debug::Verbose, "AnimatedImageVisual::OnControlVisibilityChanged: invisibile. Pause animation [%p]\n", this);
+    DALI_LOG_INFO(gAnimImgLogFilter, Debug::Verbose, "AnimatedImageVisual::OnControlInheritedVisibilityChanged: invisibile. Pause animation [%p]\n", this);
   }
 }
 
index b37d74b..d8c2f8e 100644 (file)
@@ -259,9 +259,9 @@ private:
   void CheckMaskTexture();
 
   /**
-   * @brief Callback when the visibility of the actor is changed.
+   * @brief Callback when the inherited visibility of the actor is changed.
    */
-  void OnControlVisibilityChanged(Actor actor, bool visible, DevelActor::VisibilityChange::Type type);
+  void OnControlInheritedVisibilityChanged(Actor actor, bool visible);
 
   /**
    * @brief Callback when the visibility of the window is changed.
@@ -276,6 +276,7 @@ private:
 
 private:
   Timer                     mFrameDelayTimer;
+  WeakHandle<Window>        mPlacementWindow;
   WeakHandle<Actor>         mPlacementActor;
   ImageVisualShaderFactory& mImageVisualShaderFactory;
 
index adf8da8..e751f90 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -21,6 +21,7 @@
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h> // For ImageAtlasManagerPtr
 
 // EXTERNAL HEADERS
+#include <dali/integration-api/adaptor-framework/adaptor.h>
 #include <dali/integration-api/debug.h>
 
 namespace Dali
@@ -146,12 +147,6 @@ void FixedImageCache::LoadBatch()
 TextureSet FixedImageCache::GetTextureSet(uint32_t frameIndex) const
 {
   TextureSet textureSet = mTextureManager.GetTextureSet(mImageUrls[frameIndex].mTextureId);
-  if(textureSet)
-  {
-    Sampler sampler = Sampler::New();
-    sampler.SetWrapMode(Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT);
-    textureSet.SetSampler(0u, sampler);
-  }
   return textureSet;
 }
 
@@ -165,7 +160,7 @@ void FixedImageCache::MakeReady(bool wasReady, uint32_t frameIndex, bool preMult
 
 void FixedImageCache::ClearCache()
 {
-  if(mTextureManagerAlive)
+  if(Dali::Adaptor::IsAvailable())
   {
     for(std::size_t i = 0; i < mImageUrls.size(); ++i)
     {
@@ -185,7 +180,7 @@ void FixedImageCache::LoadComplete(bool loadSuccess, TextureInformation textureI
 {
   if(loadSuccess)
   {
-    mLoadState           = TextureManager::LoadState::LOAD_FINISHED;
+    mLoadState               = TextureManager::LoadState::LOAD_FINISHED;
     bool isCurrentFrameReady = IsFrameReady(mCurrentFrameIndex);
     if(!mRequestingLoad)
     {
index 2fda611..ece9014 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -42,23 +42,12 @@ ImageCache::ImageCache(TextureManager&                     textureManager,
   mInterval(interval),
   mLoadState(TextureManager::LoadState::NOT_STARTED),
   mRequestingLoad(false),
-  mPreMultiplyOnLoad(preMultiplyOnLoad),
-  mTextureManagerAlive(true)
+  mPreMultiplyOnLoad(preMultiplyOnLoad)
 {
-  mTextureManager.AddObserver(*this);
 }
 
 ImageCache::~ImageCache()
 {
-  if(mTextureManagerAlive)
-  {
-    mTextureManager.RemoveObserver(*this);
-  }
-}
-
-void ImageCache::TextureManagerDestroyed()
-{
-  mTextureManagerAlive = false;
 }
 
 void ImageCache::SetInterval(uint32_t interval)
index c40a895..aee80b2 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_IMAGE_CACHE_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.
@@ -27,7 +27,7 @@ namespace Toolkit
 {
 namespace Internal
 {
-class ImageCache : public TextureManager::LifecycleObserver
+class ImageCache
 {
 public:
   /**
@@ -137,11 +137,6 @@ public:
   virtual void SetInterval(uint32_t interval);
 
 private:
-  /**
-   * @brief Called before the texture manager is destroyed.
-   */
-  void TextureManagerDestroyed() final;
-
   void AllocateMaskData();
 
 protected:
@@ -156,7 +151,6 @@ protected:
   TextureManager::LoadState           mLoadState;
   bool                                mRequestingLoad : 1;
   bool                                mPreMultiplyOnLoad : 1;
-  bool                                mTextureManagerAlive : 1;
 };
 
 } // namespace Internal
index 370a678..3ece4cb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -20,6 +20,7 @@
 // INTERNAL HEADERS
 #include <dali-toolkit/devel-api/image-loader/texture-manager.h>
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h> // For ImageAtlasManagerPtr
+#include <dali/integration-api/adaptor-framework/adaptor.h>
 #include <dali/integration-api/debug.h>
 
 namespace
@@ -118,7 +119,7 @@ TextureSet RollingAnimatedImageCache::Frame(uint32_t frameIndex)
       synchronouslyLoaded = true;
       interval            = mAnimatedImageLoading.GetFrameInterval(mQueue.Back().mFrameNumber);
     }
-    MakeFrameReady(synchronouslyLoaded, textureSet, interval, preMultiplyOnLoading == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD);
+    MakeFrameReady(synchronouslyLoaded, textureSet, mAnimatedImageLoading.GetImageCount(), interval, preMultiplyOnLoading == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD);
   }
 
   if(popExist || mQueue.IsEmpty() || synchronouslyLoaded)
@@ -220,7 +221,7 @@ TextureSet RollingAnimatedImageCache::RequestFrameLoading(uint32_t frameIndex, b
                                                                    synchronousLoading,
                                                                    this,
                                                                    preMultiplyOnLoading);
-  if(textureSet)
+  if(textureSet && (mWrapModeU != Dali::WrapMode::DEFAULT || mWrapModeV != Dali::WrapMode::DEFAULT))
   {
     Sampler sampler = Sampler::New();
     sampler.SetWrapMode(mWrapModeU, mWrapModeV);
@@ -274,7 +275,7 @@ TextureSet RollingAnimatedImageCache::GetFrontTextureSet() const
 
   TextureManager::TextureId textureId  = GetCachedTextureId(0);
   TextureSet                textureSet = mTextureManager.GetTextureSet(textureId);
-  if(textureSet)
+  if(textureSet && (mWrapModeU != Dali::WrapMode::DEFAULT || mWrapModeV != Dali::WrapMode::DEFAULT))
   {
     Sampler sampler = Sampler::New();
     sampler.SetWrapMode(mWrapModeU, mWrapModeV);
@@ -306,7 +307,7 @@ void RollingAnimatedImageCache::PopFrontCache()
 
 void RollingAnimatedImageCache::ClearCache()
 {
-  while(mTextureManagerAlive && !mQueue.IsEmpty())
+  while(Dali::Adaptor::IsAvailable() && !mQueue.IsEmpty())
   {
     PopFrontCache();
   }
@@ -314,7 +315,7 @@ void RollingAnimatedImageCache::ClearCache()
   mLoadState = TextureManager::LoadState::NOT_STARTED;
 }
 
-void RollingAnimatedImageCache::MakeFrameReady(bool loadSuccess, TextureSet textureSet, uint32_t interval, bool preMultiplied)
+void RollingAnimatedImageCache::MakeFrameReady(bool loadSuccess, TextureSet textureSet, uint32_t frameCount, uint32_t interval, bool preMultiplied)
 {
   if(!loadSuccess)
   {
@@ -327,9 +328,9 @@ void RollingAnimatedImageCache::MakeFrameReady(bool loadSuccess, TextureSet text
     mLoadState = TextureManager::LoadState::LOAD_FINISHED;
 
     // Reset size of Queue according to the real frame count.
-    if(mFrameCount != mAnimatedImageLoading.GetImageCount())
+    if(mFrameCount != frameCount)
     {
-      mFrameCount = mAnimatedImageLoading.GetImageCount();
+      mFrameCount = frameCount;
       mTextureIds.resize(mFrameCount);
       mIntervals.assign(mFrameCount, 0u);
     }
@@ -353,14 +354,14 @@ void RollingAnimatedImageCache::LoadComplete(bool loadSuccess, TextureInformatio
   DALI_LOG_INFO(gAnimImgLogFilter, Debug::Concise, "AnimatedImageVisual::LoadComplete(textureId:%d) start\n", textureInformation.textureId);
   LOG_CACHE;
 
-  if(textureInformation.textureSet)
+  if(textureInformation.textureSet && (mWrapModeU != Dali::WrapMode::DEFAULT || mWrapModeV != Dali::WrapMode::DEFAULT))
   {
     Sampler sampler = Sampler::New();
     sampler.SetWrapMode(mWrapModeU, mWrapModeV);
     textureInformation.textureSet.SetSampler(0u, sampler);
   }
 
-  MakeFrameReady(loadSuccess, textureInformation.textureSet, textureInformation.interval, textureInformation.preMultiplied);
+  MakeFrameReady(loadSuccess, textureInformation.textureSet, textureInformation.frameCount, textureInformation.interval, textureInformation.preMultiplied);
 
   // TODO : We need to remove some below logics, since user can remove Visual during ResourceReady callback.
 
index 5c63db5..dde53b8 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_ROLLING_ANIMATED_IMAGE_CACHE_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.
@@ -169,10 +169,11 @@ private:
    *
    * @param[in] loadSuccess whether the loading is succeded or not.
    * @param[in] textureSet textureSet for this frame.
+   * @param[in] frameCount Total frame count for this image.
    * @param[in] interval interval between this frame and next frame.
    * @param[in] preMultiplied whether the texture is premultied alpha or not.
    */
-  void MakeFrameReady(bool loadSuccess, TextureSet textureSet, uint32_t interval, bool preMultiplied);
+  void MakeFrameReady(bool loadSuccess, TextureSet textureSet, uint32_t frameCount, uint32_t interval, bool preMultiplied);
 
   /**
    * @brief Pop front entity of Cache.
index 0bb1629..d818417 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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 HEADERS
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h> // For ImageAtlasManagerPtr
-#include <dali/integration-api/debug.h>
 
 // EXTERNAL HEADERS
+#include <dali/integration-api/adaptor-framework/adaptor.h>
+#include <dali/integration-api/debug.h>
 
 namespace
 {
@@ -220,7 +221,7 @@ void RollingImageCache::PopFrontCache()
 
 void RollingImageCache::ClearCache()
 {
-  while(mTextureManagerAlive && !mQueue.IsEmpty())
+  while(Dali::Adaptor::IsAvailable() && !mQueue.IsEmpty())
   {
     PopFrontCache();
   }
@@ -257,12 +258,6 @@ void RollingImageCache::LoadComplete(bool loadSuccess, TextureInformation textur
 
     if(!frontFrameReady && IsFrontReady())
     {
-      if(textureInformation.textureSet)
-      {
-        Sampler sampler = Sampler::New();
-        sampler.SetWrapMode(Dali::WrapMode::Type::DEFAULT, Dali::WrapMode::Type::DEFAULT);
-        textureInformation.textureSet.SetSampler(0u, sampler);
-      }
       mObserver.FrameReady(textureInformation.textureSet, mInterval, textureInformation.preMultiplied);
     }
   }
index 9c81c3b..9fc2fda 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/devel-api/adaptor-framework/window-devel.h>
 #include <dali/devel-api/common/stage.h>
 #include <dali/devel-api/rendering/renderer-devel.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
 #include <dali/integration-api/debug.h>
 #include <dali/public-api/math/math-utils.h>
 #include <dali/public-api/rendering/decorated-visual-renderer.h>
@@ -100,10 +101,10 @@ AnimatedVectorImageVisual::AnimatedVectorImageVisual(VisualFactoryCache& factory
   mLastSentPlayStateId(0u),
   mLoadFailed(false),
   mRendererAdded(false),
-  mCoreShutdown(false),
   mRedrawInScalingDown(true),
   mEnableFrameCache(false),
-  mUseNativeImage(false)
+  mUseNativeImage(false),
+  mNotifyAfterRasterization(false)
 {
   // the rasterized image is with pre-multiplied alpha format
   mImpl->mFlags |= Visual::Base::Impl::IS_PREMULTIPLIED_ALPHA;
@@ -114,7 +115,7 @@ AnimatedVectorImageVisual::AnimatedVectorImageVisual(VisualFactoryCache& factory
 
 AnimatedVectorImageVisual::~AnimatedVectorImageVisual()
 {
-  if(!mCoreShutdown)
+  if(Dali::Adaptor::IsAvailable())
   {
     if(mImageUrl.IsBufferResource())
     {
@@ -122,9 +123,6 @@ AnimatedVectorImageVisual::~AnimatedVectorImageVisual()
       textureManager.RemoveEncodedImageBuffer(mImageUrl.GetUrl());
     }
 
-    auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager();
-    vectorAnimationManager.RemoveObserver(*this);
-
     if(mEventCallback)
     {
       mFactoryCache.GetVectorAnimationManager().UnregisterEventCallback(mEventCallback);
@@ -137,12 +135,6 @@ AnimatedVectorImageVisual::~AnimatedVectorImageVisual()
   }
 }
 
-void AnimatedVectorImageVisual::VectorAnimationManagerDestroyed()
-{
-  // Core is shutting down. Don't talk to the plugin any more.
-  mCoreShutdown = true;
-}
-
 void AnimatedVectorImageVisual::GetNaturalSize(Vector2& naturalSize)
 {
   if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0)
@@ -221,6 +213,7 @@ void AnimatedVectorImageVisual::DoCreatePropertyMap(Property::Map& map) const
   map.Insert(Toolkit::ImageVisual::Property::DESIRED_WIDTH, mDesiredSize.GetWidth());
   map.Insert(Toolkit::ImageVisual::Property::DESIRED_HEIGHT, mDesiredSize.GetHeight());
   map.Insert(Toolkit::DevelImageVisual::Property::ENABLE_FRAME_CACHE, mEnableFrameCache);
+  map.Insert(Toolkit::DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, mNotifyAfterRasterization);
 }
 
 void AnimatedVectorImageVisual::DoCreateInstancePropertyMap(Property::Map& map) const
@@ -285,6 +278,10 @@ void AnimatedVectorImageVisual::DoSetProperties(const Property::Map& propertyMap
       {
         DoSetProperty(Toolkit::DevelImageVisual::Property::ENABLE_FRAME_CACHE, keyValue.second);
       }
+      else if(keyValue.first == NOTIFY_AFTER_RASTERIZATION)
+      {
+        DoSetProperty(Toolkit::DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION, keyValue.second);
+      }
     }
   }
 
@@ -404,6 +401,22 @@ void AnimatedVectorImageVisual::DoSetProperty(Property::Index index, const Prope
       }
       break;
     }
+
+    case Toolkit::DevelImageVisual::Property::NOTIFY_AFTER_RASTERIZATION:
+    {
+      bool notifyAfterRasterization = false;
+      if(value.Get(notifyAfterRasterization))
+      {
+        if(mNotifyAfterRasterization != notifyAfterRasterization)
+        {
+          mNotifyAfterRasterization = notifyAfterRasterization;
+
+          mAnimationData.notifyAfterRasterization = mNotifyAfterRasterization;
+          mAnimationData.resendFlag |= VectorAnimationTask::RESEND_NOTIFY_AFTER_RASTERIZATION;
+        }
+      }
+      break;
+    }
   }
 }
 
@@ -428,9 +441,6 @@ void AnimatedVectorImageVisual::OnInitialize(void)
   mVectorAnimationTask->KeepRasterizedBuffer(mEnableFrameCache);
   mVectorAnimationTask->RequestLoad(mImageUrl, encodedImageBuffer, IsSynchronousLoadingRequired());
 
-  auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager();
-  vectorAnimationManager.AddObserver(*this);
-
   Shader shader = GenerateShader();
 
   Geometry geometry = mFactoryCache.GetGeometry(VisualFactoryCache::QUAD_GEOMETRY);
@@ -471,11 +481,12 @@ void AnimatedVectorImageVisual::DoSetOnScene(Actor& actor)
     mSizeNotification = actor.AddPropertyNotification(Actor::Property::SIZE, StepCondition(3.0f));
     mSizeNotification.NotifySignal().Connect(this, &AnimatedVectorImageVisual::OnSizeNotification);
 
-    DevelActor::VisibilityChangedSignal(actor).Connect(this, &AnimatedVectorImageVisual::OnControlVisibilityChanged);
+    actor.InheritedVisibilityChangedSignal().Connect(this, &AnimatedVectorImageVisual::OnControlInheritedVisibilityChanged);
 
     Window window = DevelWindow::Get(actor);
     if(window)
     {
+      mPlacementWindow = window;
       DevelWindow::VisibilityChangedSignal(window).Connect(this, &AnimatedVectorImageVisual::OnWindowVisibilityChanged);
     }
 
@@ -507,12 +518,13 @@ void AnimatedVectorImageVisual::DoSetOffScene(Actor& actor)
   actor.RemovePropertyNotification(mScaleNotification);
   actor.RemovePropertyNotification(mSizeNotification);
 
-  DevelActor::VisibilityChangedSignal(actor).Disconnect(this, &AnimatedVectorImageVisual::OnControlVisibilityChanged);
+  actor.InheritedVisibilityChangedSignal().Disconnect(this, &AnimatedVectorImageVisual::OnControlInheritedVisibilityChanged);
 
-  Window window = DevelWindow::Get(actor);
+  Window window = mPlacementWindow.GetHandle();
   if(window)
   {
     DevelWindow::VisibilityChangedSignal(window).Disconnect(this, &AnimatedVectorImageVisual::OnWindowVisibilityChanged);
+    mPlacementWindow.Reset();
   }
 
   mPlacementActor.Reset();
@@ -605,7 +617,7 @@ void AnimatedVectorImageVisual::OnDoAction(const Property::Index actionId, const
     }
     case DevelAnimatedVectorImageVisual::Action::FLUSH:
     {
-      if(DALI_LIKELY(!mCoreShutdown))
+      if(DALI_LIKELY(Dali::Adaptor::IsAvailable()))
       {
         SendAnimationData();
       }
@@ -718,7 +730,7 @@ void AnimatedVectorImageVisual::OnAnimationFinished(uint32_t playStateId)
     }
   }
 
-  if(mImpl->mRenderer)
+  if(!mNotifyAfterRasterization && mImpl->mRenderer)
   {
     mImpl->mRenderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED);
   }
@@ -737,14 +749,18 @@ void AnimatedVectorImageVisual::SendAnimationData()
     }
     mVectorAnimationTask->SetAnimationData(mAnimationData);
 
-    if(mImpl->mRenderer)
+    if(mImpl->mRenderer &&
+       ((mAnimationData.resendFlag & VectorAnimationTask::RESEND_PLAY_STATE) ||
+        (mAnimationData.resendFlag & VectorAnimationTask::RESEND_NOTIFY_AFTER_RASTERIZATION)))
     {
-      if(mAnimationData.playState == DevelImageVisual::PlayState::PLAYING)
+      if(!mNotifyAfterRasterization && mPlayState == DevelImageVisual::PlayState::PLAYING)
       {
+        // Make rendering behaviour if we don't notify after rasterization, but animation playing.
         mImpl->mRenderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY);
       }
       else
       {
+        // Otherwise, notify will be sended after rasterization. Make behaviour as required.
         mImpl->mRenderer.SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::IF_REQUIRED);
       }
     }
@@ -788,7 +804,7 @@ void AnimatedVectorImageVisual::StopAnimation()
 
 void AnimatedVectorImageVisual::TriggerVectorRasterization()
 {
-  if(!mEventCallback && !mCoreShutdown)
+  if(!mEventCallback && Dali::Adaptor::IsAvailable())
   {
     mEventCallback               = MakeCallback(this, &AnimatedVectorImageVisual::OnProcessEvents);
     auto& vectorAnimationManager = mFactoryCache.GetVectorAnimationManager();
@@ -841,14 +857,14 @@ void AnimatedVectorImageVisual::OnSizeNotification(PropertyNotification& source)
   }
 }
 
-void AnimatedVectorImageVisual::OnControlVisibilityChanged(Actor actor, bool visible, DevelActor::VisibilityChange::Type type)
+void AnimatedVectorImageVisual::OnControlInheritedVisibilityChanged(Actor actor, bool visible)
 {
   if(!visible)
   {
     StopAnimation();
     TriggerVectorRasterization();
 
-    DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnControlVisibilityChanged: invisibile. Pause animation [%p]\n", this);
+    DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "AnimatedVectorImageVisual::OnControlInheritedVisibilityChanged: invisibile. Pause animation [%p]\n", this);
   }
 }
 
index fc7d7a4..fe3396a 100644 (file)
@@ -53,7 +53,7 @@ using AnimatedVectorImageVisualPtr = IntrusivePtr<AnimatedVectorImageVisual>;
  * | url                      | STRING           |
  *
  */
-class AnimatedVectorImageVisual : public Visual::Base, public ConnectionTracker, public VectorAnimationManager::LifecycleObserver
+class AnimatedVectorImageVisual : public Visual::Base, public ConnectionTracker
 {
 public:
   /**
@@ -99,12 +99,6 @@ public: // from Visual
    */
   void EnablePreMultipliedAlpha(bool preMultiplied) override;
 
-protected: // From VectorAnimationManager::LifecycleObserver:
-  /**
-   * @copydoc VectorAnimationManager::LifecycleObserver::VectorAnimationManagerDestroyed()
-   */
-  void VectorAnimationManagerDestroyed() override;
-
 protected:
   /**
    * @brief Constructor.
@@ -220,7 +214,7 @@ private:
   /**
    * @brief Callback when the visibility of the actor is changed.
    */
-  void OnControlVisibilityChanged(Actor actor, bool visible, DevelActor::VisibilityChange::Type type);
+  void OnControlInheritedVisibilityChanged(Actor actor, bool visible);
 
   /**
    * @brief Callback when the visibility of the window is changed.
@@ -239,6 +233,7 @@ private:
   AnimatedVectorImageVisual& operator=(const AnimatedVectorImageVisual& visual) = delete;
 
 private:
+  WeakHandle<Window>                 mPlacementWindow;
   VisualUrl                          mImageUrl;
   VectorAnimationTask::AnimationData mAnimationData;
   VectorAnimationTaskPtr             mVectorAnimationTask;
@@ -256,10 +251,10 @@ private:
 
   bool mLoadFailed : 1;
   bool mRendererAdded : 1;
-  bool mCoreShutdown : 1;
   bool mRedrawInScalingDown : 1;
   bool mEnableFrameCache : 1;
   bool mUseNativeImage : 1;
+  bool mNotifyAfterRasterization : 1;
 };
 
 } // namespace Internal
index fda5168..2d1fce9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -44,7 +44,6 @@ DALI_INIT_TRACE_FILTER(gTraceFilter, DALI_TRACE_IMAGE_PERFORMANCE_MARKER, false)
 
 VectorAnimationManager::VectorAnimationManager()
 : mEventCallbacks(),
-  mLifecycleObservers(),
   mVectorAnimationThread(nullptr),
   mProcessorRegistered(false)
 {
@@ -52,32 +51,12 @@ VectorAnimationManager::VectorAnimationManager()
 
 VectorAnimationManager::~VectorAnimationManager()
 {
-  mEventCallbacks.clear();
+  mEventCallbacks.Clear();
 
   if(mProcessorRegistered && Adaptor::IsAvailable())
   {
     Adaptor::Get().UnregisterProcessor(*this, true);
   }
-
-  for(auto observer : mLifecycleObservers)
-  {
-    observer->VectorAnimationManagerDestroyed();
-  }
-}
-
-void VectorAnimationManager::AddObserver(VectorAnimationManager::LifecycleObserver& observer)
-{
-  DALI_ASSERT_DEBUG(mLifecycleObservers.end() == std::find(mLifecycleObservers.begin(), mLifecycleObservers.end(), &observer));
-  mLifecycleObservers.push_back(&observer);
-}
-
-void VectorAnimationManager::RemoveObserver(VectorAnimationManager::LifecycleObserver& observer)
-{
-  auto iterator = std::find(mLifecycleObservers.begin(), mLifecycleObservers.end(), &observer);
-  if(iterator != mLifecycleObservers.end())
-  {
-    mLifecycleObservers.erase(iterator);
-  }
 }
 
 VectorAnimationThread& VectorAnimationManager::GetVectorAnimationThread()
@@ -92,7 +71,7 @@ VectorAnimationThread& VectorAnimationManager::GetVectorAnimationThread()
 
 void VectorAnimationManager::RegisterEventCallback(CallbackBase* callback)
 {
-  mEventCallbacks.emplace_back(std::unique_ptr<Dali::CallbackBase>(callback));
+  mEventCallbacks.PushBack(callback); ///< Take ownership of callback.
 
   if(!mProcessorRegistered)
   {
@@ -103,16 +82,12 @@ void VectorAnimationManager::RegisterEventCallback(CallbackBase* callback)
 
 void VectorAnimationManager::UnregisterEventCallback(CallbackBase* callback)
 {
-  auto iter = std::find_if(mEventCallbacks.begin(),
-                           mEventCallbacks.end(),
-                           [callback](const std::unique_ptr<CallbackBase>& element) {
-                             return element.get() == callback;
-                           });
-  if(iter != mEventCallbacks.end())
+  auto iter = mEventCallbacks.Find(callback);
+  if(iter != mEventCallbacks.End())
   {
-    mEventCallbacks.erase(iter);
+    mEventCallbacks.Erase(iter);
 
-    if(mEventCallbacks.empty())
+    if(mEventCallbacks.Count() == 0u)
     {
       if(Adaptor::IsAvailable())
       {
@@ -128,10 +103,10 @@ void VectorAnimationManager::Process(bool postProcessor)
 #ifdef TRACE_ENABLED
   if(gTraceFilter && gTraceFilter->IsTraceEnabled())
   {
-    if(mEventCallbacks.size() > 0u)
+    if(mEventCallbacks.Count() > 0u)
     {
       std::ostringstream oss;
-      oss << "[" << mEventCallbacks.size() << "]";
+      oss << "[" << mEventCallbacks.Count() << "]";
       DALI_TRACE_BEGIN_WITH_MESSAGE(gTraceFilter, "DALI_VECTOR_ANIMATION_MANAGER_PROCESS", oss.str().c_str());
     }
   }
@@ -145,15 +120,15 @@ void VectorAnimationManager::Process(bool postProcessor)
 #ifdef TRACE_ENABLED
   if(gTraceFilter && gTraceFilter->IsTraceEnabled())
   {
-    if(mEventCallbacks.size() > 0u)
+    if(mEventCallbacks.Count() > 0u)
     {
       std::ostringstream oss;
-      oss << "[" << mEventCallbacks.size() << "]";
+      oss << "[" << mEventCallbacks.Count() << "]";
       DALI_TRACE_END_WITH_MESSAGE(gTraceFilter, "DALI_VECTOR_ANIMATION_MANAGER_PROCESS", oss.str().c_str());
     }
   }
 #endif
-  mEventCallbacks.clear();
+  mEventCallbacks.Clear();
 
   Adaptor::Get().UnregisterProcessor(*this, true);
   mProcessorRegistered = false;
index c3cba21..53dbb06 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_VECTOR_ANIMATION_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.
@@ -19,6 +19,7 @@
  */
 
 // EXTERNAL INCLUDES
+#include <dali/integration-api/ordered-set.h>
 #include <dali/integration-api/processor-interface.h>
 #include <dali/public-api/common/vector-wrapper.h>
 #include <dali/public-api/signals/callback.h>
@@ -40,11 +41,6 @@ class VectorAnimationThread;
 class VectorAnimationManager : public Integration::Processor
 {
 public:
-  struct LifecycleObserver
-  {
-    virtual void VectorAnimationManagerDestroyed() = 0;
-  };
-
   /**
    * @brief Constructor.
    */
@@ -56,18 +52,6 @@ public:
   ~VectorAnimationManager() override;
 
   /**
-   * Add a lifecycle observer
-   * @param[in] observer The object watching this one
-   */
-  void AddObserver(LifecycleObserver& observer);
-
-  /**
-   * Remove a lifecycle observer
-   * @param[in] observer The object watching this one
-   */
-  void RemoveObserver(LifecycleObserver& observer);
-
-  /**
    * Get the vector animation thread.
    * @return A raw pointer pointing to the vector animation thread.
    */
@@ -110,10 +94,10 @@ private:
   VectorAnimationManager& operator=(const VectorAnimationManager& manager) = delete;
 
 private:
-  std::vector<std::unique_ptr<CallbackBase>> mEventCallbacks;
-  std::vector<LifecycleObserver*>            mLifecycleObservers;
-  std::unique_ptr<VectorAnimationThread>     mVectorAnimationThread;
-  bool                                       mProcessorRegistered;
+  Dali::Integration::OrderedSet<CallbackBase> mEventCallbacks; ///< Event triggered callback lists (owned)
+
+  std::unique_ptr<VectorAnimationThread> mVectorAnimationThread;
+  bool                                   mProcessorRegistered : 1;
 };
 
 } // namespace Internal
index 4f4e97d..ac448c0 100644 (file)
@@ -98,6 +98,7 @@ VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache)
   mForward(true),
   mUpdateFrameNumber(false),
   mNeedAnimationFinishedTrigger(true),
+  mNeedForceRenderOnceTrigger(false),
   mAnimationDataUpdated(false),
   mDestroyTask(false),
   mLoadRequest(false),
@@ -107,6 +108,7 @@ VectorAnimationTask::VectorAnimationTask(VisualFactoryCache& factoryCache)
   mLayerInfoCached(false),
   mMarkerInfoCached(false),
   mEnableFrameCache(false),
+  mNotifyAfterRasterization(false),
   mSizeUpdated(false)
 {
   mVectorRenderer.UploadCompletedSignal().Connect(this, &VectorAnimationTask::OnUploadCompleted);
@@ -376,6 +378,9 @@ void VectorAnimationTask::PauseAnimation()
   {
     mPlayState = PlayState::PAUSED;
 
+    // Ensure to render paused frame.
+    mNeedForceRenderOnceTrigger = true;
+
     DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::PauseAnimation: Pause [%p]\n", this);
   }
 }
@@ -467,10 +472,22 @@ void VectorAnimationTask::SetPlayRange(const Property::Array& playRange)
     if(mStartFrame > mCurrentFrame)
     {
       mCurrentFrame = mStartFrame;
+
+      if(mPlayState != PlayState::PLAYING)
+      {
+        // Ensure to render current frame.
+        mNeedForceRenderOnceTrigger = true;
+      }
     }
     else if(mEndFrame < mCurrentFrame)
     {
       mCurrentFrame = mEndFrame;
+
+      if(mPlayState != PlayState::PLAYING)
+      {
+        // Ensure to render current frame.
+        mNeedForceRenderOnceTrigger = true;
+      }
     }
 
     DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetPlayRange: [%d, %d] [%s] [%p]\n", mStartFrame, mEndFrame, mImageUrl.GetUrl().c_str(), this);
@@ -496,6 +513,12 @@ void VectorAnimationTask::SetCurrentFrameNumber(uint32_t frameNumber)
     mCurrentFrame      = frameNumber;
     mUpdateFrameNumber = false;
 
+    if(mPlayState != PlayState::PLAYING)
+    {
+      // Ensure to render current frame.
+      mNeedForceRenderOnceTrigger = true;
+    }
+
     DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::SetCurrentFrameNumber: frame number = %d [%p]\n", mCurrentFrame, this);
   }
   else
@@ -693,6 +716,8 @@ bool VectorAnimationTask::Rasterize()
     mForward     = true;
     mCurrentLoop = 0;
 
+    mNeedForceRenderOnceTrigger = true;
+
     if(mVectorRenderer)
     {
       // Notify the Renderer that rendering is stopped.
@@ -711,6 +736,14 @@ bool VectorAnimationTask::Rasterize()
     DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Rasterize: Animation is finished [current = %d] [%p]\n", currentFrame, this);
   }
 
+  // Forcely trigger render once if need.
+  if(mNotifyAfterRasterization || mNeedForceRenderOnceTrigger)
+  {
+    Mutex::ScopedLock lock(mMutex);
+    mVectorAnimationThread.RequestForceRenderOnce();
+    mNeedForceRenderOnceTrigger = false;
+  }
+
   if(mPlayState != PlayState::PAUSED && mPlayState != PlayState::STOPPED)
   {
     mKeepAnimation = true;
@@ -845,6 +878,11 @@ void VectorAnimationTask::ApplyAnimationData()
       SetCurrentFrameNumber(animationData.currentFrame);
     }
 
+    if(animationData.resendFlag & VectorAnimationTask::RESEND_NOTIFY_AFTER_RASTERIZATION)
+    {
+      mNotifyAfterRasterization = animationData.notifyAfterRasterization;
+    }
+
     if(animationData.resendFlag & VectorAnimationTask::RESEND_NEED_RESOURCE_READY)
     {
       mVectorRenderer.InvalidateBuffer();
index eb48a13..c741be1 100644 (file)
@@ -67,15 +67,16 @@ public:
    */
   enum ResendFlags
   {
-    RESEND_PLAY_RANGE          = 1 << 0,
-    RESEND_LOOP_COUNT          = 1 << 1,
-    RESEND_STOP_BEHAVIOR       = 1 << 2,
-    RESEND_LOOPING_MODE        = 1 << 3,
-    RESEND_CURRENT_FRAME       = 1 << 4,
-    RESEND_SIZE                = 1 << 5,
-    RESEND_PLAY_STATE          = 1 << 6,
-    RESEND_NEED_RESOURCE_READY = 1 << 7,
-    RESEND_DYNAMIC_PROPERTY    = 1 << 8
+    RESEND_PLAY_RANGE                 = 1 << 0,
+    RESEND_LOOP_COUNT                 = 1 << 1,
+    RESEND_STOP_BEHAVIOR              = 1 << 2,
+    RESEND_LOOPING_MODE               = 1 << 3,
+    RESEND_CURRENT_FRAME              = 1 << 4,
+    RESEND_SIZE                       = 1 << 5,
+    RESEND_PLAY_STATE                 = 1 << 6,
+    RESEND_NEED_RESOURCE_READY        = 1 << 7,
+    RESEND_DYNAMIC_PROPERTY           = 1 << 8,
+    RESEND_NOTIFY_AFTER_RASTERIZATION = 1 << 9,
   };
 
   /**
@@ -94,22 +95,24 @@ public:
       width(0),
       height(0),
       loopCount(-1),
-      playStateId(0)
+      playStateId(0),
+      notifyAfterRasterization(false)
     {
     }
 
     AnimationData& operator=(const AnimationData& rhs)
     {
       resendFlag |= rhs.resendFlag; // OR resend flag
-      playRange    = rhs.playRange;
-      playState    = rhs.playState;
-      stopBehavior = rhs.stopBehavior;
-      loopingMode  = rhs.loopingMode;
-      currentFrame = rhs.currentFrame;
-      width        = rhs.width;
-      height       = rhs.height;
-      loopCount    = rhs.loopCount;
-      playStateId  = rhs.playStateId;
+      playRange                = rhs.playRange;
+      playState                = rhs.playState;
+      stopBehavior             = rhs.stopBehavior;
+      loopingMode              = rhs.loopingMode;
+      currentFrame             = rhs.currentFrame;
+      width                    = rhs.width;
+      height                   = rhs.height;
+      loopCount                = rhs.loopCount;
+      playStateId              = rhs.playStateId;
+      notifyAfterRasterization = rhs.notifyAfterRasterization;
       dynamicProperties.insert(dynamicProperties.end(), rhs.dynamicProperties.begin(), rhs.dynamicProperties.end());
       return *this;
     }
@@ -125,6 +128,7 @@ public:
     uint32_t                             height;
     int32_t                              loopCount;
     uint32_t                             playStateId;
+    bool                                 notifyAfterRasterization;
   };
 
   /**
@@ -257,6 +261,16 @@ public:
    */
   bool IsAnimating();
 
+  void KeepRasterizedBuffer(bool enableFrameCache)
+  {
+    mEnableFrameCache = enableFrameCache;
+  }
+
+  bool IsKeptRasterizedBuffer() const
+  {
+    return mEnableFrameCache;
+  }
+
 public: // Implementation of AsyncTask
   /**
    * @copydoc Dali::AsyncTask::Process()
@@ -276,16 +290,6 @@ public: // Implementation of AsyncTask
     return "VectorAnimationTask";
   }
 
-  void KeepRasterizedBuffer(bool enableFrameCache)
-  {
-    mEnableFrameCache = enableFrameCache;
-  }
-
-  bool IsKeptRasterizedBuffer()
-  {
-    return mEnableFrameCache;
-  }
-
 private:
   /**
    * @brief Loads the animation file.
@@ -416,6 +420,7 @@ private:
   bool                                 mForward : 1;
   bool                                 mUpdateFrameNumber : 1;
   bool                                 mNeedAnimationFinishedTrigger : 1;
+  bool                                 mNeedForceRenderOnceTrigger : 1;
   bool                                 mAnimationDataUpdated : 1;
   bool                                 mDestroyTask : 1;
   bool                                 mLoadRequest : 1;
@@ -425,6 +430,7 @@ private:
   mutable bool                         mLayerInfoCached : 1;
   mutable bool                         mMarkerInfoCached : 1;
   bool                                 mEnableFrameCache : 1;
+  bool                                 mNotifyAfterRasterization : 1;
   bool                                 mSizeUpdated : 1;
 };
 
index b07ba5b..5638ec3 100644 (file)
@@ -46,10 +46,12 @@ VectorAnimationThread::VectorAnimationThread()
   mSleepThread(MakeCallback(this, &VectorAnimationThread::OnAwakeFromSleep)),
   mConditionalWait(),
   mEventTriggerMutex(),
+  mLogFactory(Dali::Adaptor::Get().GetLogFactory()),
+  mTraceFactory(Dali::Adaptor::Get().GetTraceFactory()),
   mNeedToSleep(false),
   mDestroyThread(false),
-  mLogFactory(Dali::Adaptor::Get().GetLogFactory()),
-  mTraceFactory(Dali::Adaptor::Get().GetTraceFactory())
+  mEventTriggered(false),
+  mForceRenderOnce(false)
 {
   mAsyncTaskManager = Dali::AsyncTaskManager::Get();
   mSleepThread.Start();
@@ -184,6 +186,21 @@ void VectorAnimationThread::RemoveEventTriggerCallbacks(CallbackBase* callback)
   }
 }
 
+void VectorAnimationThread::RequestForceRenderOnce()
+{
+  Mutex::ScopedLock lock(mEventTriggerMutex);
+  if(!mDestroyThread)
+  {
+    mForceRenderOnce = true;
+
+    if(!mEventTriggered)
+    {
+      mEventTrigger->Trigger();
+      mEventTriggered = true;
+    }
+  }
+}
+
 void VectorAnimationThread::Run()
 {
   SetThreadName("VectorAnimationThread");
@@ -285,6 +302,18 @@ void VectorAnimationThread::OnEventCallbackTriggered()
     }
     CallbackBase::Execute(*callbackPair.first, callbackPair.second);
   }
+  // Request update once if we need.
+  {
+    Mutex::ScopedLock lock(mEventTriggerMutex);
+    if(!mDestroyThread && mForceRenderOnce)
+    {
+      mForceRenderOnce = false;
+      if(Dali::Adaptor::IsAvailable())
+      {
+        Dali::Adaptor::Get().UpdateOnce();
+      }
+    }
+  }
 }
 
 std::pair<CallbackBase*, uint32_t> VectorAnimationThread::GetNextEventCallback()
index b1f608a..8b820cc 100644 (file)
@@ -90,6 +90,11 @@ public:
    */
   void RemoveEventTriggerCallbacks(CallbackBase* callback);
 
+  /**
+   * @brief Request to event callback from rasterize thread. This is called when we want to ensure rendering next frame.
+   */
+  void RequestForceRenderOnce();
+
 protected:
   /**
    * @brief The entry function of the animation thread.
@@ -149,8 +154,9 @@ private:
     std::chrono::time_point<std::chrono::steady_clock> mSleepTimePoint;
     const Dali::LogFactoryInterface&                   mLogFactory;
     const Dali::TraceFactoryInterface&                 mTraceFactory;
-    bool                                               mNeedToSleep;
-    bool                                               mDestroyThread;
+
+    bool mNeedToSleep : 1;
+    bool mDestroyThread : 1;
   };
 
 private:
@@ -169,12 +175,14 @@ private:
   ConditionalWait                                 mConditionalWait;
   Mutex                                           mEventTriggerMutex;
   std::unique_ptr<EventThreadCallback>            mEventTrigger{};
-  bool                                            mNeedToSleep;
-  bool                                            mDestroyThread;
-  bool                                            mEventTriggered{false};
   const Dali::LogFactoryInterface&                mLogFactory;
   const Dali::TraceFactoryInterface&              mTraceFactory;
   Dali::AsyncTaskManager                          mAsyncTaskManager;
+
+  bool mNeedToSleep : 1;
+  bool mDestroyThread : 1;
+  bool mEventTriggered : 1;
+  bool mForceRenderOnce : 1;
 };
 
 } // namespace Internal
index 1aa9bd8..066d506 100644 (file)
@@ -258,10 +258,13 @@ void GradientVisual::OnInitialize()
   TextureSet    textureSet    = TextureSet::New();
   Dali::Texture lookupTexture = mGradient->GenerateLookupTexture();
   textureSet.SetTexture(0u, lookupTexture);
-  Dali::WrapMode::Type wrap    = GetWrapMode(mGradient->GetSpreadMethod());
-  Sampler              sampler = Sampler::New();
-  sampler.SetWrapMode(wrap, wrap);
-  textureSet.SetSampler(0u, sampler);
+  Dali::WrapMode::Type wrap = GetWrapMode(mGradient->GetSpreadMethod());
+  if(wrap != Dali::WrapMode::DEFAULT)
+  {
+    Sampler sampler = Sampler::New();
+    sampler.SetWrapMode(wrap, wrap);
+    textureSet.SetSampler(0u, sampler);
+  }
 
   mImpl->mRenderer = DecoratedVisualRenderer::New(geometry, shader);
   mImpl->mRenderer.ReserveCustomProperties(CUSTOM_PROPERTY_COUNT);
index 6b30a02..02d08af 100644 (file)
@@ -694,7 +694,7 @@ void ImageVisual::LoadTexture(bool& atlasing, Vector4& atlasRect, TextureSet& te
     }
 
     EnablePreMultipliedAlpha(preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD);
-    if(!atlasing)
+    if(!atlasing && (mWrapModeU != Dali::WrapMode::DEFAULT || mWrapModeV != Dali::WrapMode::DEFAULT))
     {
       Sampler sampler = Sampler::New();
       sampler.SetWrapMode(mWrapModeU, mWrapModeV);
@@ -744,7 +744,9 @@ void ImageVisual::InitializeRenderer()
     else
     {
       mTextures = mFactoryCache.GetTextureManager().GetTextureSet(mTextureId);
-      if(!(mImpl->mFlags & Visual::Base::Impl::IS_ATLASING_APPLIED) && mTextures)
+      if(!(mImpl->mFlags & Visual::Base::Impl::IS_ATLASING_APPLIED) &&
+         mTextures &&
+         (mWrapModeU != Dali::WrapMode::DEFAULT || mWrapModeV != Dali::WrapMode::DEFAULT))
       {
         Sampler sampler = Sampler::New();
         sampler.SetWrapMode(mWrapModeU, mWrapModeV);
@@ -1057,9 +1059,12 @@ void ImageVisual::LoadComplete(bool loadingSuccess, TextureInformation textureIn
     }
     else
     {
-      Sampler sampler = Sampler::New();
-      sampler.SetWrapMode(mWrapModeU, mWrapModeV);
-      textureInformation.textureSet.SetSampler(0u, sampler);
+      if(mWrapModeU != Dali::WrapMode::DEFAULT || mWrapModeV != Dali::WrapMode::DEFAULT)
+      {
+        Sampler sampler = Sampler::New();
+        sampler.SetWrapMode(mWrapModeU, mWrapModeV);
+        textureInformation.textureSet.SetSampler(0u, sampler);
+      }
 
       mImpl->mRenderer.SetTextures(textureInformation.textureSet);
       ComputeTextureSize();
index 2544899..1047eaf 100644 (file)
@@ -105,13 +105,6 @@ void NPatchVisual::LoadImages()
     // Load the auxiliary image
     mAuxiliaryTextureSet = textureManager.LoadTexture(mAuxiliaryUrl, Dali::ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, maskingDataPtr, synchronousLoading, mAuxiliaryTextureId, atlasRect, atlasRectSize, atlasing, loadingStatus, this, nullptr, imageAtlasManagerPtr, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad);
 
-    if(mAuxiliaryTextureSet)
-    {
-      Sampler sampler = Sampler::New();
-      sampler.SetWrapMode(WrapMode::DEFAULT, WrapMode::DEFAULT);
-      mAuxiliaryTextureSet.SetSampler(0u, sampler);
-    }
-
     // If synchronousLoading is true, we can check the auxiliaryResource's status now.
     if(synchronousLoading)
     {
@@ -613,14 +606,7 @@ void NPatchVisual::LoadComplete(bool loadSuccess, TextureInformation textureInfo
     }
     if(loadSuccess)
     {
-      mAuxiliaryTextureSet = textureInformation.textureSet;
-      if(mAuxiliaryTextureSet)
-      {
-        Sampler sampler = Sampler::New();
-        sampler.SetWrapMode(WrapMode::DEFAULT, WrapMode::DEFAULT);
-        mAuxiliaryTextureSet.SetSampler(0u, sampler);
-      }
-
+      mAuxiliaryTextureSet     = textureInformation.textureSet;
       mAuxiliaryResourceStatus = Toolkit::Visual::ResourceStatus::READY;
     }
     else
index 33e2c41..02bd921 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -350,12 +350,13 @@ void TextVisual::DoSetOnScene(Actor& actor)
   UpdateRenderer();
 }
 
-void TextVisual::RemoveRenderer(Actor& actor)
+void TextVisual::RemoveRenderer(Actor& actor, bool removeDefaultRenderer)
 {
   for(RendererContainer::iterator iter = mRendererList.begin(); iter != mRendererList.end(); ++iter)
   {
     Renderer renderer = (*iter);
-    if(renderer)
+    if(renderer &&
+       (removeDefaultRenderer || (renderer != mImpl->mRenderer)))
     {
       // Removes the renderer from the actor.
       actor.RemoveRenderer(renderer);
@@ -376,7 +377,7 @@ void TextVisual::DoSetOffScene(Actor& actor)
     mOpacityConstraint.Remove();
   }
 
-  RemoveRenderer(actor);
+  RemoveRenderer(actor, true);
 
   // Resets the control handle.
   mControl.Reset();
@@ -511,7 +512,7 @@ void TextVisual::UpdateRenderer()
   if((fabsf(relayoutSize.width) < Math::MACHINE_EPSILON_1000) || (fabsf(relayoutSize.height) < Math::MACHINE_EPSILON_1000) || textLengthUtf32 == 0u)
   {
     // Remove the texture set and any renderer previously set.
-    RemoveRenderer(control);
+    RemoveRenderer(control, true);
 
     // Nothing else to do if the relayout size is zero.
     ResourceReady(Toolkit::Visual::ResourceStatus::READY);
@@ -527,7 +528,8 @@ void TextVisual::UpdateRenderer()
     mRendererUpdateNeeded = false;
 
     // Remove the texture set and any renderer previously set.
-    RemoveRenderer(control);
+    // Note, we don't need to remove the mImpl->Renderer, since it will be added again after AddRenderer call.
+    RemoveRenderer(control, false);
 
     if((relayoutSize.width > Math::MACHINE_EPSILON_1000) &&
        (relayoutSize.height > Math::MACHINE_EPSILON_1000))
@@ -765,6 +767,7 @@ void TextVisual::AddRenderer(Actor& actor, const Vector2& size, bool hasMultiple
     Renderer renderer = (*iter);
     if(renderer)
     {
+      // Note, AddRenderer will ignore renderer if it is already added. @SINCE 2_3.22
       actor.AddRenderer(renderer);
 
       if(renderer != mImpl->mRenderer)
index 7be059c..1376184 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_TEXT_VISUAL_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.
@@ -239,7 +239,7 @@ private:
   /**
    * @brief Removes the text's renderer.
    */
-  void RemoveRenderer(Actor& actor);
+  void RemoveRenderer(Actor& actor, bool removeDefaultRenderer);
 
   /**
    * @brief Create a texture in textureSet and add it.
index b3d8201..aee602d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/internal/helpers/property-helper.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
@@ -121,7 +122,7 @@ Internal::Visual::Base::Impl::Impl(FittingMode fittingMode, Toolkit::Visual::Typ
   mMixColor(Color::WHITE),
   mControlSize(Vector2::ZERO),
   mDecorationData(nullptr),
-  mDepthIndex(0.0f),
+  mDepthIndex(Toolkit::DepthIndex::AUTO_INDEX),
   mFittingMode(fittingMode),
   mFlags(0),
   mResourceStatus(Toolkit::Visual::ResourceStatus::PREPARING),
index 3d8e79e..42f945d 100644 (file)
@@ -27,6 +27,7 @@
 #include <dali/public-api/rendering/visual-renderer.h>
 
 //INTERNAL HEARDER
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/devel-api/visuals/color-visual-properties-devel.h>
 #include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
@@ -519,10 +520,16 @@ void Visual::Base::DoActionExtension(const Dali::Property::Index actionId, const
 
 void Visual::Base::SetDepthIndex(int index)
 {
-  mImpl->mDepthIndex = index;
-  if(mImpl->mRenderer)
+  // Clamp input value as valid range.
+  Dali::ClampInPlace(index, static_cast<int>(Toolkit::DepthIndex::MINIMUM_DEPTH_INDEX), static_cast<int>(Toolkit::DepthIndex::MAXIMUM_DEPTH_INDEX));
+
+  if(mImpl->mDepthIndex != index)
   {
-    mImpl->mRenderer.SetProperty(Renderer::Property::DEPTH_INDEX, mImpl->mDepthIndex);
+    mImpl->mDepthIndex = index;
+    if(mImpl->mRenderer)
+    {
+      mImpl->mRenderer.SetProperty(Renderer::Property::DEPTH_INDEX, mImpl->mDepthIndex);
+    }
   }
 }
 
@@ -542,7 +549,14 @@ void Visual::Base::SetOnScene(Actor& actor)
     if(mImpl->mRenderer)
     {
       mImpl->mRenderer.SetProperty(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, IsPreMultipliedAlphaEnabled());
-      mImpl->mRenderer.SetProperty(Renderer::Property::DEPTH_INDEX, mImpl->mDepthIndex);
+      if(mImpl->mDepthIndex == static_cast<int>(DepthIndex::AUTO_INDEX))
+      {
+        mImpl->mRenderer.SetProperty(Renderer::Property::DEPTH_INDEX, static_cast<int>(DepthIndex::CONTENT));
+      }
+      else
+      {
+        mImpl->mRenderer.SetProperty(Renderer::Property::DEPTH_INDEX, mImpl->mDepthIndex);
+      }
     }
 
     mImpl->mFlags |= Impl::IS_ON_SCENE;
index 6d89342..ae39540 100644 (file)
@@ -212,6 +212,7 @@ const char* const MASK_TEXTURE_RATIO_NAME("maskTextureRatio");
 const char* const FAST_TRACK_UPLOADING_NAME("fastTrackUploading");
 const char* const ENABLE_BROKEN_IMAGE("enableBrokenImage");
 const char* const ENABLE_FRAME_CACHE("enableFrameCache");
+const char* const NOTIFY_AFTER_RASTERIZATION("notifyAfterRasterization");
 
 // Text visual
 const char* const TEXT_PROPERTY("text");
index cc97413..9835299 100644 (file)
@@ -114,6 +114,7 @@ extern const char* const MASK_TEXTURE_RATIO_NAME;
 extern const char* const FAST_TRACK_UPLOADING_NAME;
 extern const char* const ENABLE_BROKEN_IMAGE;
 extern const char* const ENABLE_FRAME_CACHE;
+extern const char* const NOTIFY_AFTER_RASTERIZATION;
 
 // Text visual
 extern const char* const TEXT_PROPERTY;
index 67b5ab0..40f34a0 100644 (file)
@@ -581,7 +581,7 @@ void Control::OnPropertySet(Property::Index index, const Property::Value& proper
     case Actor::Property::VISIBLE:
     {
       auto* accessible = GetAccessibleObject();
-      if(DALI_LIKELY(accessible))
+      if(DALI_LIKELY(accessible) && accessible->IsHighlighted())
       {
         accessible->EmitVisible(Self().GetProperty<bool>(Actor::Property::VISIBLE));
       }
index 81dc48e..9e4e00e 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 {
 const unsigned int TOOLKIT_MAJOR_VERSION = 2;
 const unsigned int TOOLKIT_MINOR_VERSION = 3;
-const unsigned int TOOLKIT_MICRO_VERSION = 18;
+const unsigned int TOOLKIT_MICRO_VERSION = 23;
 const char* const  TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index 034d18e..5f9ed14 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali2-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    2.3.18
+Version:    2.3.23
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT