fltk-derive 0.7.21

Rust bindings for the FLTK GUI library
Documentation
use crate::utils::get_fl_name;
use proc_macro::TokenStream;
use quote::*;
use syn::*;

pub fn impl_window_trait(ast: &DeriveInput) -> TokenStream {
    let name = &ast.ident;
    let name_str = get_fl_name(name.to_string());

    let make_modal = Ident::new(
        format!("{}_{}", name_str, "make_modal").as_str(),
        name.span(),
    );
    let fullscreen = Ident::new(
        format!("{}_{}", name_str, "fullscreen").as_str(),
        name.span(),
    );
    let make_current = Ident::new(
        format!("{}_{}", name_str, "make_current").as_str(),
        name.span(),
    );
    let set_icon = Ident::new(format!("{}_{}", name_str, "set_icon").as_str(), name.span());
    let icon = Ident::new(format!("{}_{}", name_str, "icon").as_str(), name.span());
    let set_border = Ident::new(
        format!("{}_{}", name_str, "set_border").as_str(),
        name.span(),
    );
    let border = Ident::new(format!("{}_{}", name_str, "border").as_str(), name.span());
    let make_resizable = Ident::new(
        format!("{}_{}", name_str, "make_resizable").as_str(),
        name.span(),
    );
    let set_cursor = Ident::new(
        format!("{}_{}", name_str, "set_cursor").as_str(),
        name.span(),
    );
    let shown = Ident::new(format!("{}_{}", name_str, "shown").as_str(), name.span());
    let raw_handle = Ident::new(
        format!("{}_{}", name_str, "raw_handle").as_str(),
        name.span(),
    );
    let set_raw_handle = Ident::new(
        format!("{}_{}", name_str, "set_raw_handle").as_str(),
        name.span(),
    );
    let region = Ident::new(format!("{}_{}", name_str, "region").as_str(), name.span());
    let set_region = Ident::new(format!("{}_{}", name_str, "set_region").as_str(), name.span());

    let gen = quote! {
        unsafe impl WindowExt for #name {
            fn center_screen(mut self) -> Self {
                assert!(!self.was_deleted());
                debug_assert!(self.width() != 0 && self.height() != 0, "center_screen requires the size of the widget to be known!");
                let (mut x, mut y) = screen_size();
                x -= self.width() as f64;
                y -= self.height() as f64;
                self.resize((x / 2.0) as i32, (y / 2.0) as i32, self.width(), self.height());
                self
            }

            fn make_modal(&mut self, val: bool) {
                assert!(!self.was_deleted());
                unsafe { #make_modal(self._inner, val as u32) }
            }

            fn fullscreen(&mut self, val: bool) {
                assert!(!self.was_deleted());
                unsafe { #fullscreen(self._inner, val as u32) }
            }

            fn make_current(&mut self) {
                assert!(!self.was_deleted());
                unsafe { #make_current(self._inner) }
            }

            fn set_icon<T: ImageExt>(&mut self, image: Option<T>) {
                assert!(!self.was_deleted());
                assert!(std::any::type_name::<T>() != std::any::type_name::<crate::image::SharedImage>(), "SharedImage icons are not supported!");
                if let Some(image) = image {
                    assert!(!image.was_deleted());
                    unsafe { #set_icon(self._inner, image.as_ptr()) }
                } else {
                    unsafe { #set_icon(self._inner, std::ptr::null_mut() as *mut raw::c_void) }
                }
            }

            fn icon(&self) -> Option<Image> {
                unsafe {
                    assert!(!self.was_deleted());
                    let icon_ptr = #icon(self._inner);
                    if icon_ptr.is_null() {
                        None
                    } else {
                        Some(Image::from_raw(icon_ptr as *mut fltk_sys::image::Fl_Image))
                    }
                }
            }

            fn make_resizable(&mut self, val: bool) {
                assert!(!self.was_deleted());
                if val {
                    unsafe {
                        #make_resizable(self._inner, self._inner as *mut raw::c_void)
                    }
                }
            }

            fn set_cursor(&mut self, cursor: Cursor) {
                assert!(!self.was_deleted());
                unsafe {
                    #set_cursor(self._inner, cursor as i32)
                }
            }

            fn shown(&self) -> bool {
                assert!(!self.was_deleted());
                unsafe {
                    match #shown(self._inner) {
                        0 => false,
                        _ => true,
                    }
                }
            }

            fn set_border(&mut self, flag: bool) {
                assert!(!self.was_deleted());
                unsafe {
                    #set_border(self._inner, flag as i32)
                }
            }

            fn border(&self) -> bool {
                assert!(!self.was_deleted());
                unsafe {
                    #border(self._inner) != 0
                }
            }

            fn raw_handle(&self) -> RawHandle {
                assert!(!self.was_deleted());
                unsafe {
                    let ptr = #raw_handle(self._inner);
                    assert!(!ptr.is_null());
                    let winid = resolve_raw_handle(ptr);

                    #[cfg(any(target_os = "windows", target_os = "macos", target_os = "android", target_os = "ios"))]
                    return winid.opaque;

                    #[cfg(any(
                        target_os = "linux",
                        target_os = "dragonfly",
                        target_os = "freebsd",
                        target_os = "netbsd",
                        target_os = "openbsd",
                    ))]
                    return winid.x_id;
                }
            }

            unsafe fn set_raw_handle(&mut self, handle: RawHandle) {
                assert!(!self.was_deleted());

                #[cfg(any(target_os = "windows", target_os = "macos", target_os = "android", target_os = "ios"))]
                assert!(!handle.is_null());

                #[cfg(any(
                    target_os = "linux",
                    target_os = "dragonfly",
                    target_os = "freebsd",
                    target_os = "netbsd",
                    target_os = "openbsd",
                ))]
                assert!(handle != 0);
                
                #set_raw_handle(self._inner, mem::transmute(&handle));
            }

            fn region(&self) -> crate::draw::Region {
                assert!(!self.was_deleted());
                unsafe {
                    let ptr = #region(self._inner);
                    assert!(!ptr.is_null());
                    ptr
                }
            }

            unsafe fn set_region(&mut self, region: crate::draw::Region) {
                assert!(!self.was_deleted());
                assert!(!region.is_null());
                #set_region(self._inner, region)
            }
        }
    };
    gen.into()
}