Native windows gui nwg

Getting started

In this first chapter, you will install NWG and then look at a very simple application. This tutorial will use both native-windows-derive (the procedural macro to generate GUI’s from rust structs) and the plain native-window-gui api. The next chapter «Basics» will go deeper into these.

Installing NWG

Hello World!

The example in details

Basic project structure

Native-windows-gui uses structures to represent a UI interface. Controls are represent as members. It’s that simple.

Each control is a thin wrapper over a window handle (HWND). For more complex controls (such as listboxes), the control may contains extra data. All controls implements the Default trait. Default-built controls are considered uninitialized. Calling their methods will cause the program to panic.

Ui actions (displaying a message box in this case) should be implemented as structure methods. That is in no way a hard rule though. Any type of functions can be used. It just wraps nicely with the way the derive macro handles the events.

Native windows derive

By deriving NwgUi , Native-windows-derive can automatically generate the Ui code. The derive macro has no way to actually know how to actually create the controls, so more information must be provided over the fields.

nwg_control specifies the control parameters. The actual syntax is ident: expr . The parameters names maps directly to the control builder field (yes NWG uses builders to create controls, more on that later). Check a specific control documentation to see which parameters are available.

In this example, absolute positioning is used. Ex: position: (300, 300) . This is ok for this example because the window cannot be resized, but NWG also supports layouts.

nwg_events specifies the events that the control responds to. It take an array of EVENT_NAME: [callbacks] . Note that this is only the default way to dispatch events. nwg_events can be further customized to match all your callback needs. Again, check a specific control documentation to see which events can be raised.

The derive macro has other functions that are out of scope for this introduction, see the native-windows-derive section for more information.

Initialization

Native windows GUI needs to initialize a few things before being usable. This includes styles and loading some control classes. The initialization done by calling nwg::init() . This function should not fail, but if it does, it’s because the host system is really broken. In such case, the only thing left to do is to panic. Note that some helper functions (such as nwg::simple_message ) can still be called.

The next thing to do is to initialize your application. As mentionned in the previous step, this means instantiating your struct. native-windows-derive implements the NativeUi trait, which gives you the build_ui function. The build_ui function takes a single argument: the initial state of your application (aka your UI struct default state). Because this application is very simple, there’s no user state to initialize, so we just pass Default::default at let native-windows-derive do its magic.

Finally, the only thing left is to start listening for events on the thread. This is done by calling nwg::dispatch_thread_events() . This function will block the thread until nwg::stop_thread_dispatch() is called. NWG does not provide a default handler on window close, so you will have to manually bind the `OnWindowClose` event

Now lets looks a the inner workings of NWG in the next section.

Hello World! (no macro)

The implementation in details

Native UI

Implementing NativeUI is the recommended way to create native-windows-gui application. This example is very close to what native-windows-derive outputs. As mentioned in the previous section, all of the code logic is in build_ui .

Читайте также:  Windows cmd new file

For clarity, the method is separated in 3 steps: Controls, Wrap-up, and Events.

Controls

Native windows controls are built with builders. Each controls can instance a builder using the nwg::CONTROL::builder() method. Default values and builder parameters are available in the documentation.

The builder build function does not return the new control, instead you must pass a mutable reference to the function. This allows further customization of controls using DerefMut shenanigans.

The control build can fail. End the builder call with a ? to propagate the error to the caller.

Regarding controls, Native-windows-derive includes a few features that improves quality of life.

  • It can guess the parent based on the order of the controls. Otherwise, you need to use the parent builder method.
  • It unwraps the flags values. Going from «WINDOW|VISIBLE» to nwg::WindowFlags::WINDOW | nwg::WindowFlags::VISIBLE

Wrap up

To keep things clean, a new structure called [Control]Ui wraps the inner application data.

Before going further, the application data needs to be Rc’ed. This is because the application data needs to be shared between the events callbacks.

This is the way of doing things is used because it is the safest and simplest way to handle callbacks.

The ui wrapper also contains an handle to the default event handler. More on that in the next section.

Events

Okay. You might look at the way NWG handles events and tell yourself «wtf is this». Don’t stress out. It might be different from how other GUI platform handle events, but in the end, this way of doing things wraps very nicely with both Rust and the way events are dispatched in Windows.

In Winapi, events hooking can be done by «subclassing» a window. This is exactly what full_bind_event_handler do (with lots, lots of safety guards).

Every time an event is raised by the parent or it’s children, the callback will be called. Behind the scene, NWG will carefully parse the raw winapi parameters and return three simple values: an event Event , it’s data (if any) EventData , and the sender window handle ControlHandle .

You can see that there are no way to fetch our application data from these parameters. That’s why the application data (now behind a RC) is cloned and passed to the closure. A WeakRef is used here so that Drop can be called.

Inside the callback, the developer needs to do three things:

  • Match the event value. match evt
  • Check which control sent the event. &handle == &evt_ui.hello_button
  • Call the required functions BasicApp::say_hello(&evt_ui.inner);

Note that full_bind_event_handler applies to the parent and all its children. This means you only need to bind handlers on TOP LEVEL window. Lastly, the handler returned by full_bind_event_handler is saved in the wrapper struct under default_handler .

Freeing

Events handlers are not automatically unbound on drop. it must be done using nwg::unbind_event_handler(&handler)

Because we use a WeakRef in our event handler, the ui struct only has 1 strong refcount. This way we can unbind the event handler in the drop method.

And that is all for events handling. Thankfully, native-windows-derive handles all of this for us!

End note

Right now, you’ve learned about 50% of NWG. That’s enough to build small applications, but there’s two intermediate topics that you will want to learn: layouts, and resources handling (fonts, image). For larger applications you will want to look at more advanced topics such as UI partials, dynamic control creation, dynamic event binding (and unbinding), and multithreading.

Читайте также:  Что такое интерфейс ос windows не имеет

Good luck with your UI projects. Hopefully, NWG will be a good fit.

native-windows-gui
Release 1.0.11

A very light and simple rust GUI library

SourceRank 12

Documentation

Native Windows GUI

Welcome to Native Windows GUI (aka NWG). A rust library to develop native GUI applications on the desktop for Microsoft Windows.

NWG is a very light wrapper over WINAPI. It allows you, the developer, to handle the quirks and rough edges of the API by providing a simple, safe and rust-like interface.

Native Windows GUI keeps things simple. This means small compile times, minimal resource usage, less time searching the documentation and more time for you to develop your application.

Of course, you don’t have to take my word for it, check out the showcase and the examples.

This is the 3rd and final version of NWG. It is considered «mature» or, as I would say «the backlog is empty, and it will most likely stay that way». This version implements pretty much everything required to develop applications on Windows. Don’t bother using the older versions as they have «irreconcilable design decisions» and cannot support some key features. Future development will be done in other libraries.

If you’ve managed to read through this introduction, you should know that my twitter handle is #gdube_dev and you can support this project with GitHub Sponsors.

Any support is greatly appreciated.

To use NWG in your project add it to cargo.toml:

And then, in main.rs or lib.rs :

Rust 2018 aliasing

You can skip the extern crate define in your source code by adding the following code in Cargo.toml Note that procedural macros still require an extern crate definition, so this wont work with native-windows-derive

See it for yourself. NWG has plenty of examples and a fully interactive test suite. The only thing you need to do is:

Cross-compiling from Ubuntu

Requirement: MinGW compiler

Requirement: Rust support

Compiling and running basic example:

This is the main project git. It is separated in multiple sections

  • native-windows-gui
    • The base library. Includes an interactive test suite and plenty of examples
  • native-windows-derive
    • A procedural macro that generates the GUI application from rust structure (pretty cool stuff IMO)
  • docs/native-windows-docs read it online
    • Hefty documentation that goes over everything you need to know about NWG
  • showcase
    • Images of the examples. If you’ve made an NWG application and want to share it here, send me a message or open a PR. It’s free real estate.
  • The WHOLE winapi control library (reference)
    • Some very niche controls are not supported: flat scroll bar, ip control, rebar, and pager.
  • Menus and menu bar
  • Image and font resource
    • BMP
    • ICO
    • CUR
    • PNG*
    • GIF*
    • JPG*
    • TIFF*
    • DDS*
    • *: Extended image formats with the Windows Imaging Component (WIC).
  • Localization support
    • Uses Windows National Language Support internally (reference)
  • Tooltip
  • System tray notification
  • Cursor handling
  • A full clipboard wrapper
  • Partial templates support
    • Split large application into chunks
  • Dynamic controls support
    • Add/Remove controls at runtime
    • Bind or unbind new events at runtime
  • Multithreaded application support
    • Communicate to the GUI thread from another thread
    • Run multiple windows on different threads
  • Simple layout configurations
    • FlexboxLayout
    • GridLayout
  • Drag and drop
    • Drop files from the desktop to a window
  • The most common dialog boxes
    • File dialog (save, open, open folder)
    • Font dialog
    • Color dialog
  • A canvas that can be used by external rendering APIs
  • High-DPI aware
  • Support for accessibility functions
    • Tab navigation
  • Support for low level system message capture (HWND, MSG, WPARAM, LPARAM)
  • Cross compiling and testing from Linux to Windows with Wine and mingw.
    • Not all features are supported (but the majority are, thanks WINE!)
    • See https://zork.net/

      st/jottings/rust-windows-and-debian.html for the steps to follow

This was measured on a Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz, 3401 Mhz, 4 Core(s), 8 Logical Processor(s)

In release mode, the basic example weighs 163kb on disk and takes 900kb in memory. Launch time is instantaneous.

The interactive test suite (with every feature and 100s of tests) weighs 931 kb on disk and takes 8MB in memory. Launch time is still instantaneous.

Initial build time takes around 22 seconds for a basic application. This is mainly due to winapi-rs initial compile time. Subsequent compile time takes around 0.7 seconds.

The development of this library is considered «done». By that, I mean that there won’t be any change to the API. Issues can be raised if a bug is found or if some area in the documentation is unclear. If I overlooked a very important feature, it will most likely be added.

native-windows-gui 0.2.0

Native Windows GUI

Native Windows GUI (NWG) is a thin GUI toolkit built over the Microsoft Windows WINAPI for rust. The current version is 0.2.0 BETA 1 . The library is close to be production ready, but still lacks some important features and some useful controls and resources.

NWG uses retep998/winapi-rs and works on all rust channels and most rust versions. NWG was tested on Windows 8.1 and Windows 10 using the MSVC ABI build but any version of Microsoft Windows supported by Rust is supposed to be supported by NWG (vista and up).

Why NWG?

Is native-windows-gui the gui framework you are looking for? It is .

  • For those who wants to develop on Windows and want the smallest executable and memory footprint possible.
  • For those who LOVE hashmap. The UI are represented as hashmap-like objects (called the UI)
  • For those who don’t like dependencies. NWG only requires some winapi-rs crates and do not depends on external «executable» code
  • For those who want a canvas to draw pretty things, NWG has a very powerful (and light) canvas build over Direct2D
  • For those who don’t like to manage widgets (aka controls, aka stuff the user clicks on), NWG is for you. The UI manages the controls and the resources for you.
  • For those who like documentation, NWG has one ( and I think it’s pretty good ). Oh and its API is avaible online too: https://gabdube.github.io/native-windows-gui/
  • For those who want a light and simple API, NWG might be for you (ok, I’m totally biased on this one, external opinion required)
  • For those who want portability across system. Maybe it will work with WINE though.
  • For those who has to create controls on the fly. Each UI element requires a unique ID, which make this kind of UI harder to create
  • For those who want to deploy a production ready application as soon as possible. The first stable version will take some time to come out.
  • For those who want a safe api to create custom control, nwg is not there YET.
  • For those who want a UI to track a killers API address, Visual Basic is better (source: CSI)

Beta notes

The beta release is a rewrite , so the ALPHA code won’t work anymore. Most of the concepts remain though.

NWG now supports macro templates in order to make interface definition much less painful.

Installation

To use NWG in your project add it to cargo.toml:

And then, in main.rs or lib.rs :

Documentation

NWG has a complete documentation available here: https://gabdube.github.io/native-windows-gui/

The documentation alone should be enough to introduce to the basics of NWG.

(btw) If English is your first language (it’s not mine), it would be super kind to give me feedback about quality of the docs.

Example

Having cargo installed and in your PATH, execute the following code to run the included example:

Читайте также:  Увеличить шрифт windows 10 утилита
Оцените статью