1use std::{fmt, str::FromStr};
4
5use glib::translate::*;
6
7use crate::{ffi, RGBA};
8
9#[derive(Debug)]
10#[must_use = "The builder must be built to be used"]
15pub struct RGBABuilder(RGBA);
16
17impl Default for RGBABuilder {
18 fn default() -> Self {
19 Self(RGBA::WHITE)
20 }
21}
22
23impl RGBABuilder {
24 pub fn new() -> Self {
27 Self::default()
28 }
29
30 pub fn blue(mut self, blue: f32) -> Self {
31 self.0.set_blue(blue);
32 self
33 }
34
35 pub fn green(mut self, green: f32) -> Self {
36 self.0.set_green(green);
37 self
38 }
39
40 pub fn red(mut self, red: f32) -> Self {
41 self.0.set_red(red);
42 self
43 }
44
45 pub fn alpha(mut self, alpha: f32) -> Self {
46 self.0.set_alpha(alpha);
47 self
48 }
49
50 #[must_use = "The RGBA returned by this builder should probably be used"]
53 pub fn build(self) -> RGBA {
54 self.0
55 }
56}
57
58impl RGBA {
59 #[inline]
60 pub const fn new(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
61 skip_assert_initialized!();
62 Self {
63 inner: ffi::GdkRGBA {
64 red,
65 green,
66 blue,
67 alpha,
68 },
69 }
70 }
71
72 #[inline]
84 pub const fn with_red(self, red: f32) -> Self {
85 Self {
86 inner: ffi::GdkRGBA { red, ..self.inner },
87 }
88 }
89
90 #[inline]
102 pub const fn with_green(self, green: f32) -> Self {
103 Self {
104 inner: ffi::GdkRGBA {
105 green,
106 ..self.inner
107 },
108 }
109 }
110
111 #[inline]
123 pub const fn with_blue(self, blue: f32) -> Self {
124 Self {
125 inner: ffi::GdkRGBA { blue, ..self.inner },
126 }
127 }
128
129 #[inline]
141 pub const fn with_alpha(self, alpha: f32) -> Self {
142 Self {
143 inner: ffi::GdkRGBA {
144 alpha,
145 ..self.inner
146 },
147 }
148 }
149
150 pub fn builder() -> RGBABuilder {
158 RGBABuilder::default()
159 }
160
161 #[inline]
162 pub fn red(&self) -> f32 {
163 self.inner.red
164 }
165
166 #[inline]
167 pub fn set_red(&mut self, red: f32) {
168 self.inner.red = red;
169 }
170
171 #[inline]
172 pub fn green(&self) -> f32 {
173 self.inner.green
174 }
175
176 #[inline]
177 pub fn set_green(&mut self, green: f32) {
178 self.inner.green = green;
179 }
180
181 #[inline]
182 pub fn blue(&self) -> f32 {
183 self.inner.blue
184 }
185
186 #[inline]
187 pub fn set_blue(&mut self, blue: f32) {
188 self.inner.blue = blue;
189 }
190
191 #[inline]
192 pub fn alpha(&self) -> f32 {
193 self.inner.alpha
194 }
195
196 #[inline]
197 pub fn set_alpha(&mut self, alpha: f32) {
198 self.inner.alpha = alpha;
199 }
200
201 #[doc(alias = "gdk_rgba_parse")]
202 pub fn parse(s: impl IntoGStr) -> Result<RGBA, glib::error::BoolError> {
203 skip_assert_initialized!();
204 unsafe {
205 s.run_with_gstr(|s| {
206 let mut res = RGBA::uninitialized();
207 glib::result_from_gboolean!(
208 ffi::gdk_rgba_parse(res.to_glib_none_mut().0, s.as_ptr()),
209 "Can't parse RGBA"
210 )
211 .map(|_| res)
212 })
213 }
214 }
215
216 pub const BLACK: RGBA = Self::new(0f32, 0f32, 0f32, 1f32);
217
218 pub const BLUE: RGBA = Self::new(0f32, 0f32, 1f32, 1f32);
219
220 pub const GREEN: RGBA = Self::new(0f32, 1f32, 0f32, 1f32);
221
222 pub const RED: RGBA = Self::new(1f32, 0f32, 0f32, 1f32);
223
224 pub const WHITE: RGBA = Self::new(1f32, 1f32, 1f32, 1f32);
225
226 pub const TRANSPARENT: RGBA = Self::new(0f32, 0f32, 0f32, 0f32);
227}
228
229impl fmt::Debug for RGBA {
230 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
231 f.debug_struct("RGBA")
232 .field("red", &self.red())
233 .field("green", &self.green())
234 .field("blue", &self.blue())
235 .field("alpha", &self.alpha())
236 .finish()
237 }
238}
239
240impl FromStr for RGBA {
241 type Err = glib::BoolError;
242 fn from_str(s: &str) -> Result<Self, Self::Err> {
243 skip_assert_initialized!();
244 RGBA::parse(s)
245 }
246}