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