partial_simple/
partial_simple.rs

1extern crate native_windows_gui2 as nwg;
2
3use nwg::{NativeUi, PartialUi};
4use std::{cell::RefCell, ops::Deref, rc::Rc};
5
6#[derive(Default)]
7pub struct MainUi {
8    window: nwg::Window,
9    form: SubmitForm,
10}
11
12#[derive(Default)]
13pub struct SubmitForm {
14    form_data: String,
15    layout: nwg::GridLayout,
16    value: nwg::TextInput,
17    sumbit_button: nwg::Button,
18}
19
20pub struct MainUiWrapper {
21    inner: Rc<MainUi>,
22    default_handler: RefCell<Vec<nwg::EventHandler>>,
23}
24
25impl nwg::NativeUi<MainUiWrapper> for MainUi {
26    fn build_ui(mut data: MainUi) -> Result<MainUiWrapper, nwg::NwgError> {
27        nwg::Window::builder()
28            .size((500, 200))
29            .position((500, 300))
30            .title("My Form")
31            .build(&mut data.window)?;
32
33        // !!! Partials controls setup !!!
34        SubmitForm::build_partial(&mut data.form, Some(&data.window))?;
35
36        let ui = MainUiWrapper {
37            inner: Rc::new(data),
38            default_handler: Default::default(),
39        };
40
41        // !!! Partials Event Binding !!!
42        let mut window_handles = vec![&ui.window.handle];
43        window_handles.append(&mut ui.form.handles());
44
45        for handle in window_handles.iter() {
46            let evt_ui = Rc::downgrade(&ui.inner);
47            let handle_events = move |evt, evt_data, handle| {
48                use nwg::Event as E;
49
50                if let Some(ui) = evt_ui.upgrade() {
51                    // !!! Partials Event Dispatch !!!
52                    ui.form.process_event(evt, &evt_data, handle);
53
54                    match evt {
55                        E::OnButtonClick => {
56                            if &handle == &ui.form.sumbit_button {
57                                println!("SAVING!");
58                            }
59                        }
60                        E::OnWindowClose => {
61                            if &handle == &ui.window {
62                                nwg::stop_thread_dispatch();
63                            }
64                        }
65                        _ => {}
66                    }
67                }
68            };
69
70            ui.default_handler
71                .borrow_mut()
72                .push(nwg::full_bind_event_handler(handle, handle_events));
73        }
74
75        return Ok(ui);
76    }
77}
78
79impl Deref for MainUiWrapper {
80    type Target = MainUi;
81
82    fn deref(&self) -> &MainUi {
83        &self.inner
84    }
85}
86
87impl PartialUi for SubmitForm {
88    fn build_partial<W: Into<nwg::ControlHandle>>(
89        data: &mut SubmitForm,
90        parent: Option<W>,
91    ) -> Result<(), nwg::NwgError> {
92        let parent = parent.unwrap().into();
93
94        nwg::TextInput::builder()
95            .text(&data.form_data)
96            .parent(&parent)
97            .build(&mut data.value)?;
98
99        nwg::Button::builder()
100            .text("Save")
101            .parent(&parent)
102            .build(&mut data.sumbit_button)?;
103
104        nwg::GridLayout::builder()
105            .child(0, 0, &data.value)
106            .child(0, 1, &data.sumbit_button)
107            .parent(&parent)
108            .build(&data.layout)?;
109
110        Ok(())
111    }
112
113    fn process_event<'a>(
114        &self,
115        evt: nwg::Event,
116        _evt_data: &nwg::EventData,
117        handle: nwg::ControlHandle,
118    ) {
119        use nwg::Event as E;
120
121        match evt {
122            E::OnButtonClick => {
123                if &handle == &self.sumbit_button {
124                    println!("PARTIAL EVENT!");
125                }
126            }
127            _ => {}
128        }
129    }
130
131    fn handles(&self) -> Vec<&nwg::ControlHandle> {
132        // No top level window in this partial
133        Vec::new()
134    }
135}
136
137fn main() {
138    nwg::init().expect("Failed to init Native Windows GUI");
139    nwg::Font::set_global_family("Segoe UI").expect("Failed to set default font");
140
141    let state = MainUi {
142        form: SubmitForm {
143            form_data: "Default Value".to_string(),
144            ..Default::default()
145        },
146        ..Default::default()
147    };
148
149    let _ui = MainUi::build_ui(state).expect("Failed to build UI");
150    nwg::dispatch_thread_events();
151}