docs
Loading...
Searching...
No Matches
Builder.h
Go to the documentation of this file.
1///
2/// Copyright (C) 2026 Ultralight, Inc. All rights reserved.
3/// A license is required for commercial use. https://ultralig.ht
4///
5/// @file Builder.h
6///
7/// Declarative functions for constructing layout trees.
8///
9/// `#include <AppCore/layout/Builder.h>`
10///
11/// The panel(), row(), and column() functions return builder elements that describe panels and
12/// containers. They let you declare an entire layout hierarchy in a single expression instead of
13/// adding nodes step by step with Container::AddPanel(), Container::AddRow(), and
14/// Container::AddColumn().
15///
16/// This declares a toolbar above a resizable body with a sidebar and a content pane:
17///
18/// ```
19/// RefPtr<Panel> toolbar, sidebar, content;
20///
21/// window->BuildLayout({},
22/// panel({ .key = "toolbar", .size = "44px", .fixed = true }, &toolbar),
23/// row({ .key = "body", .resizable = true },
24/// panel({ .key = "sidebar", .size = "240px" }, &sidebar),
25/// panel({ .key = "content" }, &content)));
26///
27/// toolbar->view()->LoadURL("file:///toolbar.html");
28/// ```
29///
30/// ## Building Layout Trees
31///
32/// Builder elements construct nodes through a window or an existing container:
33///
34/// - **Window::BuildLayout() populates the window while setting options on its root container.**
35/// Pass ContainerOptions for the root container as the first argument, followed by the child
36/// elements.
37/// - **Container::Build() appends children to an existing container.** Pass the child elements
38/// directly to add them to that container.
39///
40/// The builder functions accept the same PanelOptions and ContainerOptions as
41/// Container::AddPanel(), Container::AddRow(), and Container::AddColumn(), and they produce the
42/// same Panel and Container nodes.
43///
44/// ## Capturing Node Handles
45///
46/// You can capture handles to nodes during layout construction by passing the address of a RefPtr
47/// handle to panel(), row(), or column(). When the layout is built, each function populates the
48/// target pointer with the created Panel or Container. This lets you interact with nodes
49/// immediately (such as calling Panel::view() to load content) so you don't need to look them up by
50/// key later.
51///
52/// @note Window::BuildLayout() and Container::Build() append children to the existing tree.
53/// Calling either method again appends duplicate children. Call Container::RemoveAll() first
54/// if you want to rebuild from a clean slate.
55///
56/// @see Window::BuildLayout(), Container::Build(), panel(), row(), column()
57///
58#pragma once
60
61#include <tuple>
62#include <utility>
63
64namespace ultralight {
65
66///
67/// A panel element inside a Build()/BuildLayout() expression. Create with panel().
68///
69struct PanelSpec {
71 RefPtr<Panel>* out = nullptr;
72
73 void ApplyTo(Container& parent) const {
74 RefPtr<Panel> result = parent.AddPanel(options);
75 if (out)
76 *out = result;
77 }
78};
79
80///
81/// Describe a panel in a builder expression (see Builder.h for an example).
82///
83/// @param options The panel's declared options.
84///
85/// @param out Receives the created panel when the layout is built. Pass nullptr if you
86/// don't need the handle.
87///
88/// @return Returns a builder element describing the panel.
89///
90inline PanelSpec panel(PanelOptions options = {}, RefPtr<Panel>* out = nullptr) {
91 return PanelSpec { std::move(options), out };
92}
93
94///
95/// A container element inside a Build()/BuildLayout() expression. Create with row() or
96/// column().
97///
98template <typename... Children>
101 bool is_row = false;
103 std::tuple<Children...> children;
104
105 void ApplyTo(Container& parent) const {
106 RefPtr<Container> result
107 = is_row ? parent.AddRow(options) : parent.AddColumn(options);
108 if (out)
109 *out = result;
110 std::apply([&](const Children&... child) { (child.ApplyTo(*result), ...); }, children);
111 }
112};
113
114///
115/// Describe a row container with child elements.
116///
117/// @param options The container's declared options.
118///
119/// @param children The child elements to append, in order.
120///
121/// @return Returns a builder element describing the row.
122///
123template <typename... Children>
124 requires(LayoutBuildable<Children> && ...)
125ContainerSpec<Children...> row(ContainerOptions options, Children... children) {
126 return ContainerSpec<Children...> { std::move(options), true, nullptr,
127 std::make_tuple(std::move(children)...) };
128}
129
130///
131/// Describe a row container, capturing the created handle in `out`.
132///
133/// @param options The container's declared options.
134///
135/// @param out Receives the created container when the layout is built.
136///
137/// @param children The child elements to append, in order.
138///
139/// @return Returns a builder element describing the row.
140///
141template <typename... Children>
142 requires(LayoutBuildable<Children> && ...)
143ContainerSpec<Children...> row(ContainerOptions options, RefPtr<Container>* out,
144 Children... children) {
145 return ContainerSpec<Children...> { std::move(options), true, out,
146 std::make_tuple(std::move(children)...) };
147}
148
149///
150/// Describe a column container with child elements.
151///
152/// @param options The container's declared options.
153///
154/// @param children The child elements to append, in order.
155///
156/// @return Returns a builder element describing the column.
157///
158template <typename... Children>
159 requires(LayoutBuildable<Children> && ...)
160ContainerSpec<Children...> column(ContainerOptions options, Children... children) {
161 return ContainerSpec<Children...> { std::move(options), false, nullptr,
162 std::make_tuple(std::move(children)...) };
163}
164
165///
166/// Describe a column container, capturing the created handle in `out`.
167///
168/// @param options The container's declared options.
169///
170/// @param out Receives the created container when the layout is built.
171///
172/// @param children The child elements to append, in order.
173///
174/// @return Returns a builder element describing the column.
175///
176template <typename... Children>
177 requires(LayoutBuildable<Children> && ...)
178ContainerSpec<Children...> column(ContainerOptions options, RefPtr<Container>* out,
179 Children... children) {
180 return ContainerSpec<Children...> { std::move(options), false, out,
181 std::make_tuple(std::move(children)...) };
182}
183
184} // namespace ultralight
A layout node that organizes child nodes into a row or column.
Definition Container.h:101
virtual RefPtr< Container > AddColumn(const ContainerOptions &options={}, InsertPosition position={})=0
Create a child column container.
virtual RefPtr< Panel > AddPanel(const PanelOptions &options={}, InsertPosition position={})=0
Create a panel with a new View (window-default view configuration).
virtual RefPtr< Container > AddRow(const ContainerOptions &options={}, InsertPosition position={})=0
Create a child row container.
A nullable smart pointer.
Definition RefPtr.h:126
Root namespace for every public Ultralight type, function, and enumeration.
ContainerSpec< Children... > column(ContainerOptions options, Children... children)
Describe a column container with child elements.
Definition Builder.h:160
ContainerSpec< Children... > row(ContainerOptions options, Children... children)
Describe a row container with child elements.
Definition Builder.h:125
PanelSpec panel(PanelOptions options={}, RefPtr< Panel > *out=nullptr)
Describe a panel in a builder expression (see Builder.h for an example).
Definition Builder.h:90
Configuration options for a row or column container.
Definition Options.h:265
A container element inside a Build()/BuildLayout() expression.
Definition Builder.h:99
std::tuple< Children... > children
Definition Builder.h:103
bool is_row
Definition Builder.h:101
ContainerOptions options
Definition Builder.h:100
void ApplyTo(Container &parent) const
Definition Builder.h:105
RefPtr< Container > * out
Definition Builder.h:102
Configuration options for a panel in a row or column.
Definition Options.h:182
A panel element inside a Build()/BuildLayout() expression.
Definition Builder.h:69
PanelOptions options
Definition Builder.h:70
void ApplyTo(Container &parent) const
Definition Builder.h:73
RefPtr< Panel > * out
Definition Builder.h:71