Merge "Use Renderer::BlendMode::USE_ACTOR_OPACITY instead to use depth write mode...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / image-view / image-view-impl.cpp
index c299886..1133211 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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/devel-api/scripting/scripting.h>
+#include <dali/public-api/math/math-utils.h>
 #include <dali/public-api/object/type-registry-helper.h>
 #include <dali/public-api/object/type-registry.h>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/devel-api/visuals/visual-actions-devel.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>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
@@ -61,8 +62,8 @@ DALI_TYPE_REGISTRATION_END()
 
 using namespace Dali;
 
-ImageView::ImageView()
-: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
+ImageView::ImageView(ControlBehaviour additionalBehaviour)
+: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT | additionalBehaviour)),
   mImageSize(),
   mImageVisualPaddingSetByTransform(false),
   mImageViewPixelAreaSetByFittingMode(false)
@@ -73,9 +74,9 @@ ImageView::~ImageView()
 {
 }
 
-Toolkit::ImageView ImageView::New()
+Toolkit::ImageView ImageView::New(ControlBehaviour additionalBehaviour)
 {
-  ImageView* impl = new ImageView();
+  ImageView* impl = new ImageView(additionalBehaviour);
 
   Toolkit::ImageView handle = Toolkit::ImageView(*impl);
 
@@ -94,10 +95,7 @@ void ImageView::OnInitialize()
   Dali::Toolkit::Control handle(GetOwner());
   handle.ResourceReadySignal().Connect(this, &ImageView::OnResourceReady);
 
-  DevelControl::SetAccessibilityConstructor(Self(), [](Dali::Actor actor) {
-    return std::unique_ptr<Dali::Accessibility::Accessible>(
-      new DevelControl::ControlAccessible(actor, Dali::Accessibility::Role::IMAGE));
-  });
+  Self().SetProperty(DevelControl::Property::ACCESSIBILITY_ROLE, Dali::Accessibility::Role::IMAGE);
 }
 
 void ImageView::SetImage(const Property::Map& map)
@@ -171,6 +169,19 @@ void ImageView::SetImage(const std::string& url, ImageDimensions size)
   // Signal that a Relayout may be needed
 }
 
+void ImageView::ClearImageVisual()
+{
+  // Clear cached properties
+  mPropertyMap.Clear();
+  mUrl.clear();
+
+  // Unregister the exsiting visual
+  DevelControl::UnregisterVisual(*this, Toolkit::ImageView::Property::IMAGE);
+
+  // Trigger a size negotiation request that may be needed when unregistering a visual.
+  RelayoutRequest();
+}
+
 void ImageView::EnablePreMultipliedAlpha(bool preMultipled)
 {
   if(mVisual)
@@ -334,8 +345,8 @@ void ImageView::SetTransformMapForFittingMode(Vector2 finalSize, Vector2 natural
       auto availableVisualSize = finalSize;
 
       // scale to fit the padded area
-      finalSize = naturalSize * std::min((naturalSize.width ? (availableVisualSize.width / naturalSize.width) : 0),
-                                         (naturalSize.height ? (availableVisualSize.height / naturalSize.height) : 0));
+      finalSize = naturalSize * std::min((!Dali::EqualsZero(naturalSize.width) ? (availableVisualSize.width / naturalSize.width) : 0),
+                                         (!Dali::EqualsZero(naturalSize.height) ? (availableVisualSize.height / naturalSize.height) : 0));
 
       // calculate final offset within the padded area
       finalOffset += (availableVisualSize - finalSize) * .5f;
@@ -349,8 +360,8 @@ void ImageView::SetTransformMapForFittingMode(Vector2 finalSize, Vector2 natural
     {
       mImageViewPixelAreaSetByFittingMode = true;
       auto availableVisualSize            = finalSize;
-      finalSize                           = naturalSize * std::max((naturalSize.width ? (availableVisualSize.width / naturalSize.width) : 0),
-                                         (naturalSize.height ? (availableVisualSize.height / naturalSize.height) : 0));
+      finalSize                           = naturalSize * std::max((!Dali::EqualsZero(naturalSize.width) ? (availableVisualSize.width / naturalSize.width) : 0.0f),
+                                         (!Dali::EqualsZero(naturalSize.height) ? (availableVisualSize.height / naturalSize.height) : 0.0f));
 
       auto originalOffset = finalOffset;
       finalOffset += (availableVisualSize - finalSize) * .5f;
@@ -376,8 +387,8 @@ void ImageView::SetTransformMapForFittingMode(Vector2 finalSize, Vector2 natural
       }
       else
       {
-        finalSize = naturalSize * std::min((naturalSize.width ? (availableVisualSize.width / naturalSize.width) : 0),
-                                           (naturalSize.height ? (availableVisualSize.height / naturalSize.height) : 0));
+        finalSize = naturalSize * std::min((!Dali::EqualsZero(naturalSize.width) ? (availableVisualSize.width / naturalSize.width) : 0.0f),
+                                           (!Dali::EqualsZero(naturalSize.height) ? (availableVisualSize.height / naturalSize.height) : 0.0f));
       }
 
       finalOffset += (availableVisualSize - finalSize) * .5f;
@@ -477,33 +488,46 @@ void ImageView::SetProperty(BaseObject* object, Property::Index index, const Pro
         else
         {
           map = value.GetMap();
-          if(map)
+          if(DALI_LIKELY(map))
           {
-            Property::Value* shaderValue = map->Find(Toolkit::Visual::Property::SHADER, CUSTOM_SHADER);
-            // set image only if property map contains image information other than custom shader
-            if(map->Count() > 1u || !shaderValue)
+            // the property map is emtpy map. Unregister visual.
+            if(DALI_UNLIKELY(map->Count() == 0u))
             {
-              impl.SetImage(*map);
+              impl.ClearImageVisual();
             }
-            // the property map contains only the custom shader
-            else if((map->Count() == 1u) && (shaderValue))
+            else
             {
-              Property::Map* shaderMap = shaderValue->GetMap();
-              if(shaderMap)
+              Property::Value* shaderValue = map->Find(Toolkit::Visual::Property::SHADER, CUSTOM_SHADER);
+              // set image only if property map contains image information other than custom shader
+              if(map->Count() > 1u || !shaderValue)
               {
-                impl.mShaderMap = *shaderMap;
-
-                if(!impl.mUrl.empty())
-                {
-                  impl.SetImage(impl.mUrl, impl.mImageSize);
-                }
-                else if(!impl.mPropertyMap.Empty())
+                impl.SetImage(*map);
+              }
+              // the property map contains only the custom shader
+              else if((map->Count() == 1u) && (shaderValue))
+              {
+                Property::Map* shaderMap = shaderValue->GetMap();
+                if(shaderMap)
                 {
-                  impl.SetImage(impl.mPropertyMap);
+                  impl.mShaderMap = *shaderMap;
+
+                  if(!impl.mUrl.empty())
+                  {
+                    impl.SetImage(impl.mUrl, impl.mImageSize);
+                  }
+                  else if(!impl.mPropertyMap.Empty())
+                  {
+                    impl.SetImage(impl.mPropertyMap);
+                  }
                 }
               }
             }
           }
+          else
+          {
+            // invalid property value comes. Unregister visual.
+            impl.ClearImageVisual();
+          }
         }
         break;
       }