Fix bug in transition effect 11/308711/11
authorsunghyun kim <scholb.kim@samsung.com>
Wed, 27 Mar 2024 07:33:59 +0000 (16:33 +0900)
committersunghyun kim <scholb.kim@samsung.com>
Mon, 8 Apr 2024 00:39:32 +0000 (09:39 +0900)
Image view provides transitoin effect when image is replaced.
but this function has some bugs, so i fixed them.

Below is the issue list
1.Sometimes, some of view play transition effect when image is not replaced.
2.Sometimes, Don't play transition effect when image is replaced.
3.Focus items show transition effect even if resource is not changed.

Change-Id: I610ef472c3046177c5e3f76dd4d854497805168c

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 942fb76..4eb38b8 100644 (file)
@@ -5520,6 +5520,66 @@ int UtcDaliImageViewTransitionEffect03(void)
   END_TEST;
 }
 
+int UtcDaliImageViewTransitionEffect04(void)
+{
+  tet_infoline("Test transitoin effect operation when image is changed quickly ");
+
+  ToolkitTestApplication application;
+  Property::Map          map;
+
+  ImageView imageView = ImageView::New();
+  imageView.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 200.0f));
+  imageView.SetProperty(ImageView::Property::ENABLE_TRANSITION_EFFECT, true);
+  imageView.SetProperty(Toolkit::ImageView::Property::PLACEHOLDER_IMAGE, gImage_34_RGBA);
+  imageView.SetImage("");
+  application.GetScene().Add(imageView);
+
+  ImageView imageView2 = ImageView::New();
+  imageView2.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 200.0f));
+  imageView2.SetProperty(ImageView::Property::ENABLE_TRANSITION_EFFECT, true);
+  imageView2.SetProperty(Toolkit::ImageView::Property::PLACEHOLDER_IMAGE, gImage_34_RGBA);
+  imageView2.SetImage("");
+  application.GetScene().Add(imageView2);
+  application.SendNotification();
+  application.Render();
+
+  //PLACEHOLDER_IMAGE is not call WaitForEventThreadTrigger because it is not shown url is null.
+  //DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+  imageView.SetImage(gImage_600_RGB);
+  imageView.SetProperty(ImageView::Property::PLACEHOLDER_IMAGE, gImage_34_RGBA);
+  imageView2.SetImage(TEST_IMAGE_1);
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+
+  imageView.SetImage(TEST_IMAGE_1);
+  imageView2.SetImage(gImage_600_RGB);
+  application.SendNotification();
+  application.Render(3000);
+
+  imageView.SetImage("");
+  application.SendNotification();
+  application.Render();
+
+  imageView.SetImage(TEST_IMAGE_2);
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+  Property::Value value;
+  value = imageView.GetProperty(ImageView::Property::ENABLE_TRANSITION_EFFECT);
+  bool transition;
+  DALI_TEST_CHECK(value.Get(transition));
+  DALI_TEST_CHECK(transition == true);
+
+  // Clear all cached
+  imageView.Unparent();
+  imageView.Reset();
+
+  END_TEST;
+}
+
 int UtcDaliImageViewImageLoadFailureAndReload01(void)
 {
   tet_infoline("Try to load invalid image first, and then reload after that image valid.");
index 5c522ba..7f11261 100644 (file)
@@ -49,6 +49,10 @@ 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;
+
 BaseHandle Create()
 {
   return Toolkit::ImageView::New();
@@ -74,7 +78,8 @@ ImageView::ImageView(ControlBehaviour additionalBehaviour)
   mImageVisualPaddingSetByTransform(false),
   mImageViewPixelAreaSetByFittingMode(false),
   mTransitionEffect(false),
-  mNeedLazyFittingMode(false)
+  mNeedLazyFittingMode(false),
+  mImageReplaced(false)
 {
 }
 
@@ -117,7 +122,8 @@ void ImageView::SetImage(const Property::Map& map)
       {
         if(mTransitionAnimation.GetState() == Animation::PLAYING)
         {
-          mTransitionAnimation.Stop();
+          // Hide placeholder
+          HidePlaceholderImage();
           ClearTransitionAnimation();
         }
       }
@@ -134,6 +140,8 @@ void ImageView::SetImage(const Property::Map& map)
   mPropertyMap = map;
   mUrl.clear();
 
+  mImageReplaced = true;
+
   // keep alpha for transition effect
   if(mTransitionEffect)
   {
@@ -175,7 +183,6 @@ void ImageView::SetImage(const Property::Map& map)
     // Trigger a size negotiation request that may be needed when unregistering a visual.
     RelayoutRequest();
   }
-
   // Signal that a Relayout may be needed
 }
 
@@ -190,7 +197,7 @@ void ImageView::SetImage(const std::string& url, ImageDimensions size)
       {
         if(mTransitionAnimation.GetState() == Animation::PLAYING)
         {
-          mTransitionAnimation.Stop();
+          HidePlaceholderImage();
           ClearTransitionAnimation();
         }
       }
@@ -203,11 +210,15 @@ 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;
   mPropertyMap.Clear();
 
+  mImageReplaced = true;
+
   if(!mVisual)
   {
     ShowPlaceholderImage();
@@ -238,7 +249,6 @@ void ImageView::SetImage(const std::string& url, ImageDimensions size)
     // Trigger a size negotiation request that may be needed when unregistering a visual.
     RelayoutRequest();
   }
-
   // Signal that a Relayout may be needed
 }
 
@@ -390,6 +400,12 @@ void ImageView::OnRelayout(const Vector2& size, RelayoutContainer& container)
     {
       visual.SetTransformAndSize(Property::Map(), size);
     }
+
+    if(!mTransitionEffect)
+    {
+      // we don't need placeholder anymore because visual is replaced. so hide placeholder.
+      HidePlaceholderImage();
+    }
   }
 }
 
@@ -445,15 +461,6 @@ void ImageView::OnResourceReady(Toolkit::Control control)
       // when placeholder is disabled or ready placeholder and image, we need to transition effect
       TransitionImageWithEffect();
     }
-    else
-    {
-      ClearTransitionAnimation();
-    }
-  }
-  else
-  {
-    // we don't need placeholder anymore because visual is replaced. so hide placeholder.
-    HidePlaceholderImage();
   }
 
   // Visual ready so update visual attached to this ImageView, following call to RelayoutRequest will use this visual.
@@ -635,6 +642,7 @@ void ImageView::CreatePlaceholderImage()
   if(mPlaceholderVisual)
   {
     mPlaceholderVisual.SetName("placeholder");
+    mPlaceholderVisual.SetDepthIndex(mPlaceholderVisual.GetDepthIndex() + PLACEHOLDER_DEPTH_INDEX);
   }
   else
   {
@@ -671,6 +679,23 @@ void ImageView::TransitionImageWithEffect()
 
   if(handle)
   {
+    if(!mImageReplaced)
+    {
+      // If the image is not replaced, the transition effect is not required.
+      return;
+    }
+
+    if(mTransitionAnimation)
+    {
+      ClearTransitionAnimation();
+    }
+
+    // Control visual's depth for transition effect
+    if(mPreviousVisual)
+    {
+      mPreviousVisual.SetDepthIndex(mPreviousVisual.GetDepthIndex() + PREVIOUS_VISUAL_DEPTH_INDEX);
+    }
+
     mTransitionAnimation = Animation::New(TRANSITION_EFFECT_SPEED);
     mTransitionAnimation.SetEndAction(Animation::EndAction::DISCARD);
     float destinationAlpha = (mTransitionTargetAlpha > LOW_OPACITY) ? mTransitionTargetAlpha : LOW_OPACITY;
@@ -683,6 +708,7 @@ void ImageView::TransitionImageWithEffect()
       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);
+      imageVisual.SetDepthIndex(imageVisual.GetDepthIndex() + CURRENT_VISUAL_DEPTH_INDEX);
     }
 
     // Play transition animation
@@ -693,9 +719,6 @@ void ImageView::TransitionImageWithEffect()
 
 void ImageView::ClearTransitionAnimation()
 {
-  // Hide placeholder
-  HidePlaceholderImage();
-
   // Clear PreviousVisual
   if(mPreviousVisual)
   {
@@ -708,8 +731,16 @@ void ImageView::ClearTransitionAnimation()
 
   if(mTransitionAnimation)
   {
+    if(mTransitionAnimation.GetState() == Animation::PLAYING)
+    {
+      mTransitionAnimation.Stop();
+    }
     mTransitionAnimation.FinishedSignal().Disconnect(this, &ImageView::OnTransitionAnimationFinishedCallback);
     mTransitionAnimation.Clear();
+    mTransitionAnimation.Reset();
+
+    // After transition effect is cleared, we don't need transition effect until image is replaced.
+    mImageReplaced = false;
   }
 }
 
@@ -871,6 +902,8 @@ Property::Value ImageView::GetProperty(BaseObject* object, Property::Index prope
 
 void ImageView::OnTransitionAnimationFinishedCallback(Animation& animation)
 {
+  // Hide placeholder
+  HidePlaceholderImage();
   ClearTransitionAnimation();
 }
 
index 27ee4e3..8cf8d3a 100644 (file)
@@ -251,6 +251,7 @@ private:
   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
+  bool            mImageReplaced:1;                        ///< Flag to indicate image is replaced
 };
 
 } // namespace Internal