2 releases

0.1.0-alpha.1 Apr 24, 2023

#240 in #reactive

Download history 82/week @ 2024-02-19 60/week @ 2024-02-26 7/week @ 2024-03-04 13/week @ 2024-03-11 4/week @ 2024-03-18 14/week @ 2024-03-25 55/week @ 2024-04-01

88 downloads per month
Used in 4 crates (2 directly)

MIT/Apache

16KB
437 lines

Ori

Crates.io Documentation license

Ori is a cross-platform declarative UI framework for Rust, with a focus on simplicity and performance.

Ori is heavily inspired by SwiftUI and xilem, and uses a similar approach to building user interfaces. It is built on top of ori_core, which provides the core functionality, and ori_winit, which provides a winit based shell, and supports both a wgpu, and glow based renderer.

Examples

For more examples, see ori/examples.

use ori::prelude::*;

// We create our application data struct that holds all the state of our app.
//
// In this case, we only need a counter.
#[derive(Default)]
struct Data {
    counter: u32,
}

// We create a counter button component that increments the `Data::counter` when clicked.
//
// This returns a type that implements the `View` trait with `Data`.
fn counter_button() -> impl View<Data> {
    // We create a button with the text "Click me!", and a fancy value of `4.0`.
    let counter = button(text("Click me!")).fancy(4.0);

    // We use the `on_click` function to attach a callback to the button that
    // increments the counter.
    //
    // Note that the callback is a closure that takes a mutable reference to
    // an `EventCx` and a mutable reference to the `Data` struct.
    let counter = on_click(counter, |_, data: &mut Data| data.counter += 1);
    tooltip("Click to increment the counter!", counter)
}

// We create our app function that creates the UI of our app.
//
// This will be called every time the UI needs to be rebuilt,
// eg. when the a button is clicked.
fn app(data: &mut Data) -> impl View<Data> {
    // We use the `vstack!` macro to create a vertical stack of views.
    let content = vstack![counter_button(), text!("Clicked {} time(s)", data.counter)];

    // We use the `center` function to center the content in the window.
    center(content)
}

fn main() {
    let window = WindowDescriptor::new().title("Counter (examples/counter.rs)");

    // We create a new app with our `app` function and initial `Data` struct.
    // Then we set the title of the window and run the app.
    Launcher::new(Data::default()).window(window, app).launch();
}

Dependencies

~3.5MB
~75K SLoC