Skip to main content

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::{RGBA, ffi};
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    ///  can be either numbers in the range 0 to 100 or
202    /// percentages.
203    /// ## `spec`
204    /// the string specifying the color
205    ///
206    /// # Returns
207    ///
208    /// [`true`] if the parsing succeeded
209    #[doc(alias = "gdk_rgba_parse")]
210    pub fn parse(s: impl IntoGStr) -> Result<RGBA, glib::error::BoolError> {
211        skip_assert_initialized!();
212        unsafe {
213            s.run_with_gstr(|s| {
214                let mut res = RGBA::uninitialized();
215                glib::result_from_gboolean!(
216                    ffi::gdk_rgba_parse(res.to_glib_none_mut().0, s.as_ptr()),
217                    "Can't parse RGBA"
218                )
219                .map(|_| res)
220            })
221        }
222    }
223
224    pub const BLACK: RGBA = Self::new(0f32, 0f32, 0f32, 1f32);
225
226    pub const BLUE: RGBA = Self::new(0f32, 0f32, 1f32, 1f32);
227
228    pub const GREEN: RGBA = Self::new(0f32, 1f32, 0f32, 1f32);
229
230    pub const RED: RGBA = Self::new(1f32, 0f32, 0f32, 1f32);
231
232    pub const WHITE: RGBA = Self::new(1f32, 1f32, 1f32, 1f32);
233
234    pub const TRANSPARENT: RGBA = Self::new(0f32, 0f32, 0f32, 0f32);
235}
236
237impl fmt::Debug for RGBA {
238    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
239        f.debug_struct("RGBA")
240            .field("red", &self.red())
241            .field("green", &self.green())
242            .field("blue", &self.blue())
243            .field("alpha", &self.alpha())
244            .finish()
245    }
246}
247
248impl FromStr for RGBA {
249    type Err = glib::BoolError;
250    fn from_str(s: &str) -> Result<Self, Self::Err> {
251        skip_assert_initialized!();
252        RGBA::parse(s)
253    }
254}