Skip to content

Parameters ​

Render functions, paint functions and event handlers request parameters by specifying them in their parameter list, in any order. Barton matches each one by type and passes in the value.

cpp
MenuItem {
    "Duplicate Window",
    on_activate =
        [](const ActivateEvent&, State& state, Windows& windows) {
            state.copies += 1;
            windows.open<MainWindow>({ .title = "Copy" });
        },
}

A function's parameter list is the only declaration Barton needs. Adding a parameter is enough to receive it, and removing one stops it from being passed.

Resolution order ​

For each parameter, Barton checks in this order:

  1. The event, in a handler, when the type matches the event being handled.
  2. The component's State, as const State& in render and paint, or State& in a handler.
  3. A built-in parameter, from the lists below.
  4. The environment, for any other type: the nearest Provider enclosing the component, then app data. If nothing provides it, Barton passes a default-constructed value.

The last step is what makes custom types work without setup. See Environment.

Everywhere ​

These work in render, paint and handlers alike.

State ​

The component's own state. Read-only while rendering or painting, writable in a handler.

cpp
View render(const State& state) const;
on_click = [](State& state) { state.open = !state.open; };

A handler binds to exactly one State, found by type among the components above it. That means a handler inside a child can name its parent's state directly:

cpp
on_click = [](LayersPanel::State& panel) { panel.selected = 0; };

TIP

In a handler, state is always State&. A const State& parameter is looked up in the environment instead.

Environment values ​

Any type in the environment, taken as const T& or by value.

TypeValue
ColorSchemeLight or dark, from the system unless a Provider overrides it
const Theme&Colors the built-in components use for their default styles
const T&The nearest Provider { T {...}, ... } above, or app data registered with App {}.data<T>()

In render ​

TypeValue
Assets&Loads images, fonts and custom types in the background. See Assets
Frame&The current frame's time, and request() for another frame

In paint ​

TypeValue
Painter&Draws inside the component's bounds
Frame&Frame time and delta, request() and request_at(time) for animation
InteractionsWhether the component is hovered, pressed or focused
const Style&The component's resolved style
const ResolvedLayout&The component's resolved layout
const Measurer&Measures text for custom layout
cpp
void paint(Painter& painter, Interactions interactions) const {
    const bool hot = interactions.contains(Interaction::Hovered);
    painter.rect(hot ? Color::WHITE.set_a(0.1f) : Color::TRANSPARENT);
}

In event handlers ​

TypeValue
const Event&The event being handled, such as const SelectEvent&
Windows&Opens and closes windows: windows.open<T>({ .title = "..." })
CurrentWindowThe window the event came from: close(), close_with(result)
AppData<T>Writable access to app data: data->count += 1
FileDialogShows a native open, save or folder dialog. See Dialogs
Clipboard&Reads and writes clipboard text
Assets&Same as in render
InstantWhen the event happened
BoundsThe component's bounds on screen
const ResolvedLayout&The component's resolved layout
MeasurerMeasures text, for example to place a caret
DispatchDelivers another press or release event along the same path
PassLets the event continue to the next handler instead of stopping here

A few of these together:

cpp
MenuItem {
    "Open...",
    on_activate = [](FileDialog dialog) {
        dialog.show(OpenFile {}.with_filter("Images", "png;jpg"))
            .then([](const FileDialogEvent& event, State& state) {
                if (const auto* accepted = event.accepted())
                    state.path = accepted->paths.front();
            });
    },
},
MenuItem {
    "Copy Path",
    on_activate = [](State& state, Clipboard& clipboard) {
        clipboard.set_text(state.path.string());
    },
},

Callbacks passed to then follow the same rules, so they can take the reply and any state they need.

Custom parameters ​

Specializing into_param<T> adds a built-in parameter, the same way Barton's own are defined. The contexts these read from aren't part of the public API yet, so a Provider or app data is currently the better way to make custom types available.

Barton is in early development.