basic/
basic.rs

1/*!
2    A very simple application that show your name in a message box.
3    See `basic_d` for the derive version
4*/
5
6extern crate native_windows_gui as nwg;
7use nwg::NativeUi;
8
9
10#[derive(Default)]
11pub struct BasicApp {
12    window: nwg::Window,
13    name_edit: nwg::TextInput,
14    hello_button: nwg::Button
15}
16
17impl BasicApp {
18
19    fn say_hello(&self) {
20        nwg::modal_info_message(&self.window, "Hello", &format!("Hello {}", self.name_edit.text()));
21    }
22    
23    fn say_goodbye(&self) {
24        nwg::modal_info_message(&self.window, "Goodbye", &format!("Goodbye {}", self.name_edit.text()));
25        nwg::stop_thread_dispatch();
26    }
27
28}
29
30//
31// ALL of this stuff is handled by native-windows-derive
32//
33mod basic_app_ui {
34    use native_windows_gui as nwg;
35    use super::*;
36    use std::rc::Rc;
37    use std::cell::RefCell;
38    use std::ops::Deref;
39
40    pub struct BasicAppUi {
41        inner: Rc<BasicApp>,
42        default_handler: RefCell<Option<nwg::EventHandler>>
43    }
44
45    impl nwg::NativeUi<BasicAppUi> for BasicApp {
46        fn build_ui(mut data: BasicApp) -> Result<BasicAppUi, nwg::NwgError> {
47            use nwg::Event as E;
48            
49            // Controls
50            nwg::Window::builder()
51                .flags(nwg::WindowFlags::WINDOW | nwg::WindowFlags::VISIBLE)
52                .size((300, 135))
53                .position((300, 300))
54                .title("Basic example")
55                .build(&mut data.window)?;
56
57            nwg::TextInput::builder()
58                .size((280, 35))
59                .position((10, 10))
60                .text("Heisenberg")
61                .parent(&data.window)
62                .focus(true)
63                .build(&mut data.name_edit)?;
64
65            nwg::Button::builder()
66                .size((280, 70))
67                .position((10, 50))
68                .text("Say my name")
69                .parent(&data.window)
70                .build(&mut data.hello_button)?;
71
72            // Wrap-up
73            let ui = BasicAppUi {
74                inner: Rc::new(data),
75                default_handler: Default::default(),
76            };
77
78            // Events
79            let evt_ui = Rc::downgrade(&ui.inner);
80            let handle_events = move |evt, _evt_data, handle| {
81                if let Some(ui) = evt_ui.upgrade() {
82                    match evt {
83                        E::OnButtonClick => 
84                            if &handle == &ui.hello_button {
85                                BasicApp::say_hello(&ui);
86                            },
87                        E::OnWindowClose => 
88                            if &handle == &ui.window {
89                                BasicApp::say_goodbye(&ui);
90                            },
91                        _ => {}
92                    }
93                }
94            };
95
96           *ui.default_handler.borrow_mut() = Some(nwg::full_bind_event_handler(&ui.window.handle, handle_events));
97
98            return Ok(ui);
99        }
100    }
101
102    impl Drop for BasicAppUi {
103        /// To make sure that everything is freed without issues, the default handler must be unbound.
104        fn drop(&mut self) {
105            let handler = self.default_handler.borrow();
106            if handler.is_some() {
107                nwg::unbind_event_handler(handler.as_ref().unwrap());
108            }
109        }
110    }
111
112    impl Deref for BasicAppUi {
113        type Target = BasicApp;
114
115        fn deref(&self) -> &BasicApp {
116            &self.inner
117        }
118    }
119}
120
121fn main() {
122    nwg::init().expect("Failed to init Native Windows GUI");
123    nwg::Font::set_global_family("Segoe UI").expect("Failed to set default font");
124    let _ui = BasicApp::build_ui(Default::default()).expect("Failed to build UI");
125    nwg::dispatch_thread_events();
126}