In this first chapter, you will install NWG and then look at a very simple application. This tutorial will intoduce the concepts of Control Templates, Actions and Events: the foundations of NWG. The next chapter "Basics" will go deeper into these.
cargo.toml
:
[dependencies] native-windows-gui = "0.1.0"And then, in
main.rs
or lib.rs
:
extern crate native_windows_gui as nwg;
extern crate native_windows_gui as nwg; use nwg::Ui; use nwg::events::EventCallback; use nwg::controls::{Button, Window, TextInput}; use nwg::actions::{Action, ActionReturn}; use nwg::actions::helper as actions_help; use nwg::constants::{HTextAlign, VTextAlign, MessageButtons, MessageIcons}; fn setup_controls(ui: &mut Ui<&'static str>) { let main_window = Window { caption: "Hello".to_string(), size: (200, 200), position: (100, 100), visible: true, resizable: false, exit_on_close: true }; let name_input = TextInput { text: "".to_string(), size: (180, 20), position: (10, 10), parent: "MainWindow", placeholder: Some("Your name Here".to_string()), text_align: HTextAlign::Left, password: false, readonly: false }; let hello_button = Button { text: "Say Hello!".to_string(), size: (180, 130), position: (10, 50), parent: "MainWindow", text_align: (HTextAlign::Center, VTextAlign::Center), }; ui.new_control("MainWindow", main_window).unwrap(); ui.new_control("Name", name_input).unwrap(); ui.new_control("Hello", hello_button).unwrap(); } fn main() { let mut ui: Ui<&'static str> = Ui::new(); setup_controls(&mut ui); ui.bind("Hello", "SayHello", EventCallback::Click(Box::new(|ui, caller|{ println!("Caller is: {:?}", caller); if let Ok(ActionReturn::Text(name)) = ui.exec("Name", Action::GetText) { let msg = actions_help::message( "Hello!", format!("Hello {}!", name), MessageButtons::Ok, MessageIcons::None ); ui.exec("MainWindow", msg).unwrap(); } }))).unwrap(); nwg::dispatch_events(); }
main
function creates the Ui object. You can think of it as some
kind of service. In fact, NWG Ui abstract the whole UI, this means that, as a developer, you don't have access to the
actual controls.
In order to expose the controls to the developer, NWG uses controls IDS. This way, controls can be accessed from
anywhere in the code without you having drag some kind of data along. The type of the ID is choosen by the developer, but
the it must implement the Eq+Clone+Hash
traits.
For this example the control id type is &'static str
. Using str
is great for visibility,
but it has one big inconvenient: you can't create controls on the fly.
Yup, with NWG all created controls must have a unique name. Because of this, using int
with
const
is usually a better idea. You could also use enums.(!Send + !Sync)
. This is a OS restriction, so it will never go away.
ControlTemplate
trait. NWG offers a wide variety of built-in controls. For more details see:
The Controls dictionnary. ui.new_control
. The first argument
is the unique control ID and the second is the template. The creation can fail if the ID already exists or if the
template configurations contains invalid values. bind
method of Ui. The first argument is the widget
identifer, the second is a user indentifier for the callback and the third is the EventCallback.
EventCallback
enum. The enum either
take a boxed fn
or a boxed closure
. The first two parameters are always the Ui and the
caller ID. Depending on the callback, more values can be passed.exec
method and then reading the returned ActionReturn.
The first parameter is the identifier of the control that will receive the event, the second is the action.ActionReturn::None
, furthermore, sending an unsupported action to a control
(ex: GetReadOnly of a label) is not considered an error. Instead ActionReturn::NotSupported
will be returned.Action/ActionReturn
enums. nwg::dispatch_events
in order to block the thread and
process the system events. The function will return once a Quit event is received.