Skip to main content

cranpose_ui/
draw.rs

1use std::rc::Rc;
2
3use crate::modifier::Size;
4use cranpose_ui_graphics::{DrawPrimitive, DrawScope, DrawScopeDefault};
5
6pub type DrawCommandFn = Rc<dyn Fn(Size) -> Vec<DrawPrimitive>>;
7
8#[derive(Clone)]
9pub enum DrawCommand {
10    Behind(DrawCommandFn),
11    Overlay(DrawCommandFn),
12}
13
14#[derive(Default, Clone)]
15pub struct DrawCacheBuilder {
16    behind: Vec<DrawCommandFn>,
17    overlay: Vec<DrawCommandFn>,
18}
19
20impl DrawCacheBuilder {
21    pub fn on_draw_behind(&mut self, f: impl Fn(&mut dyn DrawScope) + 'static) {
22        let func = Rc::new(move |size: Size| {
23            let mut scope = DrawScopeDefault::new(size);
24            f(&mut scope);
25            scope.into_primitives()
26        });
27        self.behind.push(func);
28    }
29
30    pub fn on_draw_with_content(&mut self, f: impl Fn(&mut dyn DrawScope) + 'static) {
31        let func = Rc::new(move |size: Size| {
32            let mut scope = DrawScopeDefault::new(size);
33            f(&mut scope);
34            scope.into_primitives()
35        });
36        self.overlay.push(func);
37    }
38
39    pub fn finish(self) -> Vec<DrawCommand> {
40        let mut commands = Vec::new();
41        commands.extend(self.behind.into_iter().map(DrawCommand::Behind));
42        commands.extend(self.overlay.into_iter().map(DrawCommand::Overlay));
43        commands
44    }
45}
46
47pub fn execute_draw_commands(commands: &[DrawCommand], size: Size) -> Vec<DrawPrimitive> {
48    let mut primitives = Vec::new();
49    for command in commands {
50        match command {
51            DrawCommand::Behind(f) | DrawCommand::Overlay(f) => {
52                primitives.extend(f(size).into_iter());
53            }
54        }
55    }
56    primitives
57}