gtk4/
spin_button.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{boxed::Box as Box_, mem::transmute};
4
5use glib::{
6    signal::{connect_raw, SignalHandlerId},
7    translate::*,
8};
9use libc::{c_double, c_int};
10
11use crate::{ffi, prelude::*, SpinButton};
12
13impl SpinButton {
14    pub fn connect_input<F>(&self, f: F) -> SignalHandlerId
15    where
16        F: Fn(&Self) -> Option<Result<f64, ()>> + 'static,
17    {
18        unsafe {
19            let f: Box_<F> = Box_::new(f);
20            connect_raw(
21                self.as_ptr() as *mut _,
22                b"input\0".as_ptr() as *mut _,
23                Some(transmute::<usize, unsafe extern "C" fn()>(
24                    input_trampoline::<F> as usize,
25                )),
26                Box_::into_raw(f),
27            )
28        }
29    }
30}
31
32unsafe extern "C" fn input_trampoline<F: Fn(&SpinButton) -> Option<Result<f64, ()>> + 'static>(
33    this: *mut ffi::GtkSpinButton,
34    new_value: *mut c_double,
35    f: &F,
36) -> c_int {
37    match f(SpinButton::from_glib_borrow(this).unsafe_cast_ref()) {
38        Some(Ok(v)) => {
39            *new_value = v;
40            glib::ffi::GTRUE
41        }
42        Some(Err(_)) => ffi::GTK_INPUT_ERROR,
43        None => glib::ffi::GFALSE,
44    }
45}