[][src]Module coffee::ui

Build a responsive graphical user interface for your game.

Basic concepts

The user interface runtime in Coffee is heavily inspired by Elm and The Elm Architecture.

Basically, user interfaces in Coffee are split into four different concepts:

  • state — data owned by the implementor of UserInterface
  • messages — user interactions or meaningful events that you care about
  • update logic — a way to react to messages and update your state
  • layout logic — a way to transform your state into widgets that may produce messages on user interaction

Getting started

Once you have implemented the Game trait, you can easily add a user interface to your game by implementing the UserInterface trait.

Let's take a look at a simple example with basic user interaction: an interactive counter that can be incremented and decremented using two different buttons.

use coffee::graphics::{Color, Window};
use coffee::ui::{button, Button, Column, Element, Renderer, Text, UserInterface};

// The state of our user interface
struct Counter {
    // The counter value
    value: i32,

    // Local state of the two counter buttons
    // This is internal widget state that may change outside our update
    // logic
    increment_button: button::State,
    decrement_button: button::State,

// The messages, user interactions that we are interested on
#[derive(Debug, Clone, Copy)]
pub enum Message {

impl UserInterface for Counter {
    // We use the message enum we just defined
    type Message = Message;

    // We can use the the built-in `Renderer`
    type Renderer = Renderer;

    // The update logic, called when a message is produced
    fn react(&mut self, message: Message, _window: &mut Window) {
        // We update the counter value after an interaction here
        match message {
            Message::IncrementPressed => {
                self.value += 1;
            Message::DecrementPressed => {
                self.value -= 1;

    // The layout logic, describing the different components of the user interface
    fn layout(&mut self, window: &Window) -> Element<Message> {
        // We use a column so the elements inside are laid out vertically
                // The increment button. We tell it to produce an
                // `IncrementPressed` message when pressed
                Button::new(&mut self.increment_button, "+")
                // We show the value of the counter here
                // The decrement button. We tell it to produce a
                // `DecrementPressed` message when pressed
                Button::new(&mut self.decrement_button, "-")
            .into() // We need to return a generic `Element`

The Game implementation is mostly irrelevant and was omitted in order to keep the example short. You can find the full source code of this example (and other examples too!) in the examples directory on GitHub.

Notice how UserInterface::react focuses on processing messages and updating state. On the other hand, UserInterface::layout only focuses on building the user interface from the current state. This separation of concerns will help you build composable user interfaces that are easy to debug and test!


Coffee provides some widgets and a Renderer out-of-the-box. However, you can build your own! Check out the core module to learn more!


pub use self::core::Align;
pub use self::core::Justify;
pub use widget::button;
pub use widget::image;
pub use widget::progress_bar;
pub use widget::slider;
pub use widget::Button;
pub use widget::Checkbox;
pub use widget::Image;
pub use widget::ProgressBar;
pub use widget::Radio;
pub use widget::Slider;
pub use widget::Text;



Customize your user interface with your own widgets and renderers.


Use the built-in widgets in your user interface.



The Renderer configuration.


A renderer capable of drawing all the built-in widgets.



The user interface of your game.

Type Definitions


A Column using the built-in Renderer.


An Element using the built-in Renderer.


A Panel using the built-in Renderer.


A Row using the built-in Renderer.