Adding a Property for ImageView's Transition Effect Setting 63/310863/3
authorsunghyun kim <scholb.kim@samsung.com>
Thu, 9 May 2024 05:12:06 +0000 (14:12 +0900)
committersunghyun kim <scholb.kim@samsung.com>
Fri, 17 May 2024 05:02:51 +0000 (14:02 +0900)
Adding a new property specifically designed for ImageView's transition effect settings.
With this feature, users will have greater control over how images are displayed and animated within our app.

Change-Id: Id53f5b0c9887c8a652cc0d64e715e9c0fd8df887

automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/controls/image-view/image-view-impl.h
dali-toolkit/internal/visuals/transition-data-impl.cpp
dali-toolkit/internal/visuals/transition-data-impl.h
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/public-api/controls/image-view/image-view.h

index 4eb38b890786c37333cba88c4f162e249f6461dc..efc772ddd6e8ea011463dfda557f6073e802a955 100644 (file)
@@ -5580,6 +5580,86 @@ int UtcDaliImageViewTransitionEffect04(void)
   END_TEST;
 }
 
+int UtcDaliImageViewTransitionEffect05(void)
+{
+  tet_printf("Testing user's transition effect in ImageView \n");
+  ToolkitTestApplication application;
+
+  Property::Map map;
+  map["target"]      = "image";
+  map["property"]    = "opacity";
+  map["initialValue"] = 0.2f;
+  map["targetValue"] = 1.0f;
+  map["animator"]    = Property::Map()
+                      .Add("alphaFunction", "EASE_IN_OUT")
+                      .Add("timePeriod", Property::Map().Add("delay", 0.0f).Add("duration", 2.0f))
+                      .Add("animationType", "BETWEEN");
+
+  ImageView imageView = ImageView::New();
+  imageView.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 200.0f));
+  imageView.SetProperty(ImageView::Property::ENABLE_TRANSITION_EFFECT, true);
+  imageView.SetProperty(ImageView::Property::TRANSITION_EFFECT_OPTION, map);
+  imageView.SetImage(gImage_600_RGB);
+  application.GetScene().Add(imageView);
+
+  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 UtcDaliImageViewTransitionEffect06(void)
+{
+  tet_printf("Testing user's transition effect in ImageView \n");
+  ToolkitTestApplication application;
+
+  Property::Map map;
+  map["target"]      = "image";
+  map["property"]    = "opacity";
+  map["initialValue"] = 0.2f;
+  map["targetValue"] = 1.0f;
+  map["animator"]    = Property::Map()
+                      .Add("alphaFunction", "EASE_IN_OUT")
+                      .Add("timePeriod", Property::Map().Add("delay", 0.0f).Add("duration", 2.0f))
+                      .Add("animationType", "TO");
+
+  ImageView imageView = ImageView::New();
+  imageView.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 200.0f));
+  imageView.SetProperty(ImageView::Property::ENABLE_TRANSITION_EFFECT, true);
+  imageView.SetProperty(ImageView::Property::TRANSITION_EFFECT_OPTION, map);
+  imageView.SetImage(gImage_600_RGB);
+  application.GetScene().Add(imageView);
+
+  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 5488957eb55bf7937856d2bd6938cbbfcaa5da52..4e99e5ce1220d77ca8f6b27a4220d927f0b0163b 100644 (file)
@@ -1161,7 +1161,6 @@ void Control::Impl::AddTransitions(Dali::Animation&               animation,
     TransitionData::Animator* animator = (*iter);
 
     Toolkit::Visual::Base visual = GetVisualByName(mVisuals, animator->objectName);
-
     if(visual)
     {
 #if defined(DEBUG_ENABLED)
@@ -1207,10 +1206,10 @@ void Control::Impl::AddTransitions(Dali::Animation&               animation,
             }
 
             animation.AnimateTo(Property(child, propertyIndex),
-                                animator->targetValue,
-                                animator->alphaFunction,
-                                TimePeriod(animator->timePeriodDelay,
-                                           animator->timePeriodDuration));
+                  animator->targetValue,
+                  animator->alphaFunction,
+                  TimePeriod(animator->timePeriodDelay,
+                            animator->timePeriodDuration));
           }
         }
       }
index a59ac36e87f8ccac755449397fa22c595e212d61..200aebf106f0078927ccf0155efd4db56c911430 100644 (file)
@@ -65,6 +65,7 @@ DALI_PROPERTY_REGISTRATION(Toolkit, ImageView, "image", MAP, IMAGE)
 DALI_PROPERTY_REGISTRATION(Toolkit, ImageView, "preMultipliedAlpha", BOOLEAN, PRE_MULTIPLIED_ALPHA)
 DALI_PROPERTY_REGISTRATION(Toolkit, ImageView, "placeholderImage", STRING, PLACEHOLDER_IMAGE)
 DALI_PROPERTY_REGISTRATION(Toolkit, ImageView, "enableTransitionEffect", BOOLEAN, ENABLE_TRANSITION_EFFECT)
+DALI_PROPERTY_REGISTRATION(Toolkit, ImageView, "transitionEffectOption", MAP, TRANSITION_EFFECT_OPTION)
 DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT(Toolkit, ImageView, "pixelArea", Vector4(0.f, 0.f, 1.f, 1.f), PIXEL_AREA)
 DALI_TYPE_REGISTRATION_END()
 
@@ -327,6 +328,11 @@ bool ImageView::IsTransitionEffectEnabled() const
   return mTransitionEffect;
 }
 
+void ImageView::SetTransitionEffectOption(const Property::Map& map)
+{
+  mTransitionEffectOptionMap = map;
+}
+
 Vector3 ImageView::GetNaturalSize()
 {
   if(mVisual)
@@ -695,24 +701,50 @@ void ImageView::TransitionImageWithEffect()
       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;
-
     // Transition current image
     Toolkit::Visual::Base imageVisual = DevelControl::GetVisual(*this, Toolkit::ImageView::Property::IMAGE);
     if(imageVisual)
     {
-      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);
       imageVisual.SetDepthIndex(imageVisual.GetDepthIndex() + CURRENT_VISUAL_DEPTH_INDEX);
-    }
+      if(!mTransitionEffectOptionMap.Empty())
+      {
+        // Set user's transition effect options
+        Dali::Toolkit::TransitionData transition = Toolkit::TransitionData::New(mTransitionEffectOptionMap);
+        Internal::Control::Impl& controlDataImpl = Internal::Control::Impl::Get(*this);
+        mTransitionAnimation  = controlDataImpl.CreateTransition(transition);
+        if(mTransitionAnimation)
+        {
+          mTransitionAnimation.SetEndAction(Animation::EndAction::DISCARD);
+          mTransitionAnimation.FinishedSignal().Connect(this, &ImageView::OnTransitionAnimationFinishedCallback);
+          mTransitionAnimation.Play();
+        }
+        else
+        {
+          DALI_LOG_ERROR("Create Transition Animation failed");
+        }
+      }
+      else
+      {
+        mTransitionAnimation = Animation::New(TRANSITION_EFFECT_SPEED);
+        mTransitionAnimation.SetEndAction(Animation::EndAction::DISCARD);
+        float destinationAlpha = (mTransitionTargetAlpha > LOW_OPACITY) ? mTransitionTargetAlpha : LOW_OPACITY;
+
+        // Transition current image
+        Toolkit::Visual::Base imageVisual = DevelControl::GetVisual(*this, Toolkit::ImageView::Property::IMAGE);
+        if(imageVisual)
+        {
+          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);
+          imageVisual.SetDepthIndex(imageVisual.GetDepthIndex() + CURRENT_VISUAL_DEPTH_INDEX);
+        }
 
-    // Play transition animation
-    mTransitionAnimation.FinishedSignal().Connect(this, &ImageView::OnTransitionAnimationFinishedCallback);
-    mTransitionAnimation.Play();
+        // Play transition animation
+        mTransitionAnimation.FinishedSignal().Connect(this, &ImageView::OnTransitionAnimationFinishedCallback);
+        mTransitionAnimation.Play();
+      }
+    }
   }
 }
 
@@ -842,6 +874,14 @@ void ImageView::SetProperty(BaseObject* object, Property::Index index, const Pro
         }
         break;
       }
+      case Toolkit::ImageView::Property::TRANSITION_EFFECT_OPTION:
+      {
+        Property::Map map;
+        if(value.Get(map))
+        {
+          impl.SetTransitionEffectOption(map);
+        }
+      }
     }
   }
 }
index 8cf8d3ab87e8d37dc62ed856363ce87dd8fafa41..a4cf2e704a5a9fd81db3957a106f31700ee1ef62 100644 (file)
@@ -138,6 +138,11 @@ public:
    */
   bool IsTransitionEffectEnabled() const;
 
+  /**
+   * @brief Set the transition effect option.
+  */
+  void SetTransitionEffectOption(const Property::Map& map);
+
   /**
    * @brief callback when animation for placeholder or previous visual transition effect is finished
    */
@@ -243,6 +248,7 @@ private:
   std::string     mPlaceholderUrl;                         ///< the url for the placeholder image if the image came from a PLACEHOLDER_IMAGE, empty otherwise
   Property::Map   mPropertyMap;                            ///< the Property::Map if the image came from a Property::Map, empty otherwise
   Property::Map   mShaderMap;                              ///< the Property::Map if the custom shader is set, empty otherwise
+  Property::Map   mTransitionEffectOptionMap;              ///< the Property::Map if the transition effect option is set, empty otherwise
   ImageDimensions mImageSize;                              ///< the image size
 
   Animation       mTransitionAnimation;                    ///< the animation for transition effect
index 43fe9538ed6c27e1c0629b859dc3607100616368..81a5ec7d8968898c496c11f789fcfa9afe8c3d07 100644 (file)
@@ -39,6 +39,7 @@ const char* TOKEN_TIME_PERIOD("timePeriod");
 const char* TOKEN_DURATION("duration");
 const char* TOKEN_DELAY("delay");
 const char* TOKEN_ALPHA_FUNCTION("alphaFunction");
+const char* TOKEN_ANIMATION_TYPE("animationType");
 
 DALI_ENUM_TO_STRING_TABLE_BEGIN(ALPHA_FUNCTION_BUILTIN)
   DALI_ENUM_TO_STRING_WITH_SCOPE(AlphaFunction, LINEAR)
@@ -315,6 +316,24 @@ TransitionData::Animator* TransitionData::ConvertMap(const Property::Map& map)
             }
           }
         }
+        else if(key == TOKEN_ANIMATION_TYPE)
+        {
+          if((value.GetType() == Property::STRING))
+          {
+            if(value.Get<std::string>() == "TO")
+            {
+              animator->animationType = AnimationType::TO;
+            }
+            else if(value.Get<std::string>() == "BETWEEN")
+            {
+              animator->animationType = AnimationType::BETWEEN;
+            }
+            else if(value.Get<std::string>() == "BY")
+            {
+              animator->animationType = AnimationType::BY;
+            }
+          }
+        }
       }
     }
   }
index 39c84f95393fabbce13fcbf50bf59f68f75fe3d2..127443831305b1df14f2bdf6e6f83786c577f5a4 100644 (file)
@@ -41,6 +41,13 @@ typedef IntrusivePtr<TransitionData> TransitionDataPtr;
 class TransitionData : public BaseObject
 {
 public:
+    enum class AnimationType : uint8_t
+  {
+    TO,     ///< Animating TO the given value
+    BY,     ///< Animating BY the given value
+    BETWEEN ///< Animating BETWEEN key-frames
+  };
+
   /**
    * @brief TransitionDataElement Describes one animator of an transition.
    */
@@ -51,6 +58,7 @@ public:
       alphaFunction(AlphaFunction::DEFAULT),
       timePeriodDelay(0.0f),
       timePeriodDuration(1.0f),
+      animationType(AnimationType::TO),
       animate(false)
     {
     }
@@ -62,6 +70,7 @@ public:
     Dali::AlphaFunction alphaFunction;
     float               timePeriodDelay;
     float               timePeriodDuration;
+    AnimationType       animationType;
     bool                animate;
   };
 
index 42f945d92cea0df3a22052aa34f9bf50227776cf..ed6e00cf9a7fb12d6344f75e67bedf29bc4f1045 100644 (file)
@@ -1043,7 +1043,10 @@ void Visual::Base::SetupTransition(
       {
         if(animator.initialValue.GetType() != Property::NONE)
         {
-          mImpl->mRenderer.SetProperty(index, initialValue);
+          if(animator.animationType != TransitionData::AnimationType::BETWEEN)
+          {
+            mImpl->mRenderer.SetProperty(index, initialValue);
+          }
         }
 
         if(!transition)
@@ -1051,11 +1054,26 @@ void Visual::Base::SetupTransition(
           transition = Dali::Animation::New(0.1f);
         }
 
-        transition.AnimateTo(Property(mImpl->mRenderer, index),
-                             targetValue,
-                             animator.alphaFunction,
-                             TimePeriod(animator.timePeriodDelay,
-                                        animator.timePeriodDuration));
+        if(animator.animationType == TransitionData::AnimationType::BETWEEN)
+        {
+          Dali::KeyFrames keyFrames = Dali::KeyFrames::New();
+          keyFrames.Add(0.0f, animator.initialValue);
+          keyFrames.Add(1.0f, animator.targetValue);
+          transition.AnimateBetween(Property(mImpl->mRenderer, index),keyFrames, TimePeriod(animator.timePeriodDelay, animator.timePeriodDuration));
+        }
+        else if(animator.animationType == TransitionData::AnimationType::BY)
+        {
+          // To Do
+          DALI_LOG_WARNING("AnimationType::By is not supported yet. \n");
+        }
+        else
+        {
+          transition.AnimateTo(Property(mImpl->mRenderer, index),
+                      targetValue,
+                      animator.alphaFunction,
+                      TimePeriod(animator.timePeriodDelay,
+                                animator.timePeriodDuration));
+        }
       }
     }
   }
index 6f5283253321e59d7428d4ef4da489a137634fb3..a7b986be7e370acff5c663ac233aede535020ec7 100644 (file)
@@ -126,13 +126,22 @@ public:
        * @brief name "enableTransitionEffect", type Boolean
        *
        * This effect is a crossfade effect when the image is replaced.
-       * the default duration of the crossfade effect is 1.5 seconds.
+       * the default duration of the crossfade effect is 0.3 seconds.
        * if the placeholder is enabled, the cross effect applies when the image is changed from a placeholder image to a new image.
        * if not, the cross effect applies when a new image is shown or is changed from the previous image to a new image.
        * @SINCE_2_2.24
        */
       ENABLE_TRANSITION_EFFECT,
 
+      /**
+       * @brief name "transitionEffectOption", type Map
+       *
+       * This option is for transition effect when the image is replaced.
+       * if not, the cross effect use default option.
+       * @SINCE_2_2.24
+       */
+      TRANSITION_EFFECT_OPTION,
+
       // Animatable properties
 
       /**