Native Windows GUI: Resources
Resources are non-ui components that are usually used by GUI controls. This includes images, fonts, cursors, and dialogs.
Most resource can be loaded from file, memory, or from embed resources.
This section will go over images, fonts, and cursors. The next section covers the dialog.
Images & Icons
Out of the box, winapi only supports bitmap (.bmp) and icons (.ico). Bitmap and icons are used by many controls, and some
meta resouces like
ImageList
. Use a
ImageFrame
control to display icons and bitmap in a Window.
By setting the
strict
builder parameter to
false
, NWG will load a default windows resource if the source file cannot be found
(instead of returning an error).
use native_windows_gui as nwg;
fn load_bitmap() -> nwg::Bitmap {
let mut bitmap = nwg::Bitmap::default();
nwg::Bitmap::builder()
.source_file(Some("Hello.bmp"))
.strict(true)
.build(&mut bitmap);
bitmap
}
Windows Imaging Component (WIC)
Now, because we're no longer in 3000 BC, you probably want to support more image types. Png and jpeg specifically. Thanksfully, NWG seamlessly wraps the
windows imaging component. This adds the following formats: .bmp(v5, with transparency), gif, ico, jpeg, png, tiff, vnd, and dds.
To enable the WIC, just use the
image-decoder
feature. When this is enabled, all the above formats will be supported by
Bitmap
.
The image decoder feature also enables the
ImageDecoder
resource. Which allows you load image files manually and read the pixel data.
Ability to load images from streams (ex the internet) will probably be added in the future (after the 1.0 release).
See the
image decoder example
Helper functions
The builder api can be cumbersome, that's why Native Windows GUI also includes helper functions to load resources in a single line.
The helper functions all have a similar signature:
Bitmap::from_*
,
Icon::from_*
.
You can also check out the
docs.rs documentation.
use native_windows_gui as nwg;
static EMBEDDED_BITMAP: &[u8] = include_bytes!("cat.jpg");
fn load_resources() -> Result<(), nwg::NwgError> {
let bitmap1 = nwg::Bitmap::from_file("hello.png", true)?;
let bitmap2 = nwg::Bitmap::from_bin(EMBEDDED_BITMAP)?;
let icon1 = nwg::Icon::from_file("hey.ico", true)?;
}
fn load_image_from_embedded() -> [Bitmap; 3] {
let embed = nwg::EmbedResource::load(None).unwrap();
/*
// myapp.rc
BALL BITMAP "ball.bmp"
HELLO IMAGE "test.png"
NICE IMAGE "test.jpg"
*/
[
nwg::Bitmap::from_embed(&embed, None, Some("BALL")),
nwg::Bitmap::from_embed(&embed, None, Some("HELLO")),
nwg::Bitmap::from_embed(&embed, None, Some("NICE")),
]
}
Fonts
Native-windows-gui supports
.ttf
and
.otf
font files. All controls that display text have a
set_font
and
get_font
method to set their font.
NWG has access to all the fonts families installed on the system. It's also possible to add new fonts temporarily using the
Font::add_font / Font::remove_font
or
Font::add_memory_font / Font::remove_memory_font
.
Those methods works globally.
use native_windows_gui as nwg;
fn main() {
nwg::Font::add_font("./MyFont.ttf");
// Application runtime
nwg::Font::remove_font("./MyFont.ttf");
}
Once the font families are loaded, a `Font` resource must be created. Just like the other resources, this is done using the Font builder.
use native_windows_gui as nwg;
fn build_font() -> nwg::Font {
let mut font = nwg::Font::default();
nwg::Font::builder()
.size(16)
.family("Arial")
.weight(1000)
.build(&mut font);
font
}
fn set_font(button: &nwg::Button, font: &nwg::Font) {
button.set_font(Some(font));
}
Cursors
Cursors are icons that can be used in place of the default Windows mouse cursor. Cursors can be custom, loaded from
.cur
files, or they can be loaded
from the system default cursors (using
OemCursor
).
Currently cursors can only be set globally using
GlobalCursor::set
(behind the
cursor
feature). Furthermore, this method must be called everytime the cursor moves in a control
because the default cursor is replaced automatically by Windows on mouse events. This behavior will probably change in the future.
use native_windows_gui as nwg;
fn set_cursor(window: &nwg::Window, cursor: nwg::Cursor) {
nwg::full_bind_event_handler(&window.handle, move |event, event_data, handle| {
match event {
nwg::Event::OnMousePress(_) | nwg::Event::OnMouseMove => {
nwg::GlobalCursor::set(&cursor)
},
_ => {}
}
});
}