gtk4/
spin_button.rs
1use 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
30 where
31 F: Fn(&Self) -> Option<Result<f64, ()>> + 'static,
32 {
33 unsafe {
34 let f: Box_<F> = Box_::new(f);
35 connect_raw(
36 self.as_ptr() as *mut _,
37 b"input\0".as_ptr() as *mut _,
38 Some(transmute::<usize, unsafe extern "C" fn()>(
39 input_trampoline::<F> as usize,
40 )),
41 Box_::into_raw(f),
42 )
43 }
44 }
45}
46
47unsafe extern "C" fn input_trampoline<F: Fn(&SpinButton) -> Option<Result<f64, ()>> + 'static>(
48 this: *mut ffi::GtkSpinButton,
49 new_value: *mut c_double,
50 f: &F,
51) -> c_int {
52 match f(SpinButton::from_glib_borrow(this).unsafe_cast_ref()) {
53 Some(Ok(v)) => {
54 *new_value = v;
55 glib::ffi::GTRUE
56 }
57 Some(Err(_)) => ffi::GTK_INPUT_ERROR,
58 None => glib::ffi::GFALSE,
59 }
60}