gsk4/
color_stop.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::fmt;
4
5use crate::ffi;
6use gdk::RGBA;
7use glib::translate::*;
8
9glib::wrapper! {
10    /// A color stop in a gradient node.
11    #[doc(alias = "GskColorStop")]
12    pub struct ColorStop(BoxedInline<ffi::GskColorStop>);
13}
14
15impl ColorStop {
16    #[inline]
17    pub fn new(offset: f32, color: RGBA) -> Self {
18        assert_initialized_main_thread!();
19        unsafe {
20            Self::unsafe_from(ffi::GskColorStop {
21                offset,
22                color: *color.to_glib_none().0,
23            })
24        }
25    }
26
27    // rustdoc-stripper-ignore-next
28    /// Creates a new builder-pattern struct instance to construct [`ColorStop`]
29    /// objects.
30    ///
31    /// This method returns an instance of
32    /// [`ColorStopBuilder`](crate::builders::ColorStopBuilder) which can be
33    /// used to create [`ColorStop`] objects.
34    pub fn builder() -> ColorStopBuilder {
35        ColorStopBuilder::default()
36    }
37
38    #[inline]
39    pub fn offset(&self) -> f32 {
40        self.inner.offset
41    }
42
43    #[inline]
44    pub fn color(&self) -> &RGBA {
45        unsafe { &*(&self.inner.color as *const gdk::ffi::GdkRGBA as *const RGBA) }
46    }
47}
48
49impl fmt::Debug for ColorStop {
50    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51        f.debug_struct("ColorStop")
52            .field("offset", &self.offset())
53            .field("color", &self.color())
54            .finish()
55    }
56}
57
58#[derive(Clone, Default)]
59// rustdoc-stripper-ignore-next
60/// A [builder-pattern] type to construct [`ColorStop`] objects.
61///
62/// [builder-pattern]: https://doc.rust-lang.org/1.0.0/style/ownership/builders.html
63#[must_use = "The builder must be built to be used"]
64pub struct ColorStopBuilder(Vec<ColorStop>);
65
66impl ColorStopBuilder {
67    // rustdoc-stripper-ignore-next
68    /// Create a new [`ColorStopBuilder`].
69    pub fn new() -> Self {
70        Self::default()
71    }
72
73    pub fn at(mut self, offset: f32, color: RGBA) -> Self {
74        self.0.push(ColorStop::new(offset, color));
75        self
76    }
77
78    // rustdoc-stripper-ignore-next
79    /// Build the [`ColorStop`].
80    #[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
81    pub fn build(self) -> Vec<ColorStop> {
82        self.0
83    }
84}
85
86#[test]
87fn color_stop_builder() {
88    let t1 = ColorStop::builder()
89        .at(0.0, gdk::RGBA::RED)
90        .at(0.333, gdk::RGBA::RED)
91        .at(0.667, gdk::RGBA::BLUE)
92        .at(1.0, gdk::RGBA::RED)
93        .build();
94
95    let t2 = &[
96        ColorStop::new(0.0, gdk::RGBA::RED),
97        ColorStop::new(0.333, gdk::RGBA::RED),
98        ColorStop::new(0.667, gdk::RGBA::BLUE),
99        ColorStop::new(1.0, gdk::RGBA::RED),
100    ];
101
102    assert_eq!(t1.len(), t2.len(), "Arrays don't have the same length");
103    assert!(
104        &t1.iter()
105            .zip(t2.iter())
106            .all(|(a, b)| a.offset() == b.offset() && a.color() == b.color()),
107        "Arrays are not equal"
108    );
109}