From 48f0397b8583a7e18755870c1757845ad561e73e Mon Sep 17 00:00:00 2001 From: sunghyun kim Date: Wed, 27 Mar 2024 16:33:59 +0900 Subject: [PATCH] Fix bug in transition effect 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 --- .../src/dali-toolkit/utc-Dali-ImageView.cpp | 60 +++++++++++++++++++ .../controls/image-view/image-view-impl.cpp | 67 ++++++++++++++++------ .../internal/controls/image-view/image-view-impl.h | 1 + 3 files changed, 111 insertions(+), 17 deletions(-) diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp index 942fb76..4eb38b8 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp @@ -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."); diff --git a/dali-toolkit/internal/controls/image-view/image-view-impl.cpp b/dali-toolkit/internal/controls/image-view/image-view-impl.cpp index 5c522ba..7f11261 100644 --- a/dali-toolkit/internal/controls/image-view/image-view-impl.cpp +++ b/dali-toolkit/internal/controls/image-view/image-view-impl.cpp @@ -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(); } diff --git a/dali-toolkit/internal/controls/image-view/image-view-impl.h b/dali-toolkit/internal/controls/image-view/image-view-impl.h index 27ee4e3..8cf8d3a 100644 --- a/dali-toolkit/internal/controls/image-view/image-view-impl.h +++ b/dali-toolkit/internal/controls/image-view/image-view-impl.h @@ -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 -- 2.7.4