native-windows-gui 1.0.13

A rust library to develop native GUI applications on the desktop for Microsoft Windows. Native-windows-gui wraps the native win32 window controls in a rustic API
Documentation
use crate::*;
use winapi::um::winuser::WM_LBUTTONUP;
use std::cell::RefCell;


struct MessageBoxOnDrop {}

impl Drop for MessageBoxOnDrop {
    fn drop(&mut self) {
        simple_message("Dropped", "A MessageBoxOnDrop object was dropped");
    }
}


#[derive(Default)]
struct FreeingData {
    raw_handler_bound: bool,
    raw_callback_id: usize,
    raw_handler: Option<RawEventHandler>,

    handler_bound: bool,
    handler: Option<EventHandler>,
}

#[derive(Default)]
pub struct FreeingTest {
    data: RefCell<FreeingData>,
    pub window: Window,
    layout: GridLayout,
    bind_handler_btn: Button,
    custom_bind_button: Button,

    bind_handler_btn2: Button,
    custom_bind_button2: Button,
}

impl FreeingTest {

    pub fn destroy(&self) {
        let mut data = self.data.borrow_mut();
        if data.raw_handler_bound {
            data.raw_handler_bound = false;
            drop(unbind_raw_event_handler(&data.raw_handler.take().unwrap()));
        }
    }

    fn bind_raw_handler(&self) {
        let mut data = self.data.borrow_mut();
        if data.raw_handler_bound {
            self.bind_handler_btn.set_text("Bind raw handler");
            data.raw_handler_bound = false;
            
            if let Err(_) = unbind_raw_event_handler(&data.raw_handler.take().unwrap()) {
                error_message("Error", "Failed to free event handler");
            }
            
            assert!(has_raw_handler(&self.custom_bind_button.handle, data.raw_callback_id) == false);
        } else {
            self.bind_handler_btn.set_text("Unbind raw handler");
            data.raw_handler_bound = true;
            data.raw_callback_id += 1;

            let message = MessageBoxOnDrop{};
            let handler = bind_raw_event_handler_inner(&self.custom_bind_button.handle, data.raw_callback_id, move |_hwnd, msg, _w, _l| {
                if msg == WM_LBUTTONUP {
                    &message;
                    simple_message("Raw handler", &"Hello from raw dynamic handler");
                }
                None
            });

            assert!(has_raw_handler(&self.custom_bind_button.handle, data.raw_callback_id));

            data.raw_handler = Some(handler.unwrap());
        }
    }

    fn bind_handler(&self) {
        let mut data = self.data.borrow_mut();
        if data.handler_bound {
            self.bind_handler_btn2.set_text("Bind handler");
            data.handler_bound = false;
            unbind_event_handler(&data.handler.take().unwrap());
        } else {
            self.bind_handler_btn2.set_text("Unbind handler");
            data.handler_bound = true;

            let message = MessageBoxOnDrop{};
            let bind_handler_btn2 = self.custom_bind_button2.handle;

            let handler = bind_event_handler(&self.custom_bind_button2.handle, &self.window.handle, move |event, _event_data, ctrl| {
                match event {
                    Event::OnButtonClick => {
                        if &ctrl == &bind_handler_btn2 {    
                            &message;
                            simple_message("Handler", &"Hello from dynamic handler");
                        }
                    },
                    _ => {}
                }

                ()
            });

            data.handler = Some(handler);
        }
    }

}

mod partial_freeing_test_ui {
    use super::*;
    use crate::{PartialUi, NwgError, ControlHandle};

    impl PartialUi for FreeingTest {

        fn build_partial<W: Into<ControlHandle>>(data: &mut FreeingTest, _parent: Option<W>) -> Result<(), NwgError> {
            
            Window::builder()
                .flags(WindowFlags::WINDOW)
                .size((400, 150))
                .position((450, 100))
                .title("Freeing stuff")
                .build(&mut data.window)?;

            Button::builder()
                .text("Bind raw handler")
                .parent(&data.window)
                .build(&mut data.bind_handler_btn)?;

            Button::builder()
                .text("Do something!")
                .parent(&data.window)
                .build(&mut data.custom_bind_button)?;

            Button::builder()
                .text("Bind handler")
                .parent(&data.window)
                .build(&mut data.bind_handler_btn2)?;

            Button::builder()
                .text("Do something else!")
                .parent(&data.window)
                .build(&mut data.custom_bind_button2)?;

            GridLayout::builder()
                .parent(&data.window)
                .max_column(Some(2))
                .max_row(Some(2))
                .child(0, 0, &data.bind_handler_btn)
                .child(1, 0, &data.custom_bind_button)
                .child(0, 1, &data.bind_handler_btn2)
                .child(1, 1, &data.custom_bind_button2)
                .build(&data.layout)?;

            Ok(())
        }

        fn process_event<'a>(&self, evt: Event, mut _evt_data: &EventData, handle: ControlHandle) {
            use crate::Event as E;

            match evt {
                E::OnButtonClick => 
                    if &handle == &self.bind_handler_btn {
                        FreeingTest::bind_raw_handler(self)
                    } else if &handle == &self.bind_handler_btn2 {
                        FreeingTest::bind_handler(self)
                    }
                _ => {}
            }
        }

        fn handles(&self) -> Vec<&ControlHandle> {
            vec![&self.window.handle]
        }

    }
}