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