Implement composable, type-safe renderer fallback

This commit is contained in:
Héctor Ramón Jiménez 2024-03-21 22:27:17 +01:00
parent 7e4ae8450e
commit 3645d34d6a
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
35 changed files with 1474 additions and 1210 deletions

View file

@ -1,9 +1,7 @@
use std::{f32::consts::PI, time::Instant};
use iced::mouse;
use iced::widget::canvas::{
self, stroke, Cache, Canvas, Geometry, Path, Stroke,
};
use iced::widget::canvas::{self, stroke, Cache, Canvas, Frame, Path, Stroke};
use iced::{Element, Length, Point, Rectangle, Renderer, Subscription, Theme};
pub fn main() -> iced::Result {
@ -57,11 +55,11 @@ impl<Message> canvas::Program<Message> for Arc {
fn draw(
&self,
_state: &Self::State,
renderer: &Renderer,
renderer: &mut Renderer,
theme: &Theme,
bounds: Rectangle,
_cursor: mouse::Cursor,
) -> Vec<Geometry> {
) {
let geometry = self.cache.draw(renderer, bounds.size(), |frame| {
let palette = theme.palette();
@ -104,6 +102,6 @@ impl<Message> canvas::Program<Message> for Arc {
);
});
vec![geometry]
renderer.draw_geometry([geometry]);
}
}

View file

@ -52,7 +52,7 @@ impl Example {
mod bezier {
use iced::mouse;
use iced::widget::canvas::event::{self, Event};
use iced::widget::canvas::{self, Canvas, Frame, Geometry, Path, Stroke};
use iced::widget::canvas::{self, frame, Canvas, Frame, Path, Stroke};
use iced::{Element, Length, Point, Rectangle, Renderer, Theme};
#[derive(Default)]
@ -138,30 +138,25 @@ mod bezier {
fn draw(
&self,
state: &Self::State,
renderer: &Renderer,
renderer: &mut Renderer,
_theme: &Theme,
bounds: Rectangle,
cursor: mouse::Cursor,
) -> Vec<Geometry> {
let content = self.state.cache.draw(
renderer,
bounds.size(),
|frame: &mut Frame| {
) {
let content =
self.state.cache.draw(renderer, bounds.size(), |frame| {
Curve::draw_all(self.curves, frame);
frame.stroke(
&Path::rectangle(Point::ORIGIN, frame.size()),
Stroke::default().with_width(2.0),
);
},
);
});
renderer.draw_geometry([content]);
if let Some(pending) = state {
let pending_curve = pending.draw(renderer, bounds, cursor);
vec![content, pending_curve]
} else {
vec![content]
pending.draw(renderer, bounds, cursor);
}
}
@ -187,7 +182,7 @@ mod bezier {
}
impl Curve {
fn draw_all(curves: &[Curve], frame: &mut Frame) {
fn draw_all(curves: &[Curve], frame: &mut impl Frame) {
let curves = Path::new(|p| {
for curve in curves {
p.move_to(curve.from);
@ -208,11 +203,11 @@ mod bezier {
impl Pending {
fn draw(
&self,
renderer: &Renderer,
renderer: &mut Renderer,
bounds: Rectangle,
cursor: mouse::Cursor,
) -> Geometry {
let mut frame = Frame::new(renderer, bounds.size());
) {
let mut frame = frame(renderer, bounds.size());
if let Some(cursor_position) = cursor.position_in(bounds) {
match *self {
@ -232,7 +227,7 @@ mod bezier {
};
}
frame.into_geometry()
renderer.draw_geometry([frame]);
}
}
}

View file

@ -1,6 +1,6 @@
use iced::alignment;
use iced::mouse;
use iced::widget::canvas::{stroke, Cache, Geometry, LineCap, Path, Stroke};
use iced::widget::canvas::{stroke, Cache, Frame, LineCap, Path, Stroke};
use iced::widget::{canvas, container};
use iced::{
Degrees, Element, Font, Length, Point, Rectangle, Renderer, Subscription,
@ -82,11 +82,11 @@ impl<Message> canvas::Program<Message> for Clock {
fn draw(
&self,
_state: &Self::State,
renderer: &Renderer,
renderer: &mut Renderer,
theme: &Theme,
bounds: Rectangle,
_cursor: mouse::Cursor,
) -> Vec<Geometry> {
) {
let clock = self.clock.draw(renderer, bounds.size(), |frame| {
let palette = theme.extended_palette();
@ -163,7 +163,7 @@ impl<Message> canvas::Program<Message> for Clock {
});
});
vec![clock]
renderer.draw_geometry([clock]);
}
}

View file

@ -1,6 +1,6 @@
use iced::alignment::{self, Alignment};
use iced::mouse;
use iced::widget::canvas::{self, Canvas, Frame, Geometry, Path};
use iced::widget::canvas::{self, Canvas, Frame, Path};
use iced::widget::{column, row, text, Slider};
use iced::{
Color, Element, Font, Length, Pixels, Point, Rectangle, Renderer, Size,
@ -156,7 +156,7 @@ impl Theme {
.into()
}
fn draw(&self, frame: &mut Frame, text_color: Color) {
fn draw(&self, frame: &mut impl Frame, text_color: Color) {
let pad = 20.0;
let box_size = Size {
@ -252,18 +252,18 @@ impl<Message> canvas::Program<Message> for Theme {
fn draw(
&self,
_state: &Self::State,
renderer: &Renderer,
renderer: &mut Renderer,
theme: &iced::Theme,
bounds: Rectangle,
_cursor: mouse::Cursor,
) -> Vec<Geometry> {
) {
let theme = self.canvas_cache.draw(renderer, bounds.size(), |frame| {
let palette = theme.extended_palette();
self.draw(frame, palette.background.base.text);
});
vec![theme]
renderer.draw_geometry([theme]);
}
}

View file

@ -193,7 +193,7 @@ mod grid {
use iced::touch;
use iced::widget::canvas;
use iced::widget::canvas::event::{self, Event};
use iced::widget::canvas::{Cache, Canvas, Frame, Geometry, Path, Text};
use iced::widget::canvas::{frame, Cache, Canvas, Frame, Path, Text};
use iced::{
Color, Element, Length, Point, Rectangle, Renderer, Size, Theme, Vector,
};
@ -516,11 +516,11 @@ mod grid {
fn draw(
&self,
_interaction: &Interaction,
renderer: &Renderer,
renderer: &mut Renderer,
_theme: &Theme,
bounds: Rectangle,
cursor: mouse::Cursor,
) -> Vec<Geometry> {
) {
let center = Vector::new(bounds.width / 2.0, bounds.height / 2.0);
let life = self.life_cache.draw(renderer, bounds.size(), |frame| {
@ -546,7 +546,7 @@ mod grid {
});
let overlay = {
let mut frame = Frame::new(renderer, bounds.size());
let mut frame = frame(renderer, bounds.size());
let hovered_cell = cursor.position_in(bounds).map(|position| {
Cell::at(self.project(position, frame.size()))
@ -599,12 +599,10 @@ mod grid {
..text
});
frame.into_geometry()
frame.into()
};
if self.scaling < 0.2 || !self.show_lines {
vec![life, overlay]
} else {
if self.scaling >= 0.2 && self.show_lines {
let grid =
self.grid_cache.draw(renderer, bounds.size(), |frame| {
frame.translate(center);
@ -640,7 +638,9 @@ mod grid {
}
});
vec![life, grid, overlay]
renderer.draw_geometry([life, grid, overlay]);
} else {
renderer.draw_geometry([life, overlay]);
}
}

View file

@ -44,7 +44,9 @@ mod rainbow {
cursor: mouse::Cursor,
_viewport: &Rectangle,
) {
use iced::advanced::graphics::mesh::{self, Mesh, SolidVertex2D};
use iced::advanced::graphics::mesh::{
self, Mesh, Renderer as _, SolidVertex2D,
};
use iced::advanced::Renderer as _;
let bounds = layout.bounds();

View file

@ -292,12 +292,14 @@ fn square<'a>(size: impl Into<Length> + Copy) -> Element<'a, Message> {
fn draw(
&self,
_state: &Self::State,
renderer: &Renderer,
renderer: &mut Renderer,
theme: &Theme,
bounds: Rectangle,
_cursor: mouse::Cursor,
) -> Vec<canvas::Geometry> {
let mut frame = canvas::Frame::new(renderer, bounds.size());
) {
use canvas::Frame;
let mut frame = canvas::frame(renderer, bounds.size());
let palette = theme.extended_palette();
@ -307,7 +309,7 @@ fn square<'a>(size: impl Into<Length> + Copy) -> Element<'a, Message> {
palette.background.strong.color,
);
vec![frame.into_geometry()]
renderer.draw_geometry([frame]);
}
}

View file

@ -6,7 +6,7 @@ use iced::advanced::{self, Clipboard, Layout, Shell, Widget};
use iced::event;
use iced::mouse;
use iced::time::Instant;
use iced::widget::canvas;
use iced::widget::canvas::{self, Frame};
use iced::window::{self, RedrawRequest};
use iced::{
Background, Color, Element, Event, Length, Radians, Rectangle, Renderer,
@ -356,9 +356,7 @@ where
renderer.with_translation(
Vector::new(bounds.x, bounds.y),
|renderer| {
use iced::advanced::graphics::geometry::Renderer as _;
renderer.draw(vec![geometry]);
renderer.draw_geometry([geometry]);
},
);
}

View file

@ -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, Geometry};
use iced::widget::canvas::{self, Canvas};
use iced::{Color, Element, Length, Point, Rectangle, Renderer, Theme};
use std::collections::HashMap;
@ -83,11 +83,13 @@ impl canvas::Program<Message> for Multitouch {
fn draw(
&self,
_state: &Self::State,
renderer: &Renderer,
renderer: &mut Renderer,
_theme: &Theme,
bounds: Rectangle,
_cursor: mouse::Cursor,
) -> Vec<Geometry> {
) {
use canvas::Frame;
let fingerweb = self.cache.draw(renderer, bounds.size(), |frame| {
if self.fingers.len() < 2 {
return;
@ -154,6 +156,6 @@ impl canvas::Program<Message> for Multitouch {
}
});
vec![fingerweb]
renderer.draw_geometry([fingerweb]);
}
}

View file

@ -107,11 +107,13 @@ impl canvas::Program<Message> for SierpinskiGraph {
fn draw(
&self,
_state: &Self::State,
renderer: &Renderer,
renderer: &mut Renderer,
_theme: &Theme,
bounds: Rectangle,
_cursor: mouse::Cursor,
) -> Vec<canvas::Geometry> {
) {
use canvas::Frame;
let geom = self.cache.draw(renderer, bounds.size(), |frame| {
frame.stroke(
&canvas::Path::rectangle(Point::ORIGIN, frame.size()),
@ -139,7 +141,7 @@ impl canvas::Program<Message> for SierpinskiGraph {
});
});
vec![geom]
renderer.draw_geometry([geom]);
}
}

View file

@ -126,11 +126,12 @@ impl<Message> canvas::Program<Message> for State {
fn draw(
&self,
_state: &Self::State,
renderer: &Renderer,
renderer: &mut Renderer,
_theme: &Theme,
bounds: Rectangle,
_cursor: mouse::Cursor,
) -> Vec<canvas::Geometry> {
) {
use canvas::Frame;
use std::f32::consts::PI;
let background =
@ -197,7 +198,7 @@ impl<Message> canvas::Program<Message> for State {
});
});
vec![background, system]
renderer.draw_geometry([background, system]);
}
}

View file

@ -124,11 +124,13 @@ impl<Message> canvas::Program<Message> for State {
fn draw(
&self,
_state: &Self::State,
renderer: &Renderer,
renderer: &mut Renderer,
theme: &Theme,
bounds: Rectangle,
_cursor: mouse::Cursor,
) -> Vec<canvas::Geometry> {
) {
use canvas::Frame;
let geometry = self.cache.draw(renderer, bounds.size(), |frame| {
let palette = theme.palette();
let center = bounds.center();
@ -153,7 +155,7 @@ impl<Message> canvas::Program<Message> for State {
});
});
vec![geometry]
renderer.draw_geometry([geometry]);
}
}