Overview
Inspired by [The Elm Architecture], Iced 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
We can build something to see how this works! Let’s say we want a simple counter that can be incremented and decremented using two buttons.
We start by modelling the state of our application:
#[derive(Default)]
struct Counter {
value: i32,
}
Next, we need to define the possible user interactions of our counter: the button presses. These interactions are our messages:
#[derive(Debug, Clone, Copy)]
pub enum Message {
Increment,
Decrement,
}
Now, let’s show the actual counter by putting it all together in our view logic:
use iced::widget::{button, column, text, Column};
impl Counter {
pub fn view(&self) -> Column<Message> {
// We use a column: a simple vertical layout
column![
// The increment button. We tell it to produce an
// `Increment` message when pressed
button("+").on_press(Message::Increment),
// We show the value of the counter here
text(self.value).size(50),
// The decrement button. We tell it to produce a
// `Decrement` message when pressed
button("-").on_press(Message::Decrement),
]
}
}
Finally, we need to be able to react to any produced messages and change our state accordingly in our update logic:
impl Counter {
// ...
pub fn update(&mut self, message: Message) {
match message {
Message::Increment => {
self.value += 1;
}
Message::Decrement => {
self.value -= 1;
}
}
}
}
And that’s everything! We just wrote a whole user interface. Let’s run it:
fn main() -> iced::Result {
iced::run("A cool counter", Counter::update, Counter::view)
}
Iced will automatically:
- Take the result of our view logic and layout its widgets.
- Process events from our system and produce messages for our update logic.
- Draw the resulting user interface.
Read the [book], the [documentation], and the [examples] to learn more!
Implementation details
Iced was originally born as an attempt at bringing the simplicity of [Elm] and [The Elm Architecture] into [Coffee], a 2D game engine I am working on.
The core of the library was implemented during May 2019 in this pull request.
The first alpha version was eventually released as
a renderer-agnostic GUI library. The library did not provide a renderer and
implemented the current tour example on top of ggez
, a game library.
Since then, the focus has shifted towards providing a batteries-included, end-user-oriented GUI library, while keeping the ecosystem modular: