WARNING: Cushy is in early alpha. This guide doubly so.
Welcome to the Cushy User's Guide
This is a user's guide for Cushy, a Rust GUI crate. The documentation is a great resource for finding information about specific functionality quickly. This guide is aimed to providing an example-rich walkthrough of how to use and extend Cushy.
A "Hello, World" Example
Here's the simplest "Hello, World" example:
use cushy::Run; fn main() -> cushy::Result { "Hello, World!".run() }
When run, the app just displays the text as one would hope:
That was a little too easy. Let's take it a step further by letting a user type in their name and have a label display "Hello, {name}!":
use cushy::value::{Dynamic, Source}; use cushy::widget::MakeWidget; use cushy::widgets::input::{Input, InputValue}; use cushy::Run; fn main() -> cushy::Result { // Create storage for user to enter a name. let name: Dynamic<String> = Dynamic::default(); // Create our label by using `map_each` to format the name, first checking // if it is empty. let greeting = name.map_each(|name| { let name = if name.is_empty() { "World" } else { name }; format!("Hello, {name}!") }); // Create the input widget with a placeholder. let name_input: Input = name.into_input().placeholder("Name"); // Stack our widgets as rows, and run the app. name_input.and(greeting).into_rows().run() }
This app looks like this when executed:
In this example, both name
and greeting
are Dynamic<String>
s. A
Dynamic<T>
is an Arc<Mutex<T>>
-like type that is able to invoke a set of
callbacks when its contents is changed. This simple feature is the core of
Cushy's reactive data model.
Each time name
is changed, the map_each
closure will be executed and
greeting
will be updated with the result. Now that we have the individual
pieces of data our user interface is going to work with, we can start assembling
the interface.
First, we create name_input
by converting the Dynamic<String>
into a text
input widget (Input<String>
). Since Dynamic<String>
can be used as
a Label
, all that's left is laying out our two widgets.
To layout name_input
and greeting
, we use a Stack
to lay out the
widgets as rows.
Don't worry if this example seems a bit magical or confusing as to how it works. Cushy can feel magical to use. But, it should never be a mystery. The goal of this guide is to try and explain how and why Cushy works the way it does.