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