docs
Loading...
Searching...
No Matches
Options.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#pragma once
8#include <Ultralight/RefPtr.h>
9#include <Ultralight/String.h>
10
11#include <cstdint>
12#include <utility>
13
14// X11's headers define None as a macro, which would break the None enumerators.
15#pragma push_macro("None")
16#undef None
17
18namespace ultralight {
19
20class LayoutNode;
21
22///
23/// Auto-dismiss policy for floating panels and popup windows.
24///
25/// @see ForegroundPanelOptions::dismiss, Window::SetDismiss()
26///
27enum class Dismiss : uint8_t {
28 Manual = 0, ///< Hides only when you hide it (a popup window also hides when its owner hides).
29 Auto = 1, ///< The library also hides it the way the OS closes a native menu.
30};
31
32///
33/// Keyboard focus policy for a floating panel.
34///
35/// @note Hiding a floating panel that holds focus releases focus. No panel holds focus until the
36/// user clicks one or you call Panel::Focus().
37///
38enum class FocusPolicy : uint8_t {
39 Auto = 0, ///< Takes focus when clicked, like any panel. Showing the panel never takes focus.
40 Grab = 1, ///< Takes keyboard focus when created (unless hidden) and each time it is shown,
41 ///< even from inside a click handler (dropdowns, palettes, in-window dialogs).
42 None = 2, ///< Never takes keyboard focus. Calling Panel::Focus() on it is ignored with a
43 ///< warning (toasts, HUDs).
44};
45
46///
47/// Configuration options for a floating panel.
48///
49/// Pass ForegroundPanelOptions to Foreground::AddPanel() or Foreground::AdoptPanel() to configure
50/// an overlay that floats above a window's tiled layout. A floating panel displays content such as
51/// a dialog or dropdown menu without shifting the layout beneath it.
52///
53/// Passing empty options creates a panel that fills the entire window.
54///
55/// This creates a centered dialog that closes like a native menu and takes keyboard focus:
56///
57/// ```
58/// RefPtr<Panel> dialog = window->foreground()->AddPanel(
59/// { .key = "confirm", .width = "400px", .height = "240px",
60/// .placement = Anchor::WindowCenter(), .dismiss = Dismiss::Auto,
61/// .focus = FocusPolicy::Grab });
62/// dialog->view()->LoadURL("file:///confirm.html");
63/// ```
64///
65/// ## Size and Placement
66///
67/// Set `width` and `height` using logical pixels (eg, `"400px"`) or a percentage of the window (eg,
68/// `"50%"`).
69///
70/// The `placement` option sets where the panel sits in the window (see Anchor), defaulting to the
71/// window origin.
72///
73/// @note A floating panel's size and placement are fixed at creation. To move or resize a panel,
74/// keep a reference to its View with Panel::view() before calling Foreground::Remove()--
75/// Panel::view() returns null once the panel is removed. Pass that View to
76/// Foreground::AdoptPanel() with updated options so the page doesn't reload.
77///
78/// ## Dismissal and Focus
79///
80/// By default, a floating panel uses `Dismiss::Manual` and stays open until you hide it. Set
81/// `dismiss = Dismiss::Auto` to close the panel automatically like a native menu (see Dismiss).
82/// Call Panel::OnDismiss() to respond when the library dismisses the panel automatically.
83///
84/// By default, a floating panel uses `FocusPolicy::Auto` and takes keyboard focus only when
85/// clicked. Set `focus = FocusPolicy::Grab` for dialogs and dropdown menus that need focus
86/// immediately upon appearing (see FocusPolicy).
87///
88/// ## Starting Hidden
89///
90/// Set `hidden = true` to create the panel hidden, then call Panel::Show() once its page has
91/// loaded.
92///
93/// @see Foreground::AddPanel(), Anchor, Dismiss, FocusPolicy, Panel::OnDismiss()
94///
96 ///
97 /// Optional identity for lookup and diagnostics. Empty means unkeyed.
98 ///
100
101 ///
102 /// The panel's width, in logical px or as a percent of the window's width. Unset means `100%`.
103 ///
104 /// @note A flex factor (`fr`) is not meaningful here and is treated as unset with a warning.
105 ///
107
108 ///
109 /// The panel's height, in logical px or as a percent of the window's height. Unset means
110 /// `100%`.
111 ///
112 /// @note A flex factor (`fr`) is not meaningful here and is treated as unset with a warning.
113 ///
115
116 ///
117 /// Where the panel sits in the window (see Anchor). The default is the window origin, which
118 /// with the default sizes gives a full-window panel.
119 ///
121
122 ///
123 /// The auto-dismiss policy.
124 ///
125 /// Auto hides the panel the way native menus close, ie. when:
126 ///
127 /// - a press lands outside it
128 /// - Esc is pressed
129 /// - the user moves, resizes, minimizes, maximizes, or deactivates the window (or
130 /// presses its title bar or borders)
131 ///
132 /// Panel::OnDismiss() fires each time. Scrolling never dismisses a floating panel, and Manual
133 /// panels hide only when you hide them.
134 ///
135 /// @note A press on another floating panel overlapping this one's rect still counts as
136 /// inside (the outside test is against this panel's own rect).
137 ///
139
140 ///
141 /// The keyboard-focus policy (see FocusPolicy).
142 ///
144
145 ///
146 /// Whether or not the panel starts hidden (create hidden, then Show() once its content
147 /// has loaded).
148 ///
149 bool hidden = false;
150};
151
152///
153/// Configuration options for a panel in a row or column.
154///
155/// Pass PanelOptions to Container::AddPanel() or Window::AddPanel() when adding a panel to a window
156/// layout. It declares how the panel shares space with sibling nodes along its parent container's
157/// axis.
158///
159/// The following example creates a resizable row with a sized sidebar and a default content panel:
160///
161/// ```
162/// RefPtr<Container> body = window->layout()->AddRow({ .resizable = true });
163/// RefPtr<Panel> sidebar =
164/// body->AddPanel({ .key = "sidebar", .size = "240px", .min_size = "160px" });
165/// RefPtr<Panel> content = body->AddPanel(); // one flex share
166/// ```
167///
168/// ## Defaults and Sizing
169///
170/// Every field is optional. Passing an empty `{}` gives an unkeyed panel that takes one flex share
171/// (`1fr`).
172///
173/// For the supported size units, see Size and Length.
174///
175/// ## Panel Keys
176///
177/// Setting `key` assigns a string identifier to the panel for diagnostics and retrieval. You can
178/// look up the panel later by passing its key to Window::FindPanel() or Container::Find().
179///
180/// @see Container::AddPanel(), Window::AddPanel(), Size, Length, ContainerOptions
181///
183 ///
184 /// Optional identity for lookup (Find()) and diagnostics. Empty means unkeyed, which is fully
185 /// supported.
186 ///
187 /// @note Duplicate keys log a warning, and Find() returns the most recently created match.
188 ///
190
191 ///
192 /// The panel's size along its container's axis. Unset means one flex share (`1fr`). For
193 /// what each unit means, see Size.
194 ///
196
197 ///
198 /// Minimum size constraint. Percentages are relative to the container's content box (inside its
199 /// padding). Unset means no minimum.
200 ///
202
203 ///
204 /// Maximum size constraint. Percentages are relative to the container's content box (inside its
205 /// padding). Unset means no maximum.
206 ///
208
209 ///
210 /// Whether or not the panel is fixed (the user cannot resize it by dragging a divider).
211 ///
212 bool fixed = false;
213
214 ///
215 /// Whether or not the panel is created hidden. A hidden panel keeps its declared size and
216 /// shows later without a layout flash.
217 ///
218 bool hidden = false;
219};
220
221///
222/// Configuration options for a row or column container.
223///
224/// You pass ContainerOptions to Container::AddRow() or Container::AddColumn() when adding a
225/// container to a window's layout tree. These options configure the container's own size within its
226/// parent, alongside spacing and divider behavior for its direct children.
227///
228/// This creates a resizable row with child spacing and outer padding:
229///
230/// ```
231/// RefPtr<Container> body = window->layout()->AddRow(
232/// { .key = "body", .resizable = true, .gap = 4, .padding = 8 });
233/// ```
234///
235/// ## Options Shared with Panels
236///
237/// Because a container is also a layout child, it shares its sizing, constraints, and visibility
238/// options with PanelOptions. These fields govern how the container behaves within its parent
239/// container (see PanelOptions).
240///
241/// ## Dividers and Spacing
242///
243/// Settings on the container and its children control interactive divider behavior between panes:
244///
245/// - **A container's `resizable` option enables dividers between all direct children.** Dragging a
246/// divider redistributes space between the panes on either side.
247/// - **A child node's `fixed` option preserves that child's size.** Divider drags on either side
248/// can't resize a fixed pane.
249///
250/// To configure divider thickness and colors, call Container::SetDividerStyle() or
251/// Window::SetDividerStyle() (see DividerStyle).
252///
253/// Container options configure empty space around and between direct children:
254///
255/// - **The `gap` option separates adjacent direct children along the layout axis.** Unset gap
256/// leaves no space between children.
257/// - **The `padding` option insets direct children from all four container edges.** Unset padding
258/// places children flush against the container boundary.
259///
260/// Both properties accept only logical pixels. Percentage units are ignored with a warning.
261///
262/// @see Container::AddRow(), Container::AddColumn(), Window::BuildLayout(), PanelOptions,
263/// DividerStyle
264///
266 ///
267 /// Optional identity for lookup (Find()) and diagnostics. Empty means unkeyed.
268 ///
270
271 ///
272 /// The container's size along its parent's axis. Unset means one flex share (`1fr`).
273 ///
275
276 ///
277 /// Minimum size constraint. Percentages are relative to the parent's content box (inside its
278 /// padding). Unset means no minimum.
279 ///
281
282 ///
283 /// Maximum size constraint. Percentages are relative to the parent's content box (inside its
284 /// padding). Unset means no maximum.
285 ///
287
288 ///
289 /// Whether or not the container is fixed (the user cannot resize it by dragging a divider).
290 ///
291 bool fixed = false;
292
293 ///
294 /// Whether or not the user can resize this container's children by dragging the dividers
295 /// between them.
296 ///
297 bool resizable = false;
298
299 ///
300 /// The gap between adjacent children (logical px only; other units are ignored with a
301 /// warning). Unset means no gap.
302 ///
304
305 ///
306 /// Padding between the container's edges and its children, applied on all four sides
307 /// (logical px only). Unset means no padding.
308 ///
310
311 ///
312 /// Whether or not the container is created hidden (its whole subtree is hidden with it).
313 ///
314 bool hidden = false;
315};
316
317///
318/// Position relative to an existing sibling in a container.
319///
320/// An InsertPosition places a node before or after an existing sibling instead of appending to the
321/// end of the container. You pass it when adding panels or rearranging children.
322///
323/// The helper functions Before() and After() position nodes around an existing child:
324///
325/// ```
326/// RefPtr<Panel> toolbar = window->layout()->AddPanel(
327/// { .key = "toolbar", .size = "44px" }, Before(content));
328/// body->Move(sidebar, After(content)); // put the sidebar on the right
329/// ```
330///
331/// ## Relative Placement
332///
333/// Container methods accept helper functions or default construction:
334///
335/// - **Before() places the child immediately before an anchor sibling.**
336/// - **After() places the child immediately after an anchor sibling.**
337/// - **A default-constructed position appends the child at the end of the container.** This applies
338/// whenever you omit the position argument or construct one with no anchor.
339///
340/// When the anchor sibling isn't a direct child of the container, the library logs a warning and
341/// appends the node at the end.
342///
343/// @note The anchor member here is an existing sibling LayoutNode within the container. Floating
344/// panels use the Anchor class instead to position overlays in window space.
345///
346/// @see Before(), After(), Container::AddPanel(), Container::Move()
347///
349 ///
350 /// The sibling the position is relative to. Null means append at the end.
351 ///
353
354 ///
355 /// Whether or not the position is after the anchor (Before() when false).
356 ///
357 bool after = false;
358};
359
360///
361/// Create an insertion position immediately before a sibling.
362///
363/// @param anchor The sibling to insert before.
364///
365inline InsertPosition Before(RefPtr<LayoutNode> anchor) { return { std::move(anchor), false }; }
366
367///
368/// Create an insertion position immediately after a sibling.
369///
370/// @param anchor The sibling to insert after.
371///
372inline InsertPosition After(RefPtr<LayoutNode> anchor) { return { std::move(anchor), true }; }
373
374} // namespace ultralight
375
376#pragma pop_macro("None")
Placement of a floating panel in a window.
Definition Anchor.h:107
Base class for Panels and Containers in a window layout tree.
Definition LayoutNode.h:108
A distance or size constraint in an AppCore layout.
Definition Length.h:60
A nullable smart pointer.
Definition RefPtr.h:126
Fixed, percentage, and flexible sizes for panels and containers.
Definition Length.h:371
Unicode string container with conversions for UTF-8, UTF-16, and UTF-32.
Definition String.h:31
Root namespace for every public Ultralight type, function, and enumeration.
InsertPosition Before(RefPtr< LayoutNode > anchor)
Create an insertion position immediately before a sibling.
Definition Options.h:365
FocusPolicy
Keyboard focus policy for a floating panel.
Definition Options.h:38
@ Auto
Takes focus when clicked, like any panel. Showing the panel never takes focus.
Definition Options.h:39
@ Grab
Takes keyboard focus when created (unless hidden) and each time it is shown, even from inside a click...
Definition Options.h:40
InsertPosition After(RefPtr< LayoutNode > anchor)
Create an insertion position immediately after a sibling.
Definition Options.h:372
@ None
Definition Anchor.h:36
Dismiss
Auto-dismiss policy for floating panels and popup windows.
Definition Options.h:27
@ Auto
The library also hides it the way the OS closes a native menu.
Definition Options.h:29
@ Manual
Hides only when you hide it (a popup window also hides when its owner hides).
Definition Options.h:28
Configuration options for a row or column container.
Definition Options.h:265
Length min_size
Minimum size constraint.
Definition Options.h:280
bool hidden
Whether or not the container is created hidden (its whole subtree is hidden with it).
Definition Options.h:314
Size size
The container's size along its parent's axis.
Definition Options.h:274
Length gap
The gap between adjacent children (logical px only; other units are ignored with a warning).
Definition Options.h:303
Length padding
Padding between the container's edges and its children, applied on all four sides (logical px only).
Definition Options.h:309
String key
Optional identity for lookup (Find()) and diagnostics.
Definition Options.h:269
Length max_size
Maximum size constraint.
Definition Options.h:286
bool fixed
Whether or not the container is fixed (the user cannot resize it by dragging a divider).
Definition Options.h:291
bool resizable
Whether or not the user can resize this container's children by dragging the dividers between them.
Definition Options.h:297
Configuration options for a floating panel.
Definition Options.h:95
FocusPolicy focus
The keyboard-focus policy (see FocusPolicy).
Definition Options.h:143
Anchor placement
Where the panel sits in the window (see Anchor).
Definition Options.h:120
Size height
The panel's height, in logical px or as a percent of the window's height.
Definition Options.h:114
bool hidden
Whether or not the panel starts hidden (create hidden, then Show() once its content has loaded).
Definition Options.h:149
Size width
The panel's width, in logical px or as a percent of the window's width.
Definition Options.h:106
String key
Optional identity for lookup and diagnostics.
Definition Options.h:99
Dismiss dismiss
The auto-dismiss policy.
Definition Options.h:138
Position relative to an existing sibling in a container.
Definition Options.h:348
bool after
Whether or not the position is after the anchor (Before() when false).
Definition Options.h:357
RefPtr< LayoutNode > anchor
The sibling the position is relative to.
Definition Options.h:352
Configuration options for a panel in a row or column.
Definition Options.h:182
Length min_size
Minimum size constraint.
Definition Options.h:201
bool hidden
Whether or not the panel is created hidden.
Definition Options.h:218
Size size
The panel's size along its container's axis.
Definition Options.h:195
String key
Optional identity for lookup (Find()) and diagnostics.
Definition Options.h:189
Length max_size
Maximum size constraint.
Definition Options.h:207
bool fixed
Whether or not the panel is fixed (the user cannot resize it by dragging a divider).
Definition Options.h:212