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}