gtk4/subclass/
color_chooser.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3// rustdoc-stripper-ignore-next
4//! Traits intended for implementing the [`ColorChooser`](crate::ColorChooser)
5//! interface.
6
7use gdk::RGBA;
8use glib::translate::*;
9
10use crate::{ffi, prelude::*, subclass::prelude::*, ColorChooser, Orientation};
11
12#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
13#[allow(deprecated)]
14pub trait ColorChooserImpl: ObjectImpl {
15    fn add_palette(&self, orientation: Orientation, colors_per_line: i32, colors: &[RGBA]) {
16        self.parent_add_palette(orientation, colors_per_line, colors);
17    }
18
19    fn color_activated(&self, rgba: RGBA) {
20        self.parent_color_activated(rgba);
21    }
22
23    #[doc(alias = "get_rgba")]
24    fn rgba(&self) -> RGBA;
25    fn set_rgba(&self, rgba: RGBA);
26}
27
28mod sealed {
29    pub trait Sealed {}
30    impl<T: super::ColorChooserImplExt> Sealed for T {}
31}
32
33#[cfg_attr(feature = "v4_10", deprecated = "Since 4.10")]
34#[allow(deprecated)]
35pub trait ColorChooserImplExt: sealed::Sealed + ObjectSubclass {
36    fn parent_add_palette(&self, orientation: Orientation, colors_per_line: i32, colors: &[RGBA]) {
37        unsafe {
38            let type_data = Self::type_data();
39            let parent_iface = type_data.as_ref().parent_interface::<ColorChooser>()
40                as *const ffi::GtkColorChooserInterface;
41
42            if let Some(func) = (*parent_iface).add_palette {
43                let colors_ptr: Vec<gdk::ffi::GdkRGBA> =
44                    colors.iter().map(|c| *c.to_glib_none().0).collect();
45
46                func(
47                    self.obj()
48                        .unsafe_cast_ref::<ColorChooser>()
49                        .to_glib_none()
50                        .0,
51                    orientation.into_glib(),
52                    colors_per_line,
53                    colors.len() as i32,
54                    mut_override(colors_ptr.as_ptr()),
55                )
56            }
57        }
58    }
59
60    fn parent_color_activated(&self, rgba: RGBA) {
61        unsafe {
62            let type_data = Self::type_data();
63            let parent_iface = type_data.as_ref().parent_interface::<ColorChooser>()
64                as *const ffi::GtkColorChooserInterface;
65
66            if let Some(func) = (*parent_iface).color_activated {
67                func(
68                    self.obj()
69                        .unsafe_cast_ref::<ColorChooser>()
70                        .to_glib_none()
71                        .0,
72                    rgba.to_glib_none().0,
73                )
74            }
75        }
76    }
77
78    fn parent_rgba(&self) -> RGBA {
79        unsafe {
80            let type_data = Self::type_data();
81            let parent_iface = type_data.as_ref().parent_interface::<ColorChooser>()
82                as *const ffi::GtkColorChooserInterface;
83
84            let func = (*parent_iface)
85                .get_rgba
86                .expect("no parent \"get_rgba\" implementation");
87            let rgba = std::ptr::null_mut();
88            func(
89                self.obj()
90                    .unsafe_cast_ref::<ColorChooser>()
91                    .to_glib_none()
92                    .0,
93                rgba,
94            );
95            from_glib_none(rgba)
96        }
97    }
98
99    fn parent_set_rgba(&self, rgba: RGBA) {
100        unsafe {
101            let type_data = Self::type_data();
102            let parent_iface = type_data.as_ref().parent_interface::<ColorChooser>()
103                as *const ffi::GtkColorChooserInterface;
104
105            if let Some(func) = (*parent_iface).set_rgba {
106                func(
107                    self.obj()
108                        .unsafe_cast_ref::<ColorChooser>()
109                        .to_glib_none()
110                        .0,
111                    rgba.to_glib_none().0,
112                )
113            }
114        }
115    }
116}
117
118impl<T: ColorChooserImpl> ColorChooserImplExt for T {}
119
120unsafe impl<T: ColorChooserImpl> IsImplementable<T> for ColorChooser {
121    fn interface_init(iface: &mut glib::Interface<Self>) {
122        let iface = iface.as_mut();
123
124        assert_initialized_main_thread!();
125
126        iface.add_palette = Some(color_chooser_add_palette::<T>);
127        iface.color_activated = Some(color_chooser_color_activated::<T>);
128        iface.get_rgba = Some(color_chooser_get_rgba::<T>);
129        iface.set_rgba = Some(color_chooser_set_rgba::<T>);
130    }
131}
132
133unsafe extern "C" fn color_chooser_add_palette<T: ColorChooserImpl>(
134    color_chooser: *mut ffi::GtkColorChooser,
135    orientation: ffi::GtkOrientation,
136    colors_per_line: i32,
137    total: i32,
138    colorsptr: *mut gdk::ffi::GdkRGBA,
139) {
140    let instance = &*(color_chooser as *mut T::Instance);
141    let imp = instance.imp();
142
143    let colors = if total == 0 {
144        &[]
145    } else {
146        std::slice::from_raw_parts(colorsptr as *const RGBA, total as usize)
147    };
148    imp.add_palette(from_glib(orientation), colors_per_line, colors);
149}
150
151unsafe extern "C" fn color_chooser_color_activated<T: ColorChooserImpl>(
152    color_chooser: *mut ffi::GtkColorChooser,
153    rgba: *const gdk::ffi::GdkRGBA,
154) {
155    let instance = &*(color_chooser as *mut T::Instance);
156    let imp = instance.imp();
157
158    imp.color_activated(from_glib_none(rgba))
159}
160
161unsafe extern "C" fn color_chooser_get_rgba<T: ColorChooserImpl>(
162    color_chooser: *mut ffi::GtkColorChooser,
163    rgbaptr: *const gdk::ffi::GdkRGBA,
164) {
165    let instance = &*(color_chooser as *mut T::Instance);
166    let imp = instance.imp();
167
168    let rgba = imp.rgba();
169    *(rgbaptr as *mut gdk::ffi::GdkRGBA) = *rgba.to_glib_none().0;
170}
171
172unsafe extern "C" fn color_chooser_set_rgba<T: ColorChooserImpl>(
173    color_chooser: *mut ffi::GtkColorChooser,
174    rgba: *const gdk::ffi::GdkRGBA,
175) {
176    let instance = &*(color_chooser as *mut T::Instance);
177    let imp = instance.imp();
178
179    imp.set_rgba(from_glib_none(rgba))
180}