gdk4/
rgba.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{fmt, str::FromStr};
4
5use glib::translate::*;
6
7use crate::{ffi, RGBA};
8
9#[derive(Debug)]
10// rustdoc-stripper-ignore-next
11/// A [builder-pattern] type to construct [`RGBA`] objects.
12///
13/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html
14#[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    // rustdoc-stripper-ignore-next
25    /// Create a new [`RGBABuilder`].
26    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    // rustdoc-stripper-ignore-next
51    /// Build the [`RGBA`].
52    #[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    // rustdoc-stripper-ignore-next
73    /// Creates an owned [`RGBA`] like `self` but with the given red value.
74    ///
75    /// # Example
76    ///
77    /// ```
78    /// # use gdk4::RGBA;
79    ///
80    /// let rgba = RGBA::new(1.0, 1.0, 1.0, 1.0);
81    /// assert_eq!(rgba.with_red(0.5), RGBA::new(0.5, 1.0, 1.0, 1.0));
82    /// ```
83    #[inline]
84    pub const fn with_red(self, red: f32) -> Self {
85        Self {
86            inner: ffi::GdkRGBA { red, ..self.inner },
87        }
88    }
89
90    // rustdoc-stripper-ignore-next
91    /// Creates an owned [`RGBA`] like `self` but with the given green value.
92    ///
93    /// # Example
94    ///
95    /// ```
96    /// # use gdk4::RGBA;
97    ///
98    /// let rgba = RGBA::new(1.0, 1.0, 1.0, 1.0);
99    /// assert_eq!(rgba.with_green(0.5), RGBA::new(1.0, 0.5, 1.0, 1.0));
100    /// ```
101    #[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    // rustdoc-stripper-ignore-next
112    /// Creates an owned [`RGBA`] like `self` but with the given blue value.
113    ///
114    /// # Example
115    ///
116    /// ```
117    /// # use gdk4::RGBA;
118    ///
119    /// let rgba = RGBA::new(1.0, 1.0, 1.0, 1.0);
120    /// assert_eq!(rgba.with_blue(0.5), RGBA::new(1.0, 1.0, 0.5, 1.0));
121    /// ```
122    #[inline]
123    pub const fn with_blue(self, blue: f32) -> Self {
124        Self {
125            inner: ffi::GdkRGBA { blue, ..self.inner },
126        }
127    }
128
129    // rustdoc-stripper-ignore-next
130    /// Creates an owned [`RGBA`] like `self` but with the given alpha value.
131    ///
132    /// # Example
133    ///
134    /// ```
135    /// # use gdk4::RGBA;
136    ///
137    /// let rgba = RGBA::new(1.0, 1.0, 1.0, 1.0);
138    /// assert_eq!(rgba.with_alpha(0.5), RGBA::new(1.0, 1.0, 1.0, 0.5));
139    /// ```
140    #[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    // rustdoc-stripper-ignore-next
151    /// Creates a new builder-pattern struct instance to construct [`RGBA`]
152    /// objects.
153    ///
154    /// This method returns an instance of
155    /// [`RGBABuilder`](crate::builders::RGBABuilder) which can be used to
156    /// create [`RGBA`] objects.
157    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    /// Parses a textual representation of a color.
202    ///
203    /// The string can be either one of:
204    ///
205    /// - A standard name (Taken from the CSS specification).
206    /// - A hexadecimal value in the form “\#rgb”, “\#rrggbb”,
207    ///   “\#rrrgggbbb” or ”\#rrrrggggbbbb”
208    /// - A hexadecimal value in the form “\#rgba”, “\#rrggbbaa”,
209    ///   or ”\#rrrrggggbbbbaaaa”
210    /// - A RGB color in the form “rgb(r,g,b)” (In this case the color
211    ///   will have full opacity)
212    /// - A RGBA color in the form “rgba(r,g,b,a)”
213    /// - A HSL color in the form "hsl(hue, saturation, lightness)"
214    /// - A HSLA color in the form "hsla(hue, saturation, lightness, alpha)"
215    ///
216    /// Where “r”, “g”, “b” and “a” are respectively the red, green,
217    /// blue and alpha color values. In the last two cases, “r”, “g”,
218    /// and “b” are either integers in the range 0 to 255 or percentage
219    /// values in the range 0% to 100%, and a is a floating point value
220    /// in the range 0 to 1.
221    /// ## `spec`
222    /// the string specifying the color
223    ///
224    /// # Returns
225    ///
226    /// [`true`] if the parsing succeeded
227    #[doc(alias = "gdk_rgba_parse")]
228    pub fn parse(s: impl IntoGStr) -> Result<RGBA, glib::error::BoolError> {
229        skip_assert_initialized!();
230        unsafe {
231            s.run_with_gstr(|s| {
232                let mut res = RGBA::uninitialized();
233                glib::result_from_gboolean!(
234                    ffi::gdk_rgba_parse(res.to_glib_none_mut().0, s.as_ptr()),
235                    "Can't parse RGBA"
236                )
237                .map(|_| res)
238            })
239        }
240    }
241
242    pub const BLACK: RGBA = Self::new(0f32, 0f32, 0f32, 1f32);
243
244    pub const BLUE: RGBA = Self::new(0f32, 0f32, 1f32, 1f32);
245
246    pub const GREEN: RGBA = Self::new(0f32, 1f32, 0f32, 1f32);
247
248    pub const RED: RGBA = Self::new(1f32, 0f32, 0f32, 1f32);
249
250    pub const WHITE: RGBA = Self::new(1f32, 1f32, 1f32, 1f32);
251
252    pub const TRANSPARENT: RGBA = Self::new(0f32, 0f32, 0f32, 0f32);
253}
254
255impl fmt::Debug for RGBA {
256    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
257        f.debug_struct("RGBA")
258            .field("red", &self.red())
259            .field("green", &self.green())
260            .field("blue", &self.blue())
261            .field("alpha", &self.alpha())
262            .finish()
263    }
264}
265
266impl FromStr for RGBA {
267    type Err = glib::BoolError;
268    fn from_str(s: &str) -> Result<Self, Self::Err> {
269        skip_assert_initialized!();
270        RGBA::parse(s)
271    }
272}