1 unstable release

0.1.0-alpha.0 Apr 24, 2023

#1143 in GUI


Used in ori

MIT/Apache

335KB
7K SLoC

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::*;

// define the data model. this can be anything that implements 'static.
//
// here we just have a struct with a single field.
#[derive(Default)]
struct Data {
    count: u32,
}

// define the user interface builder. this is a function that takes a
// mutable reference to the Data and returns a View of the data.
//
// this function is called once when the window is created, and again
// whenever a rebuild is requested. it is therefore important that this
// function is cheap to call, as it might be called many times per second.
fn ui(data: &mut Data) -> impl View<Data> {
    // create a Text view with the current count. all builtin views have
    // shorthand functions for creating them, note that Text::new() is
    // would work just as well.
    let count = text(format!("Clicked {} times", data.count));

    // create a button that increments the count when clicked.
    let count = on_click(
        // we use the button view to add some visual feedback.
        button(count).fancy(4.0),
        // this is the event handler, it is called when the content is clicked.
        // note that this implicitly requests a rebuild of the view tree.
        |_, data: &mut Data| data.count += 1,
    );

    // finally we center the the button in the window.
    //
    // it should be noted that () implements View, a common issue is to
    // accidentally add a semicolon after the last line, which will cause
    // the function to return (), which can cause some confusing errors.
    center(count)
}

fn main() {
    // create a window descriptor.
    let window = WindowDescriptor::new()
        .title("Hello, world!"); // set the title of the window.

    // create a launcher with the data model.
    Launcher::new(Data::default())
        .window(window, ui) // add the window with the ui builder.
        .launch(); // launch the application.
}

Dependencies

~27–68MB
~1M SLoC