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}