libadwaita/
spin_row.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use 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}