Appearance
Concepts
A Barton view is a function of three inputs: props, state, and environment. When any of these inputs change, Barton reevaluates the view to reflect the updated values.
view=f(props,state,environment)
props
given by whoever creates it
UserCard { user }Text { "Hello" }padding = 8_px
state
kept by Barton across rebuilds
struct State { int count; }const State& statestate.count
environment
provided by type
const Theme& themeColorScheme schemeAssets& assets
Props: Values supplied when a component is created, allowing its parent to configure its appearance and behavior.
State: Data belonging to a specific component instance. State is initialized when the component first appears and persists across subsequent renders.
Environment: Values made available to components by type, without requiring them to be passed explicitly through each level of the component hierarchy.
Components
A component is a type with a render function, and its props are the values it's created with.
cpp
struct UserCard {
User user;
View render() const {
return Container {
padding = 12_px,
Text { std::format("{}'s profile", user.name) },
};
}
};Custom components are created just like built-in views: UserCard { user }. They also support named props, using the same syntax as built-in components. See Props.
Requesting parameters
Components can request state, environment values, and other dependencies directly through their render function's parameters. Barton resolves these automatically, so components only need to declare what they use.
cpp
struct Counter {
struct State {
int clicks = 0;
};
View render(const State& state, ColorScheme scheme) const {
return Text { std::format("{} clicks in {} mode", state.clicks,
scheme == ColorScheme::Dark ? "dark" : "light") };
}
};Here, state belongs to component instance, while ColorScheme is obtained from the environment. Event handlers can request parameters in the same way. See Parameters for the complete list of supported paramater types.
Composition
Barton interfaces are built by composing views into a hierarchy. Container views arrange their children, which are declared alongside their properties inside the braces. This makes it possible to describe both layout and content in ordinary C++.
For dynamic content, Barton provides a small set of helpers for conditional rendering, iteration, and variant matching:
| Helper | Renders |
|---|---|
If(condition, then) | Conditionally produces a view, with optional else |
For(range, item) | Produces a view for each element in a range |
Join(range, sep, item) | Like For, but inserts a separator between items |
Match(variant, lambdas...) | Selects a view based on the value currently held by the variant |
cpp
Column {
gap = 8_px,
If(state.signed_in, [] { return Greeting {}; }),
For(state.users, [](const User& user) { return UserCard { user }; }),
}Match is useful for values with a small set of distinct states. For example, an asset may be loading, ready, or failed, with each state displaying different content. See Assets.
Custom drawing
Components can implement a paint function to draw custom content without requiring a special component type. By default, drawing uses the component's calculated layout bounds, but explicit rectangles allow drawing beyond those bounds.
The resolved style and layout are passed to paint, providing access to properties such as background colors, padding, and content bounds. See Painting.