1 unstable release

0.1.0-alpha.0 Apr 24, 2023

#207 in #reactive

21 downloads per month
Used in ori

MIT/Apache

335KB
7K SLoC

Ori

Ori is a framework for building user interfaces in a declarative manner.

Example

use ori_gtk4::prelude::*;

// Here we define our `Data`, the state of our application, this can be anything but in this case
// it's a struct with a `count` field.
struct Data {
    count: u32,
}

// The most important concept in Ori is the `View` trait. A `View` represents the current state of
// your UI based on your `Data`. The `ui` function is called every time the `Data` changes, or more
// accurately is estimated to change. The new `View` is then compared to the previous `View` and
// the differences are applied to the UI.
fn counter(data: &Data) -> impl View<Data> + use<> {
    let text = label(format!("Clicked {} times!", data.count));

    // A button is created, taking a closure mutating our `Data` when the button is clicked. Note
    // that this closure returns a type that can be converted into an `Action`. The default
    // `Action`, i.e. `()` the unit value, is to rebuild the UI by calling the `ui` function. Other
    // actions include sending `Events` or spawning futures.
    button(text, |data: &mut Data| data.count += 1)
        .halign(Align::Center)
        .valign(Align::Center)
}

// You might notice that `ui` returns an `Effect` rather than a `View`. An `Effect` is simply a
// `View` with no element, meaning it produces no UI and only represents a side-effect. `window` is
// an `Effect` because it *produces* no UI, it only creates a window that contains some UI.
fn ui(data: &mut Data) -> impl Effect<Data> + use<> {
    window(counter(data))
}

// Lastly we simply instantiate our data and run the app with our `ui` function.
fn main() {
    let data = Data { count: 0 };

    App::new().run(data, ui).unwrap();
}

Dependencies

~22–61MB
~1M SLoC