This is a premium alert message you can set from Layout! Get Now!

Create and manage windows in your Rust app with Winit

0

Rust has been gaining popularity in the development community due to its speed, safety, and ability to handle complex tasks effectively. As Rust garners more recognition, developers want to create GUIs and manage windows in their Rust applications.

GUI frameworks and libraries are essential for building modern desktop applications and games. GUI tools allow you to create visually appealing UIs. Rust is home to many GUI libraries and frameworks, from Tauri to Druid, Slint, gtk-rs, and Winit.

Window management is an essential aspect of GUI programming and game development. Window managers are responsible for creating and managing the windows that make up a GUI. They also handle tasks such as drawing graphics, responding to user input, and managing the window’s position, size, and shape. In this article, we will explore how to create and manage windows in your Rust app with Winit.

Jump ahead:

What is Winit?

Winit is a lightweight, cross-platform window management library written in Rust that provides functionality for creating, managing, and controlling windows in Rust applications. Winit is designed to be agnostic and highly customizable, and it works seamlessly with other Rust libraries like OpenGL, making it an ideal choice for GUI and game development.

Key features of Winit

Several features built into Winit make the tool famous for creating GUIs for desktop and mobile devices.

The Winit Platform for Rust

Here are some of the features:

Windowing

Winit allows you to create windows easily, regardless of the platform. With Winit, you can create windows and set properties from size to position, title, and other properties. You can also listen to events like resizing, closing, and focus changes, resulting in a better UX.

Input handling

Input handling is an essential aspect of GUI development. Winit has inbuilt functionality for handling user input. Winit supports a mouse, keyboard, and touch input that you can use to create a seamless UX for interactivity.

Cross-platform support on mobile and desktop devices

Winit is cross-platform; you can use the library to create GUIs for various devices, including desktop and mobile devices. Winit supports platforms from Windows to Linux, macOS, iOS, and Android. You can use Winit to create applications for multiple platforms without learning a different tool for each platform.

Winit is a powerful tool for developers creating GUIs for desktop and mobile devices. With features such as windowing, input handling, cross-platform support, and extensive device support, Winit offers a versatile and reliable way to create graphical UIs. It is also free to use and modify as an open source tool, making it a popular choice for developers. Without Winit, creating interactive and engaging applications for various devices has always been challenging.

Getting started with Winit

Winit simplifies the process of window management. To get started with Winit, you’ll need to create a new Rust project. Run this command in the terminal of your working directory to create a Rust project with Cargo:

cargo new my_project

Next, you’ll need to add Winit as a dependency to your project. You can add Winit as a dependency by adding the following line to your Cargo.toml file:

[dependencies]
winit = "0.28.0"

This will download and install the specified version of Winit in your project. Now that you have Winit installed in your project, you can create and manage windows with Winit.

Creating windows with Winit

To create windows with Winit, refer to the following code:

use winit::{
    event_loop::EventLoop,
    window::{Window, WindowBuilder},
};

fn main() {
    let event_loop = EventLoop::new();
    let window = WindowBuilder::new().build(&event_loop).unwrap();

    event_loop.run(move |event, _, control_flow| {
        *control_flow = winit::event_loop::ControlFlow::Wait;

        match event {
            winit::event::Event::WindowEvent {
                event: winit::event::WindowEvent::CloseRequested,
                ..
            } => *control_flow = winit::event_loop::ControlFlow::Exit,
            _ => (),
        }
    });
}

The program creates a new event loop and window with the new method of the EventLoop and WindowBuilder structs. The run method of the EventLoop instance handles events with a closure.

The closure sets the control_flow variable to ControlFlow::Wait to keep the event loop running and then uses a match statement to check if the event is a WindowEvent with the CloseRequested variant. If it is, the closure sets the control_flow variable to ControlFlow::Exit, which causes the event loop to exit and terminate the program. Otherwise, the window stays on. Here’s what that looks like:

Example of Dark Theme With Winit

Using Winit for game and GUI development

One of the main use cases for Winit is for game and GUI development. Unfortunately, Winit doesn’t provide a direct method for drawing on windows. However, you can retrieve the raw handle of a window and display with the platform module, the raw_window_handle and raw_display_handle methods that allow you to create graphics with OpenGL, Vulkan, and Metal libraries that provide the functionality for drawing graphics. You’ll need to know these libraries to interoperate them with Winit.

Winit provides functionality for user input from the cursor and keyboard to text input. To accept keyboard input, you’ll use the KeyboardInput struct of the WindowEvent enum type. Here’s how you can accept keyboard input in your Winit app:

use winit::{event_loop::EventLoop, event::WindowEvent};
use winit::window::WindowBuilder;

fn main() {
    let event_loop = EventLoop::new();
    let window_builder = WindowBuilder::new()
        .with_title("My Window")
        .with_inner_size(winit::dpi::LogicalSize::new(800.0, 600.0));
    let window = window_builder.build(&event_loop).unwrap();

    event_loop.run(move |event, _, control_flow| {
        *control_flow = winit::event_loop::ControlFlow::Poll;

        match event {
            winit::event::Event::WindowEvent { event, .. } => match event {
                WindowEvent::KeyboardInput { input, .. } => {
                    match input.virtual_keycode {
                        Some(winit::event::VirtualKeyCode::Escape) => *control_flow = winit::event_loop::ControlFlow::Exit,
                        _ => (),
                    }
                },
                WindowEvent::CloseRequested => *control_flow = winit::event_loop::ControlFlow::Exit,
                _ => (),
            },
            _ => (),
        }
    });
}

The program creates a window with a title and size, and the event loop matches a key for the escape key on the keyboard that exits the window. On running the program and pressing the escape button, the program should exit the event loop and close the window.

Managing windows with Winit

Managing windows is one of the popular tasks you’ll perform with a windowing library. You can further customize Windows with Winit for your application, like setting the theme and window size. Winit provides methods with the window builder instance for customizing windows. You can use the with_theme method to set a theme and the with_inner_size method to set a window size. Take a look at the following code:

use winit::{event_loop::EventLoop, window::WindowBuilder};
use winit::window::Theme;

fn main() {
    let event_loop = EventLoop::new();
    let window_builder = WindowBuilder::new()
        .with_theme(Some(winit::window::Theme::Light))
        .with_title("My Window")
        .with_inner_size(winit::dpi::LogicalSize::new(800.0, 600.0));

    let window = window_builder.build(&event_loop).unwrap();

    event_loop.run(move |event, _, control_flow| {
        *control_flow = winit::event_loop::ControlFlow::Poll;

        match event {
            winit::event::Event::WindowEvent { event, .. } => match event {
                winit::event::WindowEvent::CloseRequested => *control_flow = winit::event_loop::ControlFlow::Exit,
                _ => (),
            },
            _ => (),
        }
    });
}

The program creates a window of 800 by 600, and the theme is set to Light instead of the default dark. Here’s what that looks like:

Example of Light Theme With Winit

Additionally, you can use the set_outer_position method to set the position for a window on the screen, like so:

use winit::dpi::LogicalPosition;

let window = window_builder.build(&event_loop).unwrap();
    window.set_outer_position(LogicalPosition::new(100, 100));

The LogicalPosition struct instance takes in the width and height for positioning. You can resize windows with the with_resizable method of the window builder instance that takes in a Boolean value, like so:

let window = WindowBuilder::new()
    .with_title("Resizable Window")
    .with_resizable(true)
    .build(&event_loop)
    .unwrap();

Additionally, you can set a window to full-screen mode with the with_fullscreen method that takes in a windowed context:

let window = WindowBuilder::new()
    .with_title("Fullscreen Window")
    .with_fullscreen(Some(windowed_context.get_primary_monitor()))
    .build(&event_loop)
    .unwrap();

You can also configure your windows for minimizing and maximizing with the set_minimized and set_maximized methods of the window builder instance:

window.set_minimized(true);
window.set_maximized(true);

As seen above, the two methods take in a Boolean value.

Conclusion

You’ve learned about the Winit library and its features and functionalities. You also learned how to create and manage windows for your Rust app with Winit. Winit is versatile and cross-platform, making the library a must-have in your platform development arsenal.

The post Create and manage windows in your Rust app with Winit appeared first on LogRocket Blog.



from LogRocket Blog https://ift.tt/vYgSuZE
Gain $200 in a week
via Read more

Post a Comment

0 Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.
Post a Comment

Search This Blog

To Top