gtk4/subclass/
range.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 subclassing [`Range`](crate::Range).
5
6use glib::translate::*;
7
8use crate::{ffi, prelude::*, subclass::prelude::*, Border, Range, ScrollType};
9
10pub trait RangeImpl: RangeImplExt + WidgetImpl {
11    fn adjust_bounds(&self, new_value: f64) {
12        self.parent_adjust_bounds(new_value)
13    }
14
15    fn change_value(&self, scroll_type: ScrollType, new_value: f64) -> glib::Propagation {
16        self.parent_change_value(scroll_type, new_value)
17    }
18
19    #[doc(alias = "get_range_border")]
20    fn range_border(&self) -> Border {
21        self.parent_range_border()
22    }
23
24    fn move_slider(&self, scroll_type: ScrollType) {
25        self.parent_move_slider(scroll_type)
26    }
27
28    fn value_changed(&self) {
29        self.parent_value_changed()
30    }
31}
32
33mod sealed {
34    pub trait Sealed {}
35    impl<T: super::RangeImplExt> Sealed for T {}
36}
37
38pub trait RangeImplExt: sealed::Sealed + ObjectSubclass {
39    fn parent_adjust_bounds(&self, new_value: f64) {
40        unsafe {
41            let data = Self::type_data();
42            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkRangeClass;
43            if let Some(f) = (*parent_class).adjust_bounds {
44                f(
45                    self.obj().unsafe_cast_ref::<Range>().to_glib_none().0,
46                    new_value,
47                )
48            }
49        }
50    }
51
52    fn parent_change_value(&self, scroll_type: ScrollType, new_value: f64) -> glib::Propagation {
53        unsafe {
54            let data = Self::type_data();
55            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkRangeClass;
56            let f = (*parent_class)
57                .change_value
58                .expect("No parent class impl for \"change_value\"");
59            from_glib(f(
60                self.obj().unsafe_cast_ref::<Range>().to_glib_none().0,
61                scroll_type.into_glib(),
62                new_value,
63            ))
64        }
65    }
66
67    fn parent_range_border(&self) -> Border {
68        unsafe {
69            let data = Self::type_data();
70            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkRangeClass;
71            let mut border = Border::default();
72            if let Some(f) = (*parent_class).get_range_border {
73                f(
74                    self.obj().unsafe_cast_ref::<Range>().to_glib_none().0,
75                    border.to_glib_none_mut().0,
76                );
77            }
78            border
79        }
80    }
81
82    fn parent_move_slider(&self, scroll_type: ScrollType) {
83        unsafe {
84            let data = Self::type_data();
85            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkRangeClass;
86            if let Some(f) = (*parent_class).move_slider {
87                f(
88                    self.obj().unsafe_cast_ref::<Range>().to_glib_none().0,
89                    scroll_type.into_glib(),
90                )
91            }
92        }
93    }
94
95    fn parent_value_changed(&self) {
96        unsafe {
97            let data = Self::type_data();
98            let parent_class = data.as_ref().parent_class() as *mut ffi::GtkRangeClass;
99            if let Some(f) = (*parent_class).value_changed {
100                f(self.obj().unsafe_cast_ref::<Range>().to_glib_none().0)
101            }
102        }
103    }
104}
105
106impl<T: RangeImpl> RangeImplExt for T {}
107
108unsafe impl<T: RangeImpl> IsSubclassable<T> for Range {
109    fn class_init(class: &mut glib::Class<Self>) {
110        Self::parent_class_init::<T>(class);
111
112        let klass = class.as_mut();
113        klass.adjust_bounds = Some(range_adjust_bounds::<T>);
114        klass.change_value = Some(range_change_value::<T>);
115        klass.get_range_border = Some(range_get_range_border::<T>);
116        klass.move_slider = Some(range_move_slider::<T>);
117        klass.value_changed = Some(range_value_changed::<T>);
118    }
119}
120
121unsafe extern "C" fn range_adjust_bounds<T: RangeImpl>(ptr: *mut ffi::GtkRange, new_value: f64) {
122    let instance = &*(ptr as *mut T::Instance);
123    let imp = instance.imp();
124
125    imp.adjust_bounds(new_value)
126}
127
128unsafe extern "C" fn range_change_value<T: RangeImpl>(
129    ptr: *mut ffi::GtkRange,
130    scroll_type: ffi::GtkScrollType,
131    new_value: f64,
132) -> glib::ffi::gboolean {
133    let instance = &*(ptr as *mut T::Instance);
134    let imp = instance.imp();
135
136    imp.change_value(from_glib(scroll_type), new_value)
137        .into_glib()
138}
139
140unsafe extern "C" fn range_get_range_border<T: RangeImpl>(
141    ptr: *mut ffi::GtkRange,
142    borderptr: *mut ffi::GtkBorder,
143) {
144    let instance = &*(ptr as *mut T::Instance);
145    let imp = instance.imp();
146
147    let border = imp.range_border();
148    *borderptr = *border.to_glib_none().0;
149}
150
151unsafe extern "C" fn range_move_slider<T: RangeImpl>(
152    ptr: *mut ffi::GtkRange,
153    scroll_type: ffi::GtkScrollType,
154) {
155    let instance = &*(ptr as *mut T::Instance);
156    let imp = instance.imp();
157
158    imp.move_slider(from_glib(scroll_type))
159}
160
161unsafe extern "C" fn range_value_changed<T: RangeImpl>(ptr: *mut ffi::GtkRange) {
162    let instance = &*(ptr as *mut T::Instance);
163    let imp = instance.imp();
164
165    imp.value_changed()
166}