message_bank/
message_bank.rs1extern crate native_windows_gui2 as nwg;
7use nwg::NativeUi;
8use std::cell::RefCell;
9
10#[derive(Default)]
11pub struct MessageBank {
12 window: nwg::Window,
13 layout: nwg::GridLayout,
14
15 add_message_btn: nwg::Button,
16 message_title: nwg::TextInput,
17 message_content: nwg::TextInput,
18
19 buttons: RefCell<Vec<nwg::Button>>,
20 handlers: RefCell<Vec<nwg::EventHandler>>,
21}
22
23impl MessageBank {
24 fn add_message(&self) {
25 let title = self.message_title.text();
26 let content = self.message_content.text();
27
28 let mut new_button = Default::default();
29 nwg::Button::builder()
30 .text(&title)
31 .parent(&self.window)
32 .build(&mut new_button)
33 .expect("Failed to build button");
34
35 let mut buttons = self.buttons.borrow_mut();
36 let mut handlers = self.handlers.borrow_mut();
37
38 let blen = buttons.len() as u32;
39 let (x, y) = (blen % 6, blen / 6);
40 self.layout.add_child(x, y + 1, &new_button);
41
42 let new_button_handle = new_button.handle;
44 let handler = nwg::bind_event_handler(
45 &new_button.handle,
46 &self.window.handle,
47 move |evt, _evt_data, handle| match evt {
48 nwg::Event::OnButtonClick => {
49 if handle == new_button_handle {
50 nwg::simple_message(&title, &content);
51 }
52 }
53 _ => {}
54 },
55 );
56
57 buttons.push(new_button);
58 handlers.push(handler);
59 }
60
61 fn exit(&self) {
62 let handlers = self.handlers.borrow();
63 for handler in handlers.iter() {
64 nwg::unbind_event_handler(&handler);
65 }
66
67 nwg::stop_thread_dispatch();
68 }
69}
70
71mod message_bank_ui {
75 use super::*;
76 use native_windows_gui2 as nwg;
77 use std::cell::RefCell;
78 use std::ops::Deref;
79 use std::rc::Rc;
80
81 pub struct MessageBankUi {
82 inner: Rc<MessageBank>,
83 default_handler: RefCell<Vec<nwg::EventHandler>>,
84 }
85
86 impl nwg::NativeUi<MessageBankUi> for MessageBank {
87 fn build_ui(mut data: MessageBank) -> Result<MessageBankUi, nwg::NwgError> {
88 use nwg::Event as E;
89
90 nwg::Window::builder()
92 .flags(nwg::WindowFlags::MAIN_WINDOW | nwg::WindowFlags::VISIBLE)
93 .size((400, 300))
94 .position((800, 300))
95 .title("My message bank")
96 .build(&mut data.window)?;
97
98 nwg::TextInput::builder()
99 .text("Hello World!")
100 .focus(true)
101 .parent(&data.window)
102 .build(&mut data.message_content)?;
103
104 nwg::Button::builder()
105 .text("Save")
106 .parent(&data.window)
107 .build(&mut data.add_message_btn)?;
108
109 nwg::TextInput::builder()
110 .text("Title")
111 .parent(&data.window)
112 .build(&mut data.message_title)?;
113
114 let ui = MessageBankUi {
116 inner: Rc::new(data),
117 default_handler: Default::default(),
118 };
119
120 let window_handles = [&ui.window.handle];
122
123 for handle in window_handles.iter() {
124 let evt_ui = Rc::downgrade(&ui.inner);
125 let handle_events = move |evt, _evt_data, handle| {
126 if let Some(evt_ui) = evt_ui.upgrade() {
127 match evt {
128 E::OnButtonClick => {
129 if &handle == &evt_ui.add_message_btn {
130 MessageBank::add_message(&evt_ui);
131 }
132 }
133 E::OnWindowClose => {
134 if &handle == &evt_ui.window {
135 MessageBank::exit(&evt_ui);
136 }
137 }
138 _ => {}
139 }
140 }
141 };
142
143 ui.default_handler
144 .borrow_mut()
145 .push(nwg::full_bind_event_handler(handle, handle_events));
146 }
147
148 nwg::GridLayout::builder()
150 .parent(&ui.window)
151 .max_row(Some(6))
152 .child(0, 0, &ui.add_message_btn)
153 .child_item(nwg::GridLayoutItem::new(&ui.message_title, 1, 0, 2, 1))
154 .child_item(nwg::GridLayoutItem::new(&ui.message_content, 3, 0, 3, 1))
155 .build(&ui.layout)?;
156
157 return Ok(ui);
158 }
159 }
160
161 impl Drop for MessageBankUi {
162 fn drop(&mut self) {
164 let mut handlers = self.default_handler.borrow_mut();
165 for handler in handlers.drain(0..) {
166 nwg::unbind_event_handler(&handler);
167 }
168 }
169 }
170
171 impl Deref for MessageBankUi {
172 type Target = MessageBank;
173
174 fn deref(&self) -> &MessageBank {
175 &self.inner
176 }
177 }
178}
179
180fn main() {
181 nwg::init().expect("Failed to init Native Windows GUI");
182 nwg::Font::set_global_family("Segoe UI").expect("Failed to set default font");
183
184 let _ui = MessageBank::build_ui(Default::default()).expect("Failed to build UI");
185 nwg::dispatch_thread_events();
186}