Crate pixel_widgets[][src]

Expand description

Pixel-widgets

Documentation Crates.io License

pixel-widgets is a component based user interface library focused on integratability in graphical applications.

Features

  • Very compact and easy API
  • API agnostic rendering
  • Component based workflow
  • CSS like styling
  • Many built in widgets
  • wgpu based renderer included

Overview

User interfaces in pixel-widgets are composed of Components. These components manage their own state, and generate ui elements when that state is mutated. Each component implements some methods:

  • view - this method renders the ui elements for the current component state. When the state is updated, the view will be rendered again. method:
  • update - ui elements generate messages that will be passed to the update method. In here, a component will update it’s internal state based on these messages.

Quick start

This example shows how to define a component and run it in the included sandbox. More work is required if you want to use pixel-widgets in your own game engine.

use pixel_widgets::prelude::*;

// The main component for our simple application
struct Counter {
    initial_value: i32,
}

Then, we have to define a message type. The message type should be able to tell us what happend in the ui.

// The message type that will be used in our `Counter` component.
#[derive(Clone)]
enum Message {
    UpPressed,
    DownPressed,
}

And finally, we must implement Component

use pixel_widgets::prelude::*;

// The main component for our simple application
#[derive(Default)]
struct Counter {
    initial_value: i32,
}

// The message type that will be used in our `Counter` component.
#[derive(Clone)]
enum Message {
    UpPressed,
    DownPressed,
}

impl Component for Counter {
    type State = i32;
    type Message = Message;
    type Output = ();

    // Creates the state of our component when it's first constructed.
    fn mount(&self) -> Self::State {
        self.initial_value
    }

    // Generates the widgets for this component, based on the current state.
    fn view<'a>(&'a self, state: &'a i32) -> Node<'a, Message> {
        // You can build the view using declarative syntax with the view! macro,
        //  but you can also construct widgets using normal rust code.
        view! {
            Column => {
                Button { text: "Up", on_clicked: Message::UpPressed }
                Text { val: format!("Count: {}", *state) }
                Button { text: "Down", on_clicked: Message::DownPressed }
            }
        }
    }

    // Updates the component state based on a message.
    fn update(&self, message: Message, mut state: State<i32>, _context: Context<Message, ()>) {
        match message {
            Message::UpPressed => *state += 1,
            Message::DownPressed => *state -= 1,
        }
    }
}

#[tokio::main]
async fn main() {
    use winit::window::WindowBuilder;

    Sandbox::new(
        Counter { initial_value: 15 }, 
        StyleBuilder::default(), 
        WindowBuilder::new()
            .with_title("Counter")
            .with_inner_size(winit::dpi::LogicalSize::new(240, 240))
    )
    .await
    .expect("failed to load style")
    .run()
    .await;
}

Examples

If you want more examples, check out the examples directory in the git repository.

Modules

Backend specific code

Texture cache for styles and text

The component trait.

Primitives used for drawing

User input events

Graphics loader

Primitives used for layouts

User interface building blocks

Prelude module for pixel-widgets.

Simple windowing system for those who want to render just widgets.

Styling system

Primitives for rendering text

Utility for tracking state conveniently.

User interface widgets Widgets are defined using the Widget trait. You can choose to implement widgets yourself, or you can use the built in widgets defined in this module.

Macros

The view! macro

Structs

Entry point for the user interface.