Derive Macro native_windows_derive::NwgUi
source · [−]#[derive(NwgUi)]
{
// Attributes available to this derive:
#[nwg_control]
#[nwg_resource]
#[nwg_events]
#[nwg_layout]
#[nwg_layout_item]
#[nwg_partial]
}
Expand description
The NwgUi
macro implements the native-windows-gui NativeUi
trait on the selected struct
For a detailed documentation of this macro see the documentation “native-windows-docs/nwd_basics.html”
Usage
use native_windows_gui as nwg;
#[derive(NwgUi, Default)]
pub struct BasicApp {
#[nwg_control(title: "Window")]
#[nwg_events( OnWindowClose: [nwg::stop_thread_dispatch()] )]
window: nwg::Window,
#[nwg_resource(family: "Arial")]
font: nwg::Font,
#[nwg_layout(parent: window)]
my_layout: nwg::GridLayout,
#[nwg_control(text: "Button")]
#[nwg_layout_item(layout: my_layout, col: 0, row: 0)]
button: nwg::Button,
}
// ...
let my_ui = BasicAppUi::build_ui(Default::default()).unwrap();
The macro creates a new struct named [StructName]Ui
in a submodule named [struct_name]_ui
.
The trait NativeUi
is implemented on this struct and the boilerplate code is generated for every field tagged by attributes.
Fields without attributes, even nwg
types, are left untouched.
Finally, the derive macro also creates a default event handler that will live through the ui struct lifetime.
Attributes usage
Actual UI creation works by tagging the struct fields with the some attributes
Controls
Use the nwg_control
attribute to instance a control from a struct field:
nwg_control(builder_field: builder_value,*)
This syntax is basically a compressed version of the nwg control builders. The control attribute also has built-in helpers: auto parent detection and compressed flags syntax (see the docs for more info on these features).
#[nwg_control(text: "Heisenberg", size: (280, 25), position: (10, 10))]
name_edit: nwg::TextInput,
// is the same as
nwg::TextInput::builder()
.text("Heisenberg")
.size((280, 25))
.position((10, 10))
.build(&mut data.text_edit);
Resources
Use the nwg_resource
to generate a resource from a struct field. It works the exact same way as nwg_controls
.
Resources are always instanced before the controls.
Events
Use the nwg_events
attribute to add events to the default event handler. Events can only be applied to a field that
was tagged with nwg_control
.
nwg_events( EVENT_TYPE: [CALLBACK(ARGS),*] )
where:
- EVENT_TYPE is any value of the Event enum.
- CALLBACK is the function that will be called when the event is triggered.
- ARGS specifies the parameters of the callback (optional).
Events arguments
By default, native windows derive assumes the callback is a method of the Ui structure. So for example,
TestApp::callback1
assumes the method has the following signature callback1(&self)
.
That’s very limiting. For example, if the same callback is used by two different controls, there’s no way to differenciate them. In order to fix this, NWD lets you define the callbacks parameters using those identifiers:
- SELF: Sends the ui struct
&UiStruct
. If there are no parameters, this is the default. - RC_SELF: Sends the rc ui struct
&Rc<UiStruct>
. Useful for binding dynamic events - CTRL: Sends the control that triggered the event. Ex:
&Button
- HANDLE: Sends the handle of the control.
&ControlHandle
- EVT: Sends the event that was triggered.
&Event
- EVT_DATA: Sends the data of the event that was triggered.
&EventData
It’s also possible to not use any parameters, ex: TestApp::callback1()
.
Different event types:
struct TestApp {
#[nwg_control]
#[nwg_events(
OnButtonClick: [TestApp::callback1, TestApp::callback2],
OnMouseMove: [TestApp::callback3(SELF, CTRL)],
OnButtonDoubleClick: [callback, another_callback()]
)]
button: nwg::Button
}
fn callback(me: &TestApp) {}
fn another_callback() {}
impl TestApp {
fn callback1(&self) { }
fn callback2(&self) { }
fn callback3(&self, ctrl: &nwg::Button) { }
}
Layouts
Use the nwg_layout
attribute to instance a layout from a struct field and nwg_layout_item
to associate a control to a layout.
Under the hood, both these attribute work the same way as nwg_control
. nwg_layout
uses the builder attribute for a the layout struct and
nwg_layout_item
uses the parameters of the item type of the parent (ex: GridLayoutItem
for GridLayout
).
NWD cannot guess the parent of layout items.
Partials
Use the nwg_partial
attribute to instance a partial from a struct field:
If parts of your UI is another struct that implements the PartialUi
trait, it can be easily included in your base UI using nwg_partial
.
The attribute accepts an optional parameter “parent” to pass a parent control to the partial initializer. Unlike the parent in nwg_controls
,
it must be explicitly defined.
nwg_partial works by calling PartialUi::build_partial
after initializing the controls of the base UI, calling PartialUi::process_event
in the default event handler,
and binds the default handler to the handles returned by PartialUi::handles
Also see NwgPartial
for the macro to generate a nwg partial.
struct Ui {
window: nwg::Window,
#[nwg_partial(parent: window)]
partial: MyPartial
}