Apply CornerRadius to WidgetView 75/302475/8 accepted/tizen/7.0/unified/20231226.011007
authorsunghyun kim <scholb.kim@samsung.com>
Thu, 7 Dec 2023 10:12:48 +0000 (19:12 +0900)
committersunghyun kim <scholb.kim@samsung.com>
Wed, 20 Dec 2023 08:43:10 +0000 (17:43 +0900)
The CornerRadius function previously supported in View has been modified to also apply to WidgetView.
For this behavior, WidgetView has an internal visual and its structure is changed.
Now, WidgetView no longer generates shaders and rendering directly.

Change-Id: I1fa45547761f8e859fb59bf1ee68463a0038473e

widget_viewer_dali/internal/widget_view/widget_view_impl.cpp
widget_viewer_dali/internal/widget_view/widget_view_impl.h

index 1f25c618056b58597e3a546307ec325656da6b20..3ad653d2bf9880384c066ae30cb5a8d21618a8a3 100644 (file)
 #include <dali/public-api/render-tasks/render-task-list.h>
 #include <dali/public-api/render-tasks/render-task.h>
 #include <dali/public-api/actors/camera-actor.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
+#include <dali-toolkit/public-api/image-loader/image.h>
+#include <dali-toolkit/public-api/image-loader/image-url.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
+#include <dali-toolkit/public-api/visuals/image-visual-properties.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali/integration-api/debug.h>
@@ -241,7 +247,10 @@ WidgetView::WidgetView()
   mPaused( false ),
   mPausedManually( false ),
   mWindowVisible( true ),
-  mPreviewEnable( true )
+  mPreviewEnable( true ),
+  mIsReadyToRender(false),
+  mCornerRadius(Vector4::ZERO),
+  mCornerRadiusPolicy(1.0f)
 {
 }
 
@@ -267,7 +276,10 @@ WidgetView::WidgetView( const std::string& widgetId, const std::string& contentI
   mPaused( false ),
   mPausedManually( false ),
   mWindowVisible( true ),
-  mPreviewEnable( true )
+  mPreviewEnable( true ),
+  mIsReadyToRender(false),
+  mCornerRadius(Vector4::ZERO),
+  mCornerRadiusPolicy(1.0f)
 {
 }
 
@@ -526,22 +538,46 @@ bool WidgetView::IsPermanentDelete()
 
 void WidgetView::CreateWidgetRenderer()
 {
-  Dali::Any source;
-  mImageSource = Dali::NativeImageSource::New( source );
-  Dali::Texture texture = Dali::Texture::New( *mImageSource );
 
-  Dali::Geometry geometry = CreateQuadGeometry();
-  Dali::Shader shader = CreateShader();
-  mRenderer = Dali::Renderer::New( geometry, shader );
+  // Check CornerRadius is enabled
+  Toolkit::Visual::Base widgetVisual = Dali::Toolkit::DevelControl::GetVisual(*this,  Dali::WidgetView::WidgetView::Property::WIDGET_ID);
+  if(widgetVisual)
+  {
+    Property::Map widgetMap;
+    widgetVisual.CreatePropertyMap(widgetMap);
+    Property::Value* cornerRadiusValue =  widgetMap.Find(Dali::Toolkit::DevelVisual::Property::CORNER_RADIUS);
+    mCornerRadius = cornerRadiusValue->Get<Vector4>();
+    Property::Value* cornerRadiusValuePolicy =  widgetMap.Find(Dali::Toolkit::DevelVisual::Property::CORNER_RADIUS_POLICY);
+    mCornerRadiusPolicy = cornerRadiusValuePolicy->Get<int>();
+    DALI_LOG_RELEASE_INFO("Create widgetVisual for CornerRadius corner(%f,%f,%f,%f), policy:%f \n", mCornerRadius.x, mCornerRadius.y, mCornerRadius.z, mCornerRadius.w, mCornerRadiusPolicy);
+  }
+  else
+  {
+    DALI_LOG_ERROR("widgetVisual is null, we can't use corner radius  %d", Dali::WidgetView::WidgetView::Property::WIDGET_ID);
+  }
 
-  Dali::TextureSet textureSet = Dali::TextureSet::New();
-  textureSet.SetTexture( 0u, texture );
-  mRenderer.SetTextures( textureSet );
+  // Create Renderer if cornderRadius is disabled.
+  if(mCornerRadius == Vector4::ZERO)
+  {
+    // We don't need WidgetVisual anymore, so we can delete it.
+    Dali::Toolkit::DevelControl::UnregisterVisual(*this, Dali::WidgetView::WidgetView::Property::WIDGET_ID);
 
-  //EFL app should be pre multiplied image.
-  mRenderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true );
+    Dali::Any source;
+    mImageSource = Dali::NativeImageSource::New( source );
+    Dali::Texture texture = Dali::Texture::New( *mImageSource );
+    Dali::Geometry geometry = CreateQuadGeometry();
+    Dali::Shader shader = CreateShader();
+    mRenderer = Dali::Renderer::New( geometry, shader );
 
-  Self().AddRenderer( mRenderer );
+    Dali::TextureSet textureSet = Dali::TextureSet::New();
+    textureSet.SetTexture( 0u, texture );
+    mRenderer.SetTextures( textureSet );
+
+    //EFL app should be pre multiplied image.
+    mRenderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true );
+
+    Self().AddRenderer( mRenderer );
+  }
 
   // Disable preview and text
   ShowLoadingState( false );
@@ -550,19 +586,27 @@ void WidgetView::CreateWidgetRenderer()
   Dali::WidgetView::WidgetView handle( GetOwner() );
   mWidgetAddedSignal.Emit( handle );
 
+  // Renderer is created by WidgetView or widgetVisual
+  mIsReadyToRender = true;
+
   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::CreateWidgetRenderer: Widget image is added. [%p]\n", this );
 }
 
 void WidgetView::RemoveWidgetRenderer()
 {
-  if( mRenderer )
+  if(mIsReadyToRender)
   {
-    Self().RemoveRenderer( mRenderer );
+    if(mRenderer)
+    {
+      Self().RemoveRenderer( mRenderer );
+    }
 
     ShowRetryState( true );
 
     Dali::WidgetView::WidgetView handle( GetOwner() );
     mWidgetDeletedSignal.Emit( handle );
+
+    mIsReadyToRender = false;
   }
 
   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::RemoveWidgetRenderer: Widget image is removed. [%p]\n", this );
@@ -1050,6 +1094,25 @@ void WidgetView::OnInitialize()
   mStateTextActor.Add( mRetryText );
   mRetryText.SetProperty( Actor::Property::VISIBLE, false );
 
+  // Create WidgetVisual for WidgetView
+  Property::Map propertyMap;
+  Dali::Any source;
+  mImageSource = Dali::NativeImageSource::New(source);
+  Dali::Toolkit::ImageUrl nativeImageUrl = Dali::Toolkit::Image::GenerateUrl(mImageSource);
+  propertyMap.Insert(Dali::Toolkit::Visual::Property::TYPE, Dali::Toolkit::Visual::IMAGE);
+  propertyMap.Insert(Dali::Toolkit::ImageVisual::Property::URL, nativeImageUrl.GetUrl());
+  Toolkit::Visual::Base widgetVisual = Toolkit::VisualFactory::Get().CreateVisual(propertyMap);
+  if(widgetVisual)
+  {
+    DALI_LOG_RELEASE_INFO("Create WidgetVisual for CornerRadius corner(%f,%f,%f,%f), policy:%f \n", mCornerRadius.x, mCornerRadius.y, mCornerRadius.z, mCornerRadius.w, mCornerRadiusPolicy);
+    Dali::Toolkit::DevelControl::RegisterVisual(*this, Dali::WidgetView::WidgetView::Property::WIDGET_ID, widgetVisual);
+  }
+  else
+  {
+    DALI_LOG_ERROR("fail to create WidgetVisual for CornerRadius corner(%f,%f,%f,%f), policy:%f \n", mCornerRadius.x, mCornerRadius.y, mCornerRadius.z, mCornerRadius.w, mCornerRadiusPolicy);
+    Dali::Toolkit::DevelControl::UnregisterVisual(*this, Dali::WidgetView::WidgetView::Property::WIDGET_ID);
+  }
+
   // launch widget
   LaunchWidget();
   self.TouchedSignal().Connect( this, &WidgetView::OnTouch );
@@ -1172,24 +1235,44 @@ void WidgetView::OnSizeSet( const Vector3& targetSize )
 {
 }
 
-bool WidgetView::IsWidgetRenderer()
+bool WidgetView::IsReadyToRender()
 {
-  return ( mRenderer )? true: false;
+  return mIsReadyToRender;
 }
 
 void WidgetView::UpdateImageSource( tbm_surface_h source )
 {
   mImageSource = Dali::NativeImageSource::New( source );
-  Dali::Texture texture = Dali::Texture::New( *mImageSource );
 
+  // Create NativeImageSource using tbm_surface
   if( mRenderer )
   {
+    Dali::Texture texture = Dali::Texture::New(*mImageSource);
     Dali::TextureSet textureSet = mRenderer.GetTextures();
     textureSet.SetTexture( 0u, texture );
     mRenderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true );
   }
+  else
+  {
+    // Create WidgetVisual for new tbm surface
+    Dali::Toolkit::ImageUrl nativeImageUrl = Dali::Toolkit::Image::GenerateUrl(mImageSource);
+
+    Property::Map propertyMap;
+    propertyMap.Insert(Dali::Toolkit::Visual::Property::TYPE, Dali::Toolkit::Visual::IMAGE);
+    propertyMap.Insert(Dali::Toolkit::ImageVisual::Property::URL, nativeImageUrl.GetUrl());
+    propertyMap.Insert(Dali::Toolkit::DevelVisual::Property::CORNER_RADIUS, mCornerRadius);
+    propertyMap.Insert(Dali::Toolkit::DevelVisual::Property::CORNER_RADIUS_POLICY, mCornerRadiusPolicy);
+    Dali::Toolkit::Visual::Base widgetVisual= Toolkit::VisualFactory::Get().CreateVisual(propertyMap);
+    if(widgetVisual)
+    {
+      Dali::Toolkit::DevelControl::RegisterVisual(*this, Dali::WidgetView::WidgetView::Property::WIDGET_ID, widgetVisual);
+    }
+    else
+    {
+      Dali::Toolkit::DevelControl::UnregisterVisual(*this, Dali::WidgetView::WidgetView::Property::WIDGET_ID);
+    }
+  }
 
-  // Register a callback using WidgetBuffer class
   auto widgetBuffer = new WidgetBuffer(mBuffer,*this,mImageSource);
   Dali::DevelNativeImageSource::SetResourceDestructionCallback(*mImageSource, new EventThreadCallback(MakeCallback(widgetBuffer, &WidgetBuffer::OnResourceDestruction)));
   mBufferContainer.push_back(std::unique_ptr<WidgetBuffer>(widgetBuffer));
@@ -1708,7 +1791,7 @@ bool WidgetView::TouchEvent( const Dali::TouchEvent& event )
 
 void WidgetView::UpdateBuffer( struct tizen_remote_surface *surface, struct wl_buffer *buffer, int32_t fd)
 {
-  if( !IsWidgetRenderer() )
+  if( !IsReadyToRender() )
   {
     tizen_remote_surface_transfer_visibility( surface, TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_VISIBLE);
 
index 3dba52bf6aed326a4c0c4d9934c5a8b5d74b47dc..621b8ed8c25d13c33e6318e7cb7d722277e1cbe4 100644 (file)
@@ -241,9 +241,9 @@ public: // Internal API
   bool IsPermanentDelete();
 
   /**
-   * @brief Checks Widget Renderer exist
+   * @brief Checks Widget is ready to render
    */
-  bool IsWidgetRenderer();
+  bool IsReadyToRender();
 
   /**
    * @brief Updates image source when buffer is updated
@@ -542,9 +542,14 @@ private:
   bool mPaused;                              ///< Check whether widget is paused or not
   bool mPausedManually;                      ///< Check whether widget is paused or not by application
   bool mWindowVisible;                       ///< Check whether window is visible or not
-  bool mPreviewEnable;                      ///< Check whether preview is enable or not
+  bool mPreviewEnable;                       ///< Check whether preview is enable or not
+  bool mIsReadyToRender;                     ///< Check whether widget is ready to render or not
+
   Dali::Property::Map mEffectPropertyMap;    ///< Shader for effect
 
+  Vector4 mCornerRadius;                     /// < Corner radius
+  float   mCornerRadiusPolicy;               /// < Corner radius policy
+
   // Notification for property change confirmation
   Dali::PropertyNotification mPositionUpdateNotification;
   Dali::PropertyNotification mSizeUpdateNotification;