From 2859eb1e20c4d426f99ac5feb3dd598324c553f1 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 16 Dec 2024 09:50:58 +0100 Subject: [PATCH] Remove draw_rect() shortcut in ItemRenderer trait As discussed during API Review, reducing the API surface. --- internal/core/item_rendering.rs | 28 ++++++++++++++-------- internal/core/window.rs | 12 ++++++++++ internal/renderers/femtovg/itemrenderer.rs | 12 ++++------ internal/renderers/femtovg/lib.rs | 10 ++++++-- internal/renderers/skia/lib.rs | 10 ++++++-- 5 files changed, 50 insertions(+), 22 deletions(-) diff --git a/internal/core/item_rendering.rs b/internal/core/item_rendering.rs index bc480884c6c..4ffe7275546 100644 --- a/internal/core/item_rendering.rs +++ b/internal/core/item_rendering.rs @@ -292,6 +292,24 @@ pub trait RenderBorderRectangle { fn border_color(self: Pin<&Self>) -> Brush; } +impl RenderBorderRectangle for Brush { + fn background(self: Pin<&Self>) -> Brush { + self.get_ref().clone() + } + + fn border_width(self: Pin<&Self>) -> LogicalLength { + Default::default() + } + + fn border_radius(self: Pin<&Self>) -> LogicalBorderRadius { + Default::default() + } + + fn border_color(self: Pin<&Self>) -> Brush { + Default::default() + } +} + /// Trait for an item that represents an Image towards the renderer #[allow(missing_docs)] pub trait RenderImage { @@ -451,12 +469,6 @@ pub trait ItemRenderer { fn draw_image_direct(&mut self, image: crate::graphics::Image); - /// Fills a rectangle at (0,0) with the given size. This is used for example by the Skia renderer to - /// handle window backgrounds with a brush (gradient). - fn draw_rect(&mut self, _size: LogicalSize, _brush: Brush) { - unimplemented!() - } - /// This is called before it is being rendered (before the draw_* function). /// Returns /// - if the item needs to be drawn (false means it is clipped or doesn't need to be drawn) @@ -910,10 +922,6 @@ impl<'a, T: ItemRenderer> ItemRenderer for PartialRenderer<'a, T> { self.actual_renderer.draw_image_direct(image) } - fn draw_rect(&mut self, size: LogicalSize, brush: Brush) { - self.actual_renderer.draw_rect(size, brush); - } - fn window(&self) -> &crate::window::WindowInner { self.actual_renderer.window() } diff --git a/internal/core/window.rs b/internal/core/window.rs index 72fe4255b5c..ada66de77a8 100644 --- a/internal/core/window.rs +++ b/internal/core/window.rs @@ -1216,6 +1216,18 @@ impl WindowInner { }) } + /// Returns the window item that is the first item in the component. + pub fn window_item_rc(&self) -> Option { + self.try_component().and_then(|component_rc| { + let window_item_rc = ItemRc::new(component_rc, 0); + if window_item_rc.downcast::().is_some() { + Some(window_item_rc) + } else { + None + } + }) + } + /// Sets the size of the window item. This method is typically called in response to receiving a /// window resize event from the windowing system. pub(crate) fn set_window_item_geometry(&self, size: crate::lengths::LogicalSize) { diff --git a/internal/renderers/femtovg/itemrenderer.rs b/internal/renderers/femtovg/itemrenderer.rs index 19cc3f66700..ba6255991b6 100644 --- a/internal/renderers/femtovg/itemrenderer.rs +++ b/internal/renderers/femtovg/itemrenderer.rs @@ -176,9 +176,10 @@ impl<'a> GLItemRenderer<'a> { pub fn global_alpha_transparent(&self) -> bool { self.state.last().unwrap().global_alpha == 0.0 } +} - /// Draws a `Rectangle` using the `GLItemRenderer`. - pub fn draw_rect(&mut self, size: LogicalSize, brush: Brush) { +impl<'a> ItemRenderer for GLItemRenderer<'a> { + fn draw_rectangle(&mut self, rect: Pin<&items::Rectangle>, _: &ItemRc, size: LogicalSize) { let geometry = PhysicalRect::from(size * self.scale_factor); if geometry.is_empty() { return; @@ -186,6 +187,7 @@ impl<'a> GLItemRenderer<'a> { if self.global_alpha_transparent() { return; } + let brush = rect.background(); // TODO: cache path in item to avoid re-tesselation let path = rect_to_path(geometry); let paint = match self.brush_to_paint(brush, &path) { @@ -197,12 +199,6 @@ impl<'a> GLItemRenderer<'a> { .with_anti_alias(false); self.canvas.borrow_mut().fill_path(&path, &paint); } -} - -impl<'a> ItemRenderer for GLItemRenderer<'a> { - fn draw_rectangle(&mut self, rect: Pin<&items::Rectangle>, _: &ItemRc, size: LogicalSize) { - self.draw_rect(size, rect.background()); - } fn draw_border_rectangle( &mut self, diff --git a/internal/renderers/femtovg/lib.rs b/internal/renderers/femtovg/lib.rs index c474021f981..af421a12e22 100644 --- a/internal/renderers/femtovg/lib.rs +++ b/internal/renderers/femtovg/lib.rs @@ -264,11 +264,17 @@ impl FemtoVGRenderer { match window_background_brush { Some(Brush::SolidColor(..)) | None => {} Some(brush) => { - item_renderer.draw_rect( + let window_item_rc = window_inner.window_item_rc().unwrap(); + let window_item = + window_item_rc.downcast::().unwrap(); + let pinned_brush = std::pin::pin!(brush); + item_renderer.draw_border_rectangle( + pinned_brush, + &window_item_rc, i_slint_core::lengths::logical_size_from_api( window.size().to_logical(window_inner.scale_factor()), ), - brush, + &window_item.cached_rendering_data, ); } } diff --git a/internal/renderers/skia/lib.rs b/internal/renderers/skia/lib.rs index 5bde28c0e6b..6dba12f081a 100644 --- a/internal/renderers/skia/lib.rs +++ b/internal/renderers/skia/lib.rs @@ -449,11 +449,17 @@ impl SkiaRenderer { } None => {} Some(brush @ _) => { - item_renderer.draw_rect( + let window_item_rc = window_inner.window_item_rc().unwrap(); + let window_item = + window_item_rc.downcast::().unwrap(); + let pinned_brush = std::pin::pin!(brush); + item_renderer.draw_border_rectangle( + pinned_brush, + &window_item_rc, i_slint_core::lengths::logical_size_from_api( window.size().to_logical(window_inner.scale_factor()), ), - brush, + &window_item.cached_rendering_data, ); } }