hui_shared/rect/
color.rs

1use super::Corners;
2use glam::{Vec2, Vec3, Vec4, vec4};
3
4/// Represents the fill color of a rectangle
5///
6/// Can be a single color or a simple gradient with different colors for each corner
7#[derive(Clone, Copy, Debug, PartialEq)]
8pub struct FillColor(Corners<Vec4>);
9
10impl FillColor {
11  pub const fn new(corners: Corners<Vec4>) -> Self {
12    Self(corners)
13  }
14
15  /// Transparent background (alpha = 0)
16  pub const TRANSPARENT: Self = Self::rgba(0., 0., 0., 0.);
17
18  /// Transparent background (alpha = 0)
19  pub const fn transparent() -> Self {
20    Self::TRANSPARENT
21  }
22
23  /// Check if the fill color is completely transparent
24  ///
25  /// (i.e. all corners have an alpha value of 0.0)
26  pub fn is_transparent(&self) -> bool {
27    self.0.top_left.w == 0. &&
28    self.0.top_right.w == 0. &&
29    self.0.bottom_left.w == 0. &&
30    self.0.bottom_right.w == 0.
31  }
32
33  /// Check if the fill color is completely opaque
34  ///
35  /// (i.e. all corners have an alpha value of 1.0)
36  pub fn is_opaque(&self) -> bool {
37    self.0.top_left.w == 1. &&
38    self.0.top_right.w == 1. &&
39    self.0.bottom_left.w == 1. &&
40    self.0.bottom_right.w == 1.
41  }
42
43  /// Construct a solid color fill from values representing the red, green, blue and alpha channels
44  pub const fn rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
45    Self(Corners {
46      top_left: vec4(r, g, b, a),
47      top_right: vec4(r, g, b, a),
48      bottom_left: vec4(r, g, b, a),
49      bottom_right: vec4(r, g, b, a),
50    })
51  }
52
53  /// Construct a solid color fill from three values representing the red, green and blue channels
54  pub const fn rgb(r: f32, g: f32, b: f32) -> Self {
55    Self(Corners {
56      top_left: vec4(r, g, b, 1.0),
57      top_right: vec4(r, g, b, 1.0),
58      bottom_left: vec4(r, g, b, 1.0),
59      bottom_right: vec4(r, g, b, 1.0),
60    })
61  }
62
63  /// Construct a solid color fill from colors for each corner
64  pub const fn from_corners(corners: Corners<Vec4>) -> Self {
65    Self(corners)
66  }
67
68  /// Get a list of the colors for each corner
69  pub const fn corners(&self) -> Corners<Vec4> {
70    self.0
71  }
72
73  /// Interpolate color on position, assuming a linear gradient
74  pub fn interpolate(&self, uv: Vec2) -> Vec4 {
75    let c = self.corners();
76    let top = c.top_left.lerp(c.top_right, uv.x);
77    let bottom = c.bottom_left.lerp(c.bottom_right, uv.x);
78    top.lerp(bottom, uv.y)
79  }
80}
81
82impl Default for FillColor {
83  fn default() -> Self {
84    Self(Corners::all(vec4(0.0, 0.0, 0.0, 1.0)))
85  }
86}
87
88impl From<Corners<Vec4>> for FillColor {
89  fn from(corners: Corners<Vec4>) -> Self {
90    Self(corners)
91  }
92}
93
94impl From<FillColor> for Corners<Vec4> {
95  fn from(corners: FillColor) -> Self {
96    corners.0
97  }
98}
99
100impl From<Vec4> for FillColor {
101  fn from(value: Vec4) -> Self {
102    Self(Corners::all(value))
103  }
104}
105
106impl From<(f32, f32, f32, f32)> for FillColor {
107  fn from((r, g, b, a): (f32, f32, f32, f32)) -> Self {
108    Self(Corners::all(vec4(r, g, b, a)))
109  }
110}
111
112impl From<[f32; 4]> for FillColor {
113  fn from([r, g, b, a]: [f32; 4]) -> Self {
114    Self(Corners::all(vec4(r, g, b, a)))
115  }
116}
117
118impl From<Vec3> for FillColor {
119  fn from(value: Vec3) -> Self {
120    Self(Corners::all(vec4(value.x, value.y, value.z, 1.0)))
121  }
122}
123
124impl From<(f32, f32, f32)> for FillColor {
125  fn from((r, g, b): (f32, f32, f32)) -> Self {
126    Self(Corners::all(vec4(r, g, b, 1.0)))
127  }
128}
129
130impl From<[f32; 3]> for FillColor {
131  fn from([r, g, b]: [f32; 3]) -> Self {
132    Self(Corners::all(vec4(r, g, b, 1.0)))
133  }
134}
135
136impl From<(Vec4, Vec4, Vec4, Vec4)> for FillColor {
137  fn from((top_left, top_right, bottom_left, bottom_right): (Vec4, Vec4, Vec4, Vec4)) -> Self {
138    Self(Corners { top_left, top_right, bottom_left, bottom_right })
139  }
140}
141
142impl From<((f32, f32, f32, f32), (f32, f32, f32, f32), (f32, f32, f32, f32), (f32, f32, f32, f32))> for FillColor {
143  fn from(value: ((f32, f32, f32, f32), (f32, f32, f32, f32), (f32, f32, f32, f32), (f32, f32, f32, f32))) -> Self {
144    Self(Corners {
145      top_left: vec4(value.0.0, value.0.1, value.0.2, value.0.3),
146      top_right: vec4(value.1.0, value.1.1, value.1.2, value.1.3),
147      bottom_left: vec4(value.2.0, value.2.1, value.2.2, value.2.3),
148      bottom_right: vec4(value.3.0, value.3.1, value.3.2, value.3.3),
149    })
150  }
151}
152
153impl From<[[f32; 4]; 4]> for FillColor {
154  fn from(value: [[f32; 4]; 4]) -> Self {
155    Self(Corners {
156      top_left: vec4(value[0][0], value[0][1], value[0][2], value[0][3]),
157      top_right: vec4(value[1][0], value[1][1], value[1][2], value[1][3]),
158      bottom_left: vec4(value[2][0], value[2][1], value[2][2], value[2][3]),
159      bottom_right: vec4(value[3][0], value[3][1], value[3][2], value[3][3]),
160    })
161  }
162}
163
164impl From<Corners<Vec3>> for FillColor {
165  fn from(corners: Corners<Vec3>) -> Self {
166    Self(Corners {
167      top_left: corners.top_left.extend(1.),
168      top_right: corners.top_right.extend(1.),
169      bottom_left: corners.bottom_left.extend(1.),
170      bottom_right: corners.bottom_right.extend(1.),
171    })
172  }
173}
174
175impl From<(Vec3, Vec3, Vec3, Vec3)> for FillColor {
176  fn from((top_left, top_right, bottom_left, bottom_right): (Vec3, Vec3, Vec3, Vec3)) -> Self {
177    Self(Corners {
178      top_left: vec4(top_left.x, top_left.y, top_left.z, 1.0),
179      top_right: vec4(top_right.x, top_right.y, top_right.z, 1.0),
180      bottom_left: vec4(bottom_left.x, bottom_left.y, bottom_left.z, 1.0),
181      bottom_right: vec4(bottom_right.x, bottom_right.y, bottom_right.z, 1.0),
182    })
183  }
184}
185
186impl From<((f32, f32, f32), (f32, f32, f32), (f32, f32, f32), (f32, f32, f32))> for FillColor {
187  fn from(value: ((f32, f32, f32), (f32, f32, f32), (f32, f32, f32), (f32, f32, f32))) -> Self {
188    Self(Corners {
189      top_left: vec4(value.0.0, value.0.1, value.0.2, 1.0),
190      top_right: vec4(value.1.0, value.1.1, value.1.2, 1.0),
191      bottom_left: vec4(value.2.0, value.2.1, value.2.2, 1.0),
192      bottom_right: vec4(value.3.0, value.3.1, value.3.2, 1.0),
193    })
194  }
195}
196
197impl From<[[f32; 3]; 4]> for FillColor {
198  fn from(value: [[f32; 3]; 4]) -> Self {
199    Self(Corners {
200      top_left: vec4(value[0][0], value[0][1], value[0][2], 1.0),
201      top_right: vec4(value[1][0], value[1][1], value[1][2], 1.0),
202      bottom_left: vec4(value[2][0], value[2][1], value[2][2], 1.0),
203      bottom_right: vec4(value[3][0], value[3][1], value[3][2], 1.0),
204    })
205  }
206}