Crate panoramix[][src]

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

backend

Traits and type used internally to compute the GUI

elements

GUI elements that can be built in a component.

flex

Types used by Panoramix to lay out widgets.

widgets

Wrapper types around druid widgets.

Macros

Column

Builds a column of up to 12 Elements.

Row

Builds a row of up to 12 Elements.

Tuple

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

Structs

CompCtx

Context type passed to all components when building them.

RootHandler

Creates a GUI application from a component

RootWidget

Implements druid::Widget from a component

Enums

NoEvent

Placeholder type for elements that don’t raise events.

PlatformError

Shell errors.

Traits

Element

The trait implemented by all GUI elements.

ElementExt

Helper methods that can be called on all elements.

Attribute Macros

component

Attribute used to declare a component