rootvg_quad/primitive/
gradient.rs

1use rootvg_core::color::PackedSrgb;
2use rootvg_core::gradient::{Gradient, PackedGradient};
3use rootvg_core::math::{Point, Rect, Size};
4
5use crate::border::Border;
6use crate::Radius;
7
8/// A quad primitive with a gradient background.
9#[derive(Default, Debug, Clone, Copy, PartialEq)]
10pub struct GradientQuad {
11    /// The bounds of the quad in logical points.
12    pub bounds: Rect,
13    /// The background color of the quad
14    pub bg_gradient: Gradient,
15    /// The [`Border`] of the quad
16    pub border: Border,
17    /*
18    /// The shadow of the quad
19    pub shadow: Shadow,
20    */
21}
22
23impl GradientQuad {
24    pub fn packed(&self) -> GradientQuadPrimitive {
25        GradientQuadPrimitive {
26            gradient: self.bg_gradient.packed(self.bounds),
27            position: self.bounds.origin.into(),
28            size: self.bounds.size.into(),
29            border_color: self.border.color,
30            border_radius: self.border.radius.into(),
31            border_width: self.border.width,
32        }
33    }
34
35    pub fn builder(size: Size) -> GradientQuadBuilder {
36        GradientQuadBuilder::new(size)
37    }
38}
39
40pub struct GradientQuadBuilder {
41    quad: GradientQuad,
42}
43
44impl GradientQuadBuilder {
45    pub fn new(size: Size) -> Self {
46        Self {
47            quad: GradientQuad {
48                bounds: Rect {
49                    origin: Point::new(0.0, 0.0),
50                    size,
51                },
52                ..Default::default()
53            },
54        }
55    }
56
57    pub fn position(mut self, position: Point) -> Self {
58        self.quad.bounds.origin = position;
59        self
60    }
61
62    pub fn bg_gradient(mut self, color: impl Into<Gradient>) -> Self {
63        self.quad.bg_gradient = color.into();
64        self
65    }
66
67    pub fn border_color(mut self, color: impl Into<PackedSrgb>) -> Self {
68        self.quad.border.color = color.into();
69        self
70    }
71
72    pub fn border_width(mut self, width: f32) -> Self {
73        self.quad.border.width = width;
74        self
75    }
76
77    pub fn border_radius(mut self, radius: impl Into<Radius>) -> Self {
78        self.quad.border.radius = radius.into();
79        self
80    }
81
82    pub fn border(mut self, border: Border) -> Self {
83        self.quad.border = border;
84        self
85    }
86
87    /*
88    pub fn shadow_color(mut self, color: impl Into<PackedSrgb>) -> Self {
89        self.quad.shadow.color = color.into();
90        self
91    }
92
93    pub fn shadow_offset(mut self, offset: Point) -> Self {
94        self.quad.shadow.offset = offset;
95        self
96    }
97
98    pub fn blur_radius(mut self, blur_radius: f32) -> Self {
99        self.quad.shadow.blur_radius = blur_radius;
100        self
101    }
102
103    pub fn shadow(mut self, shadow: Shadow) -> Self {
104        self.quad.shadow = shadow;
105        self
106    }
107    */
108
109    pub fn build(self) -> GradientQuad {
110        self.quad
111    }
112}
113
114/// A quad primitive with a gradient background, packed into a format
115/// for use in rendering.
116#[repr(C)]
117#[derive(Clone, Copy, Debug, PartialEq, bytemuck::Zeroable, bytemuck::Pod)]
118pub struct GradientQuadPrimitive {
119    /// The background gradient data of the quad.
120    pub gradient: PackedGradient,
121
122    /// The position of the [`Quad`] in logical points.
123    pub position: [f32; 2],
124
125    /// The size of the [`Quad`] in logical points.
126    pub size: [f32; 2],
127
128    /// The border color of the [`Quad`], in __linear RGB__.
129    pub border_color: PackedSrgb,
130
131    /// The border radii of the [`Quad`] in logical points.
132    pub border_radius: [f32; 4],
133
134    /// The border width of the [`Quad`] in logical points.
135    pub border_width: f32,
136}
137
138impl GradientQuadPrimitive {
139    pub fn new(quad: &GradientQuad) -> Self {
140        Self {
141            gradient: quad.bg_gradient.packed(quad.bounds),
142            position: quad.bounds.origin.into(),
143            size: quad.bounds.size.into(),
144            border_color: quad.border.color,
145            border_radius: quad.border.radius.into(),
146            border_width: quad.border.width,
147        }
148    }
149}
150
151impl From<GradientQuad> for GradientQuadPrimitive {
152    fn from(q: GradientQuad) -> GradientQuadPrimitive {
153        q.packed()
154    }
155}
156
157impl<'a> From<&'a GradientQuad> for GradientQuadPrimitive {
158    fn from(q: &'a GradientQuad) -> GradientQuadPrimitive {
159        q.packed()
160    }
161}
162
163impl From<GradientQuadBuilder> for GradientQuadPrimitive {
164    fn from(q: GradientQuadBuilder) -> GradientQuadPrimitive {
165        q.build().packed()
166    }
167}
168
169impl From<GradientQuadBuilder> for GradientQuad {
170    fn from(q: GradientQuadBuilder) -> GradientQuad {
171        q.build()
172    }
173}