Apply fittingMode lazy when resource is not ready 43/297443/2
authorsunghyun kim <scholb.kim@samsung.com>
Fri, 18 Aug 2023 08:14:21 +0000 (17:14 +0900)
committersunghyun kim <scholb.kim@samsung.com>
Wed, 6 Sep 2023 08:33:04 +0000 (17:33 +0900)
FittingMode may not work properly if ResourceReady is called later than Relayout.
to prevent this, modify to apply FittingMode late if Resource is not ready

Change-Id: Idb0c572a9aa034cea25f563ffbc256ad8eacacda

automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/controls/image-view/image-view-impl.h

index 6fb05ab..fe523a6 100644 (file)
@@ -1054,6 +1054,23 @@ void ResourceReadySignal(Control control)
   gResourceReadySignalFired = true;
 }
 
+void OnResourceReadySignalSVG(Control control)
+{
+  // Check whether Image Visual transforms on ImageVieiw::OnRelayout()
+  Toolkit::Internal::Control& controlImpl = Toolkit::Internal::GetImplementation(control);
+  Toolkit::Visual::Base       imageVisual = DevelControl::GetVisual(controlImpl, ImageView::Property::IMAGE);
+  Property::Map               resultMap;
+  imageVisual.CreatePropertyMap(resultMap);
+
+  Property::Value* transformValue = resultMap.Find(Visual::Property::TRANSFORM);
+  DALI_TEST_CHECK(transformValue);
+  Property::Map* retMap = transformValue->GetMap();
+  DALI_TEST_CHECK(retMap);
+
+  // Fitting mode should not be applied at this point
+  DALI_TEST_EQUALS(retMap->Find(Visual::Transform::Property::SIZE)->Get<Vector2>(),  Vector2::ZERO, TEST_LOCATION);
+}
+
 int UtcDaliImageViewCheckResourceReady(void)
 {
   ToolkitTestApplication application;
@@ -2816,6 +2833,51 @@ int UtcDaliImageViewSyncSVGLoading(void)
   END_TEST;
 }
 
+int UtcDaliImageViewSyncSVGLoading02(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline("ImageView Testing SVG image sync loading");
+
+  {
+    ImageView imageView = ImageView::New();
+
+    // Sync loading is used
+    Property::Map syncLoadingMap;
+    syncLoadingMap.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE);
+    syncLoadingMap.Insert(Toolkit::ImageVisual::Property::URL, TEST_RESOURCE_DIR "/svg1.svg");
+    syncLoadingMap.Insert(Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, true);
+    syncLoadingMap.Insert(DevelVisual::Property::VISUAL_FITTING_MODE, Toolkit::DevelVisual::FIT_KEEP_ASPECT_RATIO);
+    imageView.SetProperty(ImageView::Property::IMAGE, syncLoadingMap);
+    imageView.ResourceReadySignal().Connect(&OnResourceReadySignalSVG);
+
+    application.GetScene().Add(imageView);
+    DALI_TEST_CHECK(imageView);
+
+    application.SendNotification();
+    application.Render();
+
+    // Check whether Image Visual transforms on ImageVieiw::OnRelayout()
+    Toolkit::Internal::Control& controlImpl = Toolkit::Internal::GetImplementation(imageView);
+    Toolkit::Visual::Base       imageVisual = DevelControl::GetVisual(controlImpl, ImageView::Property::IMAGE);
+    Property::Map               resultMap;
+    imageVisual.CreatePropertyMap(resultMap);
+
+    Property::Value* transformValue = resultMap.Find(Visual::Property::TRANSFORM);
+    DALI_TEST_CHECK(transformValue);
+    Property::Map* retMap = transformValue->GetMap();
+    DALI_TEST_CHECK(retMap);
+
+    // Image Visual should be positioned depending on ImageView's padding
+    DALI_TEST_EQUALS(retMap->Find(Visual::Transform::Property::SIZE)->Get<Vector2>(),  Vector2(100, 100), TEST_LOCATION);
+
+    Vector3 naturalSize = imageView.GetNaturalSize();
+    DALI_TEST_EQUALS(naturalSize.width, 100.0f, TEST_LOCATION);
+    DALI_TEST_EQUALS(naturalSize.height, 100.0f, TEST_LOCATION);
+  }
+  END_TEST;
+}
+
 int UtcDaliImageViewAsyncSVGLoading(void)
 {
   ToolkitTestApplication application;
index 87ab126..f893f46 100644 (file)
@@ -72,7 +72,8 @@ ImageView::ImageView(ControlBehaviour additionalBehaviour)
   mTransitionTargetAlpha(FULL_OPACITY),
   mImageVisualPaddingSetByTransform(false),
   mImageViewPixelAreaSetByFittingMode(false),
-  mTransitionEffect(false)
+  mTransitionEffect(false),
+  mNeedLazyFittingMode(false)
 {
 }
 
@@ -370,26 +371,15 @@ void ImageView::OnRelayout(const Vector2& size, RelayoutContainer& container)
   Control::OnRelayout(size, container);
   if(mVisual)
   {
-    Property::Map transformMap = Property::Map();
-
-    Extents padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
-
-    bool zeroPadding = (padding == Extents());
-
-    Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(
-      Self().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
-    if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
+    // If Resource is not ready, fittingMode is not working well.
+    // in this case, imageview set the flag for working applyFittingMode again when the resource is ready
+    if(!IsResourceReady())
     {
-      std::swap(padding.start, padding.end);
+      mNeedLazyFittingMode = true;
     }
 
-    // remove padding from the size to know how much is left for the visual
-    Vector2 finalSize   = size - Vector2(padding.start + padding.end, padding.top + padding.bottom);
-    Vector2 finalOffset = Vector2(padding.start, padding.top);
-
-    ApplyFittingMode(finalSize, finalOffset, zeroPadding, transformMap);
-
-    mVisual.SetTransformAndSize(transformMap, size);
+    // Apply FittingMode using actor's size
+    ApplyFittingMode(size);
 
     // mVisual is not updated util the resource is ready in the case of visual replacement.
     // in this case, the Property Map must be initialized so that the previous value is not reused.
@@ -467,6 +457,15 @@ void ImageView::OnResourceReady(Toolkit::Control control)
 
   // Visual ready so update visual attached to this ImageView, following call to RelayoutRequest will use this visual.
   mVisual = DevelControl::GetVisual(*this, Toolkit::ImageView::Property::IMAGE);
+
+  // Applying FittingMode again if it is not working well on OnRelayout().
+  if(mNeedLazyFittingMode)
+  {
+    const Vector2& size = Self().GetProperty(Dali::Actor::Property::SIZE).Get<Vector2>();
+    ApplyFittingMode(size);
+    mNeedLazyFittingMode = false;
+  }
+
   // Signal that a Relayout may be needed
 }
 
@@ -547,8 +546,25 @@ void ImageView::SetTransformMapForFittingMode(Vector2 finalSize, Vector2 natural
   }
 }
 
-void ImageView::ApplyFittingMode(Vector2 finalSize, Vector2 finalOffset, bool zeroPadding, Property::Map& transformMap)
+void ImageView::ApplyFittingMode(const Vector2& size)
 {
+  Property::Map transformMap = Property::Map();
+
+  Extents padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
+
+  bool zeroPadding = (padding == Extents());
+
+  Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(
+  Self().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
+  if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
+  {
+    std::swap(padding.start, padding.end);
+  }
+
+  // remove padding from the size to know how much is left for the visual
+  Vector2 finalSize   = size - Vector2(padding.start + padding.end, padding.top + padding.bottom);
+  Vector2 finalOffset = Vector2(padding.start, padding.top);
+
   Visual::FittingMode fittingMode = Toolkit::GetImplementation(mVisual).GetFittingMode();
 
   // Reset PIXEL_AREA after using OVER_FIT_KEEP_ASPECT_RATIO
@@ -602,6 +618,8 @@ void ImageView::ApplyFittingMode(Vector2 finalSize, Vector2 finalOffset, bool ze
       .Add(Toolkit::Visual::Transform::Property::SIZE_POLICY,
            Vector2(Toolkit::Visual::Transform::Policy::RELATIVE, Toolkit::Visual::Transform::Policy::RELATIVE));
   }
+
+  mVisual.SetTransformAndSize(transformMap, size);
 }
 
 void ImageView::CreatePlaceholderImage()
index bcdd8ba..27ee4e3 100644 (file)
@@ -201,12 +201,8 @@ private:
 
   /**
    * @brief Apply fittingMode
-   * param[in] finalSize The size for fittingMode
-   * param[in] offset The offset for fittingMode
-   * param[in] zeroPadding whether padding is zero
-   * param[in] transformMap  The map for fitting image
    */
-  void ApplyFittingMode(Vector2 finalSize, Vector2 offset, bool zeroPadding, Property::Map& transformMap);
+  void ApplyFittingMode(const Vector2& size);
 
    /**
    * @brief Create placeholder image if it set. placeholder image is shown when image view is waiting for the image to load.
@@ -254,6 +250,7 @@ private:
   bool            mImageVisualPaddingSetByTransform : 1;   ///< Flag to indicate Padding was set using a transform.
   bool            mImageViewPixelAreaSetByFittingMode : 1; ///< Flag to indicate pixel area was set by fitting Mode
   bool            mTransitionEffect :1;                    ///< Flag to indicate TransitionEffect is enabled
+  bool            mNeedLazyFittingMode:1;                  ///< Flag to indicate FittingMode will be applying lazy
 };
 
 } // namespace Internal