Crate panoramix

Source
Expand description

Panoramix is an experimental GUI framework for the Rust programming language.

This framework is data-driven and declarative, drawing some inspiration from React, and implemented on top of the Druid toolkit.

It aims to use simple, idiomatic Rust: Panoramix doesn’t use unsafe code, cells, mutexes, or DSL macros.

§Getting started

Here is our “hello world” example:

use panoramix::elements::{Button, Label};
use panoramix::{component, Column, CompCtx, Element, NoEvent, RootHandler};

#[component]
fn HelloBox(_ctx: &CompCtx, _props: ()) -> impl Element {
    Column!(
        Label::new("Hello world!"),
        Button::new("Say hello").on_click(|_, _| {
            println!("Hello world");
        })
    )
}

fn main() -> Result<(), panoramix::PlatformError> {
    RootHandler::new(HelloBox)
        .with_tracing(true)
        .launch()
}

To understand this example, let’s define a few terms:

  • A Widget is the fundamental unit of GUI; for instance, a text field and a label are both widgets. You’ve probably seen the term if you’ve used other GUI frameworks.
  • An Element is a lightweight description of a Widget. In our example, Button::new and Label::new both return elements. The Column macro is similar to vec - it takes an arbitrary number of elements and returns a container element.
  • A Component is a user-written function that takes Props as parameters and returns a tree of elements (or, more accurately, an arbitrary element that may or may not contain other elements). In our example, HelloBox is a component. By convention, components always have a CamelCase name.

In Panoramix, you don’t directly manipulate widgets; instead, you write components that return elements. The framework calls your components, gets a tree of elements, and builds a matching widget tree for you. When some event changes the application state, the framework calls your components again, gets a new element tree, and edits the widget tree accordingly.

As such, the root of your Panoramix application will usually look like:

// main.rs

use panoramix::elements::{Button, ButtonClick};
use panoramix::{component, CompCtx, Element, NoEvent, RootHandler};

#[derive(Debug, Default, Clone, PartialEq)]
struct ApplicationState {
    // ...
}

#[component]
fn MyRootComponent(ctx: &CompCtx, _props: ()) -> impl Element<NoEvent, ApplicationState> {
    // ...
}

fn main() -> Result<(), panoramix::PlatformError> {
    let initial_state = ApplicationState {
        // ...
    };

    RootHandler::new(MyRootComponent)
        .with_initial_state(initial_state)
        .with_tracing(true)
        .launch()
}

For information on how to write a component, see this document on Github.

Modules§

  • Traits and type used internally to compute the GUI
  • GUI elements that can be built in a component.
  • Types used by Panoramix to lay out widgets.
  • Wrapper types around druid widgets.

Macros§

  • Builds a column of up to 12 Elements.
  • Builds a row of up to 12 Elements.
  • Builds a group of up to 12 Elements, without a specified layout.

Structs§

Enums§

Traits§

  • The trait implemented by all GUI elements.
  • Helper methods that can be called on all elements.

Attribute Macros§

  • Attribute used to declare a component