Appearance
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:
- The event, in a handler, when the type matches the event being handled.
- The component's
State, asconst State&inrenderandpaint, orState&in a handler. - A built-in parameter, from the lists below.
- The environment, for any other type: the nearest
Providerenclosing 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.
| Type | Value |
|---|---|
ColorScheme | Light 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
| Type | Value |
|---|---|
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
| Type | Value |
|---|---|
Painter& | Draws inside the component's bounds |
Frame& | Frame time and delta, request() and request_at(time) for animation |
Interactions | Whether 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
| Type | Value |
|---|---|
const Event& | The event being handled, such as const SelectEvent& |
Windows& | Opens and closes windows: windows.open<T>({ .title = "..." }) |
CurrentWindow | The window the event came from: close(), close_with(result) |
AppData<T> | Writable access to app data: data->count += 1 |
FileDialog | Shows a native open, save or folder dialog. See Dialogs |
Clipboard& | Reads and writes clipboard text |
Assets& | Same as in render |
Instant | When the event happened |
Bounds | The component's bounds on screen |
const ResolvedLayout& | The component's resolved layout |
Measurer | Measures text, for example to place a caret |
Dispatch | Delivers another press or release event along the same path |
Pass | Lets 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.