extern crate native_windows_gui as nwg;
extern crate native_windows_derive as nwd;
use nwd::NwgUi;
use nwg::NativeUi;
use std::{thread, cell::RefCell};
#[derive(Default, NwgUi)]
pub struct YesNoDialog {
data: RefCell<Option<String>>,
#[nwg_control(size: (300, 115), position: (650, 300), title: "A dialog", flags: "WINDOW|VISIBLE")]
#[nwg_events( OnWindowClose: [YesNoDialog::close] )]
window: nwg::Window,
#[nwg_control(text: "YES", position: (10, 10), size: (130, 95))]
#[nwg_events( OnButtonClick: [YesNoDialog::choose(SELF, CTRL)] )]
choice_yes: nwg::Button,
#[nwg_control(text: "NO", position: (160, 10), size: (130, 95), focus: true)]
#[nwg_events( OnButtonClick: [YesNoDialog::choose(SELF, CTRL)] )]
choice_no: nwg::Button,
}
impl YesNoDialog {
fn popup(sender: nwg::NoticeSender) -> thread::JoinHandle<String> {
thread::spawn(move || {
let app = YesNoDialog::build_ui(Default::default()).expect("Failed to build UI");
nwg::dispatch_thread_events();
sender.notice();
app.data.take().unwrap_or("Cancelled!".to_owned())
})
}
fn close(&self) {
nwg::stop_thread_dispatch();
}
fn choose(&self, btn: &nwg::Button) {
let mut data = self.data.borrow_mut();
if btn == &self.choice_no {
*data = Some("No!".to_string());
} else if btn == &self.choice_yes {
*data = Some("Yes!".to_string());
}
self.window.close();
}
}
#[derive(Default, NwgUi)]
pub struct ThreadingApp {
dialog_data: RefCell<Option<thread::JoinHandle<String>>>,
#[nwg_control(size: (300, 115), position: (300, 300), title: "Multithreading example", flags: "WINDOW|VISIBLE")]
#[nwg_events( OnWindowClose: [ThreadingApp::exit] )]
window: nwg::Window,
#[nwg_control]
#[nwg_events( OnNotice: [ThreadingApp::read_dialog_output] )]
dialog_notice: nwg::Notice,
#[nwg_control(size: (280, 25), position: (10, 10), readonly: true)]
name_edit: nwg::TextInput,
#[nwg_control(text: "Open Dialog", size: (280, 60), position: (10, 40), focus: true)]
#[nwg_events( OnButtonClick: [ThreadingApp::open_dialog] )]
button: nwg::Button,
}
impl ThreadingApp {
fn exit(&self) {
nwg::stop_thread_dispatch();
}
fn open_dialog(&self) {
self.button.set_enabled(false);
*self.dialog_data.borrow_mut() = Some(YesNoDialog::popup(self.dialog_notice.sender()));
}
fn read_dialog_output(&self) {
self.button.set_enabled(true);
let data = self.dialog_data.borrow_mut().take();
match data {
Some(handle) => {
let dialog_result = handle.join().unwrap();
self.name_edit.set_text(&dialog_result);
self.button.set_focus();
},
None => {}
}
}
}
fn main() {
nwg::init().expect("Failed to init Native Windows GUI");
nwg::Font::set_global_family("Segoe UI").expect("Failed to set default font");
let _app = ThreadingApp::build_ui(Default::default()).expect("Failed to build UI");
nwg::dispatch_thread_events();
}