# Pixel-widgets [![Documentation](https://docs.rs/pixel-widgets/badge.svg)](https://docs.rs/pixel-widgets) [![Crates.io](https://img.shields.io/crates/v/pixel-widgets.svg)](https://crates.io/crates/pixel-widgets) ![License](https://img.shields.io/crates/l/pixel-widgets.svg) 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`](component/trait.Component.html) based workflow - CSS like [styling](style/index.html) - Many built in [widgets](widget/index.html) - [wgpu](https://github.com/gfx-rs/wgpu) based renderer included # Overview User interfaces in pixel-widgets are composed of [`Component`](trait.Component.html)s. These components manage their own state, and generate ui elements when that state is mutated. Each component implements some methods: - [`view`](trait.Component.html#tymethod.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`](trait.Component.html#tymethod.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. ```rust 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. ```rust // The message type that will be used in our `Counter` component. #[derive(Clone)] enum Message { UpPressed, DownPressed, } ``` And finally, we must implement [`Component`](component/trait.Component.html) ```rust no_run 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, _context: Context) { 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](https://github.com/Kurble/pixel-widgets/tree/master/examples) in the git repository.