ori_graphics/
frame.rs

1use crate::{Mesh, Quad, Rect, TextSection};
2
3#[derive(Clone, Debug)]
4pub enum PrimitiveKind {
5    Text(TextSection),
6    Quad(Quad),
7    Mesh(Mesh),
8}
9
10impl From<TextSection> for PrimitiveKind {
11    fn from(text: TextSection) -> Self {
12        Self::Text(text)
13    }
14}
15
16impl From<Quad> for PrimitiveKind {
17    fn from(quad: Quad) -> Self {
18        Self::Quad(quad)
19    }
20}
21
22impl From<Mesh> for PrimitiveKind {
23    fn from(mesh: Mesh) -> Self {
24        Self::Mesh(mesh)
25    }
26}
27
28#[derive(Clone, Debug)]
29pub struct Primitive {
30    pub kind: PrimitiveKind,
31    pub depth: f32,
32    pub clip: Option<Rect>,
33}
34
35pub struct Frame {
36    primitives: Vec<Primitive>,
37    depth: f32,
38    clip: Option<Rect>,
39}
40
41impl Frame {
42    pub fn new() -> Self {
43        Self {
44            depth: 0.0,
45            primitives: Vec::new(),
46            clip: None,
47        }
48    }
49
50    pub fn clear(&mut self) {
51        self.primitives.clear();
52    }
53
54    pub fn depth(&self) -> f32 {
55        self.depth
56    }
57
58    pub fn clip(&self) -> Option<Rect> {
59        self.clip
60    }
61
62    pub fn draw(&mut self, primitive: impl Into<PrimitiveKind>) {
63        self.draw_primitive(Primitive {
64            kind: primitive.into(),
65            depth: self.depth,
66            clip: self.clip,
67        });
68    }
69
70    pub fn draw_primitive(&mut self, primitive: Primitive) {
71        self.primitives.push(primitive);
72    }
73
74    pub fn layer(&mut self) -> Layer<'_> {
75        Layer {
76            frame: self,
77            depth: 1.0,
78            clip: None,
79        }
80    }
81
82    pub fn draw_layer(&mut self, f: impl FnOnce(&mut Self)) {
83        self.layer().draw(f);
84    }
85
86    pub fn primitives(&self) -> &[Primitive] {
87        &self.primitives
88    }
89}
90
91pub struct Layer<'a> {
92    frame: &'a mut Frame,
93    depth: f32,
94    clip: Option<Rect>,
95}
96
97impl<'a> Layer<'a> {
98    pub fn depth(mut self, depth: f32) -> Self {
99        self.depth = depth;
100        self
101    }
102
103    pub fn clip(mut self, clip: impl Into<Option<Rect>>) -> Self {
104        self.clip = clip.into().map(Rect::round);
105        self
106    }
107
108    pub fn draw(self, f: impl FnOnce(&mut Frame)) {
109        self.frame.depth += self.depth;
110
111        if let Some(clip) = self.clip {
112            let old_clip = self.frame.clip;
113            self.frame.clip = Some(clip);
114            f(self.frame);
115            self.frame.clip = old_clip;
116        } else {
117            f(self.frame);
118        }
119
120        self.frame.depth -= self.depth;
121    }
122}