From b972ebca8f8c23d2df1b45bb26038789766a5a65 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 21 Mar 2024 23:30:36 +0100 Subject: Restore `canvas::Program` API --- examples/arc/src/main.rs | 10 ++++++---- examples/bezier_tool/src/main.rs | 20 +++++++++++--------- examples/clock/src/main.rs | 10 ++++++---- examples/color_palette/src/main.rs | 8 ++++---- examples/game_of_life/src/main.rs | 12 +++++++----- examples/layout/src/main.rs | 6 +++--- examples/multitouch/src/main.rs | 8 ++++---- examples/sierpinski_triangle/src/main.rs | 8 ++++---- examples/solar_system/src/main.rs | 8 ++++---- examples/vectorial_text/src/main.rs | 6 +++--- widget/src/canvas.rs | 17 +++++++++++++---- widget/src/canvas/program.rs | 11 ++++++----- 12 files changed, 71 insertions(+), 53 deletions(-) diff --git a/examples/arc/src/main.rs b/examples/arc/src/main.rs index a7893efa..0aba82a9 100644 --- a/examples/arc/src/main.rs +++ b/examples/arc/src/main.rs @@ -1,7 +1,9 @@ use std::{f32::consts::PI, time::Instant}; use iced::mouse; -use iced::widget::canvas::{self, stroke, Cache, Canvas, Frame, Path, Stroke}; +use iced::widget::canvas::{ + self, stroke, Cache, Canvas, Frame, Geometry, Path, Stroke, +}; use iced::{Element, Length, Point, Rectangle, Renderer, Subscription, Theme}; pub fn main() -> iced::Result { @@ -55,11 +57,11 @@ impl canvas::Program for Arc { fn draw( &self, _state: &Self::State, - renderer: &mut Renderer, + renderer: &Renderer, theme: &Theme, bounds: Rectangle, _cursor: mouse::Cursor, - ) { + ) -> Vec { let geometry = self.cache.draw(renderer, bounds.size(), |frame| { let palette = theme.palette(); @@ -102,6 +104,6 @@ impl canvas::Program for Arc { ); }); - renderer.draw_geometry([geometry]); + vec![geometry] } } diff --git a/examples/bezier_tool/src/main.rs b/examples/bezier_tool/src/main.rs index e51f2a31..31d1e29c 100644 --- a/examples/bezier_tool/src/main.rs +++ b/examples/bezier_tool/src/main.rs @@ -52,7 +52,9 @@ impl Example { mod bezier { use iced::mouse; use iced::widget::canvas::event::{self, Event}; - use iced::widget::canvas::{self, frame, Canvas, Frame, Path, Stroke}; + use iced::widget::canvas::{ + self, frame, Canvas, Frame, Geometry, Path, Stroke, + }; use iced::{Element, Length, Point, Rectangle, Renderer, Theme}; #[derive(Default)] @@ -138,11 +140,11 @@ mod bezier { fn draw( &self, state: &Self::State, - renderer: &mut Renderer, + renderer: &Renderer, _theme: &Theme, bounds: Rectangle, cursor: mouse::Cursor, - ) { + ) -> Vec { let content = self.state.cache.draw(renderer, bounds.size(), |frame| { Curve::draw_all(self.curves, frame); @@ -153,10 +155,10 @@ mod bezier { ); }); - renderer.draw_geometry([content]); - if let Some(pending) = state { - pending.draw(renderer, bounds, cursor); + vec![content, pending.draw(renderer, bounds, cursor)] + } else { + vec![content] } } @@ -203,10 +205,10 @@ mod bezier { impl Pending { fn draw( &self, - renderer: &mut Renderer, + renderer: &Renderer, bounds: Rectangle, cursor: mouse::Cursor, - ) { + ) -> Geometry { let mut frame = frame(renderer, bounds.size()); if let Some(cursor_position) = cursor.position_in(bounds) { @@ -227,7 +229,7 @@ mod bezier { }; } - renderer.draw_geometry([frame]); + frame.into() } } } diff --git a/examples/clock/src/main.rs b/examples/clock/src/main.rs index 9f78903c..468443bc 100644 --- a/examples/clock/src/main.rs +++ b/examples/clock/src/main.rs @@ -1,6 +1,8 @@ use iced::alignment; use iced::mouse; -use iced::widget::canvas::{stroke, Cache, Frame, LineCap, Path, Stroke}; +use iced::widget::canvas::{ + stroke, Cache, Frame, Geometry, LineCap, Path, Stroke, +}; use iced::widget::{canvas, container}; use iced::{ Degrees, Element, Font, Length, Point, Rectangle, Renderer, Subscription, @@ -82,11 +84,11 @@ impl canvas::Program for Clock { fn draw( &self, _state: &Self::State, - renderer: &mut Renderer, + renderer: &Renderer, theme: &Theme, bounds: Rectangle, _cursor: mouse::Cursor, - ) { + ) -> Vec { let clock = self.clock.draw(renderer, bounds.size(), |frame| { let palette = theme.extended_palette(); @@ -163,7 +165,7 @@ impl canvas::Program for Clock { }); }); - renderer.draw_geometry([clock]); + vec![clock] } } diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs index 400766ff..81ad6e41 100644 --- a/examples/color_palette/src/main.rs +++ b/examples/color_palette/src/main.rs @@ -1,6 +1,6 @@ use iced::alignment::{self, Alignment}; use iced::mouse; -use iced::widget::canvas::{self, Canvas, Frame, Path}; +use iced::widget::canvas::{self, Canvas, Frame, Geometry, Path}; use iced::widget::{column, row, text, Slider}; use iced::{ Color, Element, Font, Length, Pixels, Point, Rectangle, Renderer, Size, @@ -252,18 +252,18 @@ impl canvas::Program for Theme { fn draw( &self, _state: &Self::State, - renderer: &mut Renderer, + renderer: &Renderer, theme: &iced::Theme, bounds: Rectangle, _cursor: mouse::Cursor, - ) { + ) -> Vec { let theme = self.canvas_cache.draw(renderer, bounds.size(), |frame| { let palette = theme.extended_palette(); self.draw(frame, palette.background.base.text); }); - renderer.draw_geometry([theme]); + vec![theme] } } diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs index f681b4cc..a3d385f3 100644 --- a/examples/game_of_life/src/main.rs +++ b/examples/game_of_life/src/main.rs @@ -193,7 +193,9 @@ mod grid { use iced::touch; use iced::widget::canvas; use iced::widget::canvas::event::{self, Event}; - use iced::widget::canvas::{frame, Cache, Canvas, Frame, Path, Text}; + use iced::widget::canvas::{ + frame, Cache, Canvas, Frame, Geometry, Path, Text, + }; use iced::{ Color, Element, Length, Point, Rectangle, Renderer, Size, Theme, Vector, }; @@ -516,11 +518,11 @@ mod grid { fn draw( &self, _interaction: &Interaction, - renderer: &mut Renderer, + renderer: &Renderer, _theme: &Theme, bounds: Rectangle, cursor: mouse::Cursor, - ) { + ) -> Vec { let center = Vector::new(bounds.width / 2.0, bounds.height / 2.0); let life = self.life_cache.draw(renderer, bounds.size(), |frame| { @@ -638,9 +640,9 @@ mod grid { } }); - renderer.draw_geometry([life, grid, overlay]); + vec![life, grid, overlay] } else { - renderer.draw_geometry([life, overlay]); + vec![life, overlay] } } diff --git a/examples/layout/src/main.rs b/examples/layout/src/main.rs index 198237f5..35d2d3ba 100644 --- a/examples/layout/src/main.rs +++ b/examples/layout/src/main.rs @@ -292,11 +292,11 @@ fn square<'a>(size: impl Into + Copy) -> Element<'a, Message> { fn draw( &self, _state: &Self::State, - renderer: &mut Renderer, + renderer: &Renderer, theme: &Theme, bounds: Rectangle, _cursor: mouse::Cursor, - ) { + ) -> Vec { use canvas::Frame; let mut frame = canvas::frame(renderer, bounds.size()); @@ -309,7 +309,7 @@ fn square<'a>(size: impl Into + Copy) -> Element<'a, Message> { palette.background.strong.color, ); - renderer.draw_geometry([frame]); + vec![frame.into()] } } diff --git a/examples/multitouch/src/main.rs b/examples/multitouch/src/main.rs index 41bd0151..6d9039fa 100644 --- a/examples/multitouch/src/main.rs +++ b/examples/multitouch/src/main.rs @@ -5,7 +5,7 @@ use iced::mouse; use iced::touch; use iced::widget::canvas::event; use iced::widget::canvas::stroke::{self, Stroke}; -use iced::widget::canvas::{self, Canvas}; +use iced::widget::canvas::{self, Canvas, Geometry}; use iced::{Color, Element, Length, Point, Rectangle, Renderer, Theme}; use std::collections::HashMap; @@ -83,11 +83,11 @@ impl canvas::Program for Multitouch { fn draw( &self, _state: &Self::State, - renderer: &mut Renderer, + renderer: &Renderer, _theme: &Theme, bounds: Rectangle, _cursor: mouse::Cursor, - ) { + ) -> Vec { use canvas::Frame; let fingerweb = self.cache.draw(renderer, bounds.size(), |frame| { @@ -156,6 +156,6 @@ impl canvas::Program for Multitouch { } }); - renderer.draw_geometry([fingerweb]); + vec![fingerweb] } } diff --git a/examples/sierpinski_triangle/src/main.rs b/examples/sierpinski_triangle/src/main.rs index b440b8b4..409bc718 100644 --- a/examples/sierpinski_triangle/src/main.rs +++ b/examples/sierpinski_triangle/src/main.rs @@ -1,6 +1,6 @@ use iced::mouse; use iced::widget::canvas::event::{self, Event}; -use iced::widget::canvas::{self, Canvas}; +use iced::widget::canvas::{self, Canvas, Geometry}; use iced::widget::{column, row, slider, text}; use iced::{Color, Length, Point, Rectangle, Renderer, Size, Theme}; @@ -107,11 +107,11 @@ impl canvas::Program for SierpinskiGraph { fn draw( &self, _state: &Self::State, - renderer: &mut Renderer, + renderer: &Renderer, _theme: &Theme, bounds: Rectangle, _cursor: mouse::Cursor, - ) { + ) -> Vec { use canvas::Frame; let geom = self.cache.draw(renderer, bounds.size(), |frame| { @@ -141,7 +141,7 @@ impl canvas::Program for SierpinskiGraph { }); }); - renderer.draw_geometry([geom]); + vec![geom] } } diff --git a/examples/solar_system/src/main.rs b/examples/solar_system/src/main.rs index dd36b711..e8f94ed0 100644 --- a/examples/solar_system/src/main.rs +++ b/examples/solar_system/src/main.rs @@ -10,7 +10,7 @@ use iced::mouse; use iced::widget::canvas; use iced::widget::canvas::gradient; use iced::widget::canvas::stroke::{self, Stroke}; -use iced::widget::canvas::Path; +use iced::widget::canvas::{Geometry, Path}; use iced::window; use iced::{ Color, Element, Length, Point, Rectangle, Renderer, Size, Subscription, @@ -126,11 +126,11 @@ impl canvas::Program for State { fn draw( &self, _state: &Self::State, - renderer: &mut Renderer, + renderer: &Renderer, _theme: &Theme, bounds: Rectangle, _cursor: mouse::Cursor, - ) { + ) -> Vec { use canvas::Frame; use std::f32::consts::PI; @@ -198,7 +198,7 @@ impl canvas::Program for State { }); }); - renderer.draw_geometry([background, system]); + vec![background, system] } } diff --git a/examples/vectorial_text/src/main.rs b/examples/vectorial_text/src/main.rs index 9f5baac8..9b605d23 100644 --- a/examples/vectorial_text/src/main.rs +++ b/examples/vectorial_text/src/main.rs @@ -124,11 +124,11 @@ impl canvas::Program for State { fn draw( &self, _state: &Self::State, - renderer: &mut Renderer, + renderer: &Renderer, theme: &Theme, bounds: Rectangle, _cursor: mouse::Cursor, - ) { + ) -> Vec { use canvas::Frame; let geometry = self.cache.draw(renderer, bounds.size(), |frame| { @@ -155,7 +155,7 @@ impl canvas::Program for State { }); }); - renderer.draw_geometry([geometry]); + vec![geometry] } } diff --git a/widget/src/canvas.rs b/widget/src/canvas.rs index fcd91d17..81067491 100644 --- a/widget/src/canvas.rs +++ b/widget/src/canvas.rs @@ -26,13 +26,17 @@ use std::marker::PhantomData; /// change or it is explicitly cleared. pub type Cache = geometry::Cache; +/// The geometry supported by a renderer. +pub type Geometry = + ::Geometry; + /// A widget capable of drawing 2D graphics. /// /// ## Drawing a simple circle /// If you want to get a quick overview, here's how we can draw a simple circle: /// /// ```no_run -/// # use iced_widget::canvas::{self, frame, Canvas, Fill, Frame, Path, Program}; +/// # use iced_widget::canvas::{self, frame, Canvas, Fill, Frame, Geometry, Path, Program}; /// # use iced_widget::core::{Color, Rectangle}; /// # use iced_widget::core::mouse; /// # use iced_widget::{Renderer, Theme}; @@ -47,7 +51,7 @@ pub type Cache = geometry::Cache; /// impl Program<()> for Circle { /// type State = (); /// -/// fn draw(&self, _state: &(), renderer: &mut Renderer, _theme: &Theme, bounds: Rectangle, _cursor: mouse::Cursor) { +/// fn draw(&self, _state: &(), renderer: &Renderer, _theme: &Theme, bounds: Rectangle, _cursor: mouse::Cursor) -> Vec { /// // We prepare a new `Frame` /// let mut frame = frame(renderer, bounds.size()); /// @@ -58,7 +62,7 @@ pub type Cache = geometry::Cache; /// frame.fill(&circle, Color::BLACK); /// /// // Finally, we produce the geometry -/// renderer.draw_geometry([frame]); +/// vec![frame.into()] /// } /// } /// @@ -215,7 +219,12 @@ where renderer.with_transformation( Transformation::translate(bounds.x, bounds.y), |renderer| { - self.program.draw(state, renderer, theme, bounds, cursor); + let layers = + self.program.draw(state, renderer, theme, bounds, cursor); + + for layer in layers { + renderer.draw_geometry(layer); + } }, ); } diff --git a/widget/src/canvas/program.rs b/widget/src/canvas/program.rs index 307686de..3ba31474 100644 --- a/widget/src/canvas/program.rs +++ b/widget/src/canvas/program.rs @@ -1,5 +1,6 @@ use crate::canvas::event::{self, Event}; use crate::canvas::mouse; +use crate::canvas::Geometry; use crate::core::Rectangle; use crate::graphics::geometry; @@ -41,11 +42,11 @@ where fn draw( &self, state: &Self::State, - renderer: &mut Renderer, + renderer: &Renderer, theme: &Theme, bounds: Rectangle, cursor: mouse::Cursor, - ); + ) -> Vec>; /// Returns the current mouse interaction of the [`Program`]. /// @@ -83,12 +84,12 @@ where fn draw( &self, state: &Self::State, - renderer: &mut Renderer, + renderer: &Renderer, theme: &Theme, bounds: Rectangle, cursor: mouse::Cursor, - ) { - T::draw(self, state, renderer, theme, bounds, cursor); + ) -> Vec> { + T::draw(self, state, renderer, theme, bounds, cursor) } fn mouse_interaction( -- cgit