use std::cell::RefCell;
use std::rc::Rc;
use iced::advanced::renderer;
use iced::{Background, Color, Pixels, Point, Rectangle, Transformation};
use iced_wgpu::core::image;
use iced_wgpu::core::text;
#[derive(Debug, Default, Clone)]
pub struct Recorded {
pub quads: Vec<Rectangle>,
pub primitives: Vec<Rectangle>,
pub events: Vec<DrawEvent>,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum DrawEvent {
Content(Rectangle),
Sdf(Rectangle),
}
pub struct Recorder {
transformations: Vec<Transformation>,
layers: Vec<Rectangle>,
out: Rc<RefCell<Recorded>>,
}
impl Recorder {
pub fn new(out: Rc<RefCell<Recorded>>) -> Self {
Self {
transformations: vec![Transformation::IDENTITY],
layers: Vec::new(),
out,
}
}
pub fn detached() -> Self {
Self::new(Rc::default())
}
pub fn clip(&self) -> Option<Rectangle> {
self.layers.last().copied()
}
fn current(&self) -> Transformation {
*self.transformations.last().unwrap()
}
}
impl renderer::Renderer for Recorder {
fn start_layer(&mut self, bounds: Rectangle) {
self.layers.push(bounds * self.current());
}
fn end_layer(&mut self) {
self.layers.pop();
}
fn start_transformation(&mut self, transformation: Transformation) {
self.transformations.push(self.current() * transformation);
}
fn end_transformation(&mut self) {
self.transformations.pop();
if self.transformations.is_empty() {
self.transformations.push(Transformation::IDENTITY);
}
}
fn reset(&mut self, _new_bounds: Rectangle) {}
fn fill_quad(&mut self, quad: renderer::Quad, _background: impl Into<Background>) {
let abs = quad.bounds * self.current();
let mut out = self.out.borrow_mut();
out.quads.push(abs);
out.events.push(DrawEvent::Content(abs));
}
fn allocate_image(
&mut self,
_handle: &image::Handle,
_callback: impl FnOnce(Result<image::Allocation, image::Error>) + Send + 'static,
) {
}
}
impl text::Renderer for Recorder {
type Font = iced::Font;
type Paragraph = iced_wgpu::graphics::text::Paragraph;
type Editor = iced_wgpu::graphics::text::Editor;
const ICON_FONT: iced::Font = iced::Font::DEFAULT;
const CHECKMARK_ICON: char = '0';
const ARROW_DOWN_ICON: char = '0';
const SCROLL_UP_ICON: char = '0';
const SCROLL_DOWN_ICON: char = '0';
const SCROLL_LEFT_ICON: char = '0';
const SCROLL_RIGHT_ICON: char = '0';
const ICED_LOGO: char = '0';
fn default_font(&self) -> Self::Font {
iced::Font::default()
}
fn default_size(&self) -> Pixels {
Pixels(16.0)
}
fn fill_paragraph(&mut self, _: &Self::Paragraph, _: Point, _: Color, _: Rectangle) {}
fn fill_editor(&mut self, _: &Self::Editor, _: Point, _: Color, _: Rectangle) {}
fn fill_text(&mut self, _: text::Text, _: Point, _: Color, _: Rectangle) {}
}
impl iced_wgpu::primitive::Renderer for Recorder {
fn draw_primitive(&mut self, bounds: Rectangle, _primitive: impl iced_wgpu::Primitive) {
let abs = bounds * self.current();
let mut out = self.out.borrow_mut();
out.primitives.push(abs);
out.events.push(DrawEvent::Sdf(abs));
}
}