iced/README.md
Héctor Ramón Jiménez 880a101a35 Update README
2019-08-25 19:46:41 +02:00

5.7 KiB

Iced   Build Status Documentation Crates.io License

A simple GUI runtime for Rust, heavily inspired by Elm.

Iced is in a very early stage of development. Many basic features are still missing and there are probably many bugs. Feel free to contribute!

UI Tour - Coffee

Features

  • Simple, easy-to-use, macro-free API
  • Responsive, flexbox-based layouting
  • Type-safe, reactive programming model
  • Many built-in widgets
  • Custom widget support
  • Renderer-agnostic runtime

Installation

Add iced as a dependency in your Cargo.toml:

iced = "0.1"

Iced moves fast and the master branch can contain breaking changes! If you want to learn about a specific release, check out the release list.

Overview

Iced is heavily inspired by Elm and The Elm Architecture and it expects you to split user interfaces into four different concepts:

  • State — the state of your application
  • Messages — user interactions or meaningful events that you care about
  • View logic — a way to display your state as widgets that may produce messages on user interaction
  • Update logic — a way to react to messages and update your state

Let's say we want to build an interactive counter that can be incremented and decremented using two different buttons.

We start by modelling the state of our application:

use iced::button;

struct Counter {
    // The counter value
    value: i32,

    // The local state of the two buttons
    increment_button: button::State,
    decrement_button: button::State,
}

Now that we have state, what are the user interactions we care about? The button presses! These are our messages:

#[derive(Debug, Clone, Copy)]
pub enum Message {
    IncrementPressed,
    DecrementPressed,
}

Next, let's put it all together in our view logic:

use iced::{Button, Column, Text};

impl Counter {
    fn view(&mut self) -> Column<Message> {
        // We use a column: a simple vertical layout
        Column::new()
            .push(
                // The increment button. We tell it to produce an
                // `IncrementPressed` message when pressed
                Button::new(&mut self.increment_button, "+")
                    .on_press(Message::IncrementPressed),
            )
            .push(
                // We show the value of the counter here
                Text::new(&self.value.to_string()).size(50),
            )
            .push(
                // The decrement button. We tell it to produce a
                // `DecrementPressed` message when pressed
                Button::new(&mut self.decrement_button, "-")
                    .on_press(Message::DecrementPressed),
            )
    }
}

Finally, we need to be able to react to the messages and mutate our state accordingly in our update logic:

impl Counter {
    // ...

    fn update(&mut self, message: Message) {
        match message {
            Message::IncrementPressed => {
                self.value += 1;
            }
            Message::DecrementPressed => {
                self.value -= 1;
            }
        }
    }
}

And that's everything! We just wrote a whole user interface. Iced is now able to:

  1. Take the result of our view logic and build a user interface.
  2. Process events representing user interactions and produce messages for our update logic.
  3. Draw the resulting user interface using our own custom renderer.

Browse the documentation and the examples to learn more!

UI Tour - Coffee

Implementation details

Iced was originally born as part of Coffee, a 2D game engine I am working on, as an attempt at bringing the simplicity of Elm and The Elm Architecture into Rust.

Currently, Iced builds upon

Contributing / Feedback

If you want to contribute, you are more than welcome to be a part of the project! Check out the current issues if you want to find something to work on. Try to share you thoughts first! Feel free to open a new issue if you want to discuss new ideas.

Any kind of feedback is welcome! You can open an issue or, if you want to talk, you can find me (and a bunch of awesome folks) over the #gui-and-ui channel in the Rust Community Discord. I go by @lone_scientist there.