|
Ultralight C++ API 2.0.0
|
#include <AppCore/layout/Container.h>
A layout node that organizes child nodes into a row or column.
Containers form the rows and columns of an AppCore window's layout tree. The window's root layout is a container that fills the entire window, and adding child rows or columns divides that space into a hierarchy of panes.
Each child can be a Panel that hosts a View, or another Container that splits space further. The library recalculates child sizes automatically whenever the window resizes or moves between displays with different scale factors.
The following example creates a resizable row with a sidebar and a content pane:
A container divides space along its main axis by first subtracting its padding and any gaps between children. It satisfies pixel sizes first, gives percentage sizes their shares of the free space left after pixel-sized children, and divides what remains among flexible children according to their flex factors. A child created without an explicit size defaults to one flex share (1fr). For what each size unit means, see Size and Length.
Containers also accept gap to separate adjacent children and padding to inset them from all four edges (both in logical pixels).
Setting resizable = true on a container places draggable dividers between its direct children. Dragging a divider resizes the panes on either side.
You can constrain how panes resize during a drag:
Double-clicking a divider resets both neighboring children to their declared sizes.
You can customize divider appearance by passing a DividerStyle to SetDividerStyle().
Assigning a key in a child's creation options lets you look up that node across the container's subtree with Find(), FindPanel(), or FindContainer(). If multiple descendants share the same key, the lookup returns the newest match.
An empty container reserves space in the layout without hosting a View or rendering web content.
To track the container's bounds as the window resizes, register a layout change listener:
Call SetLayoutOverride() to install a layout delegate that positions direct children manually by calling LayoutNode::SetBounds(). The delegate runs whenever the window updates layout.
Classes | |
| class | ChildIterator |
| Iterator over a container's children (a forward range of RefPtr<LayoutNode>). More... | |
| class | ChildRange |
| A range over the container's children: More... | |
Public Member Functions | |
| virtual RefPtr< Panel > | AddPanel (const PanelOptions &options={}, InsertPosition position={})=0 |
| Create a panel with a new View (window-default view configuration). | |
| virtual RefPtr< Panel > | AddPanel (const PanelOptions &options, const ViewConfig &view_config, InsertPosition position={})=0 |
| Create a panel with a caller-supplied ViewConfig. | |
| virtual RefPtr< Panel > | AdoptPanel (RefPtr< View > view, const PanelOptions &options={}, InsertPosition position={})=0 |
| Create a panel that adopts an existing View (including a View created through a Session). | |
| template<typename ViewRef> requires std::convertible_to<ViewRef&&, RefPtr<View>> | |
| RefPtr< Panel > | AddPanel (ViewRef &&view, const PanelOptions &options={}, InsertPosition position={}) |
| Adopt an existing View (shorthand for AdoptPanel()). | |
| virtual RefPtr< Container > | AddRow (const ContainerOptions &options={}, InsertPosition position={})=0 |
| Create a child row container. | |
| virtual RefPtr< Container > | AddColumn (const ContainerOptions &options={}, InsertPosition position={})=0 |
| Create a child column container. | |
| virtual bool | Remove (RefPtr< LayoutNode > node)=0 |
| Remove a direct child (and, for a container child, its whole subtree) from the tree. | |
| virtual void | RemoveAll ()=0 |
| Remove every child. | |
| virtual bool | Move (RefPtr< LayoutNode > node, InsertPosition position={})=0 |
| Reorder a direct child within this container. | |
| virtual int | child_count () const =0 |
| Get the number of children. | |
| virtual RefPtr< LayoutNode > | child_at (int index) const =0 |
| Get the child at an index. | |
| virtual RefPtr< LayoutNode > | Find (const String &key)=0 |
| Find a descendant by key. | |
| virtual RefPtr< Panel > | FindPanel (const String &key)=0 |
| Find a descendant panel by key. | |
| virtual RefPtr< Container > | FindContainer (const String &key)=0 |
| Find a descendant container by key. | |
| virtual void | SetLayoutOverride (LayoutOverrideCallback callback, void *user_data=nullptr, LayoutDestroyUserDataCallback destroy_user_data=nullptr)=0 |
| Override this container's layout with a layout delegate. | |
| virtual bool | HasLayoutOverride () const =0 |
| Whether or not this container has a layout delegate installed. | |
| virtual void | SetDividerStyle (const DividerStyle &style)=0 |
| Set this container's divider style (see <AppCore/layout/DividerStyle.h>). | |
| template<typename Callback> requires std::invocable<Callback&, Container&, const Rect&> || std::invocable<Callback&, const Rect&> | |
| void | SetLayoutOverride (Callback callback) |
| Install a layout delegate (invocable form). | |
| ChildRange | children () const |
| Get a forward range over the children. | |
| template<typename... Children> requires (LayoutBuildable<Children> && ...) | |
| RefPtr< Container > | Build (Children... children) |
| Append builder elements (see <AppCore/layout/Builder.h>) to this container. | |
| Public Member Functions inherited from LayoutNode | |
| virtual String | key () const =0 |
| Get the node's key (empty if unkeyed). | |
| virtual RefPtr< Container > | parent () const =0 |
| Get the node's parent container (null at the root or when detached). | |
| virtual int | index () const =0 |
| Get the node's index within its parent (-1 when detached). | |
| virtual RefPtr< Panel > | AsPanel ()=0 |
| Get this node as a Panel (null if it is not one). | |
| virtual RefPtr< Container > | AsContainer ()=0 |
| Get this node as a Container (null if it is not one). | |
| virtual void | Hide ()=0 |
| Hide the node and redistribute its space to its siblings. | |
| virtual void | Show ()=0 |
| Show the node again, restoring its remembered size exactly. | |
| virtual bool | is_hidden () const =0 |
| Whether or not the node is hidden. | |
| virtual Rect | bounds () const =0 |
| Get the node's rect from the most recent layout in container-local logical pixels (the same space SetBounds() takes). | |
| virtual IntRect | device_bounds () const =0 |
| Get the node's rect from the most recent layout in window back-buffer device pixels (the space your own drawing uses). | |
| virtual void | SetBounds (const Rect &bounds)=0 |
| Place this node manually. | |
| virtual void | SetSize (Size size)=0 |
| Set the node's declared size along its container's axis. | |
| virtual void | SetMinSize (Length min_size)=0 |
| Set the node's minimum size constraint. | |
| virtual void | SetMaxSize (Length max_size)=0 |
| Set the node's maximum size constraint. | |
| virtual LayoutCallback | OnUserResize (LayoutNodeCallback callback, void *user_data, LayoutDestroyUserDataCallback destroy_user_data)=0 |
| Register a callback fired when the user resizes this node with a divider. | |
| virtual LayoutCallback | OnLayoutChange (LayoutNodeCallback callback, void *user_data, LayoutDestroyUserDataCallback destroy_user_data)=0 |
| Register a callback that fires after layout changes this node's bounds (at most once per frame). | |
| template<typename Callback> requires std::invocable<Callback&, LayoutNode&> || std::invocable<Callback&> | |
| LayoutCallback | OnUserResize (Callback callback) |
| Register a user-resize callback (invocable form). | |
| template<typename Callback> requires std::invocable<Callback&, LayoutNode&> || std::invocable<Callback&> | |
| LayoutCallback | OnLayoutChange (Callback callback) |
| Register a layout-change callback (invocable form). | |
| RefPtr< LayoutNode > | next_sibling () const |
| Get the sibling after this node (null at the end, at the root, or when detached). | |
| RefPtr< LayoutNode > | previous_sibling () const |
| Get the sibling before this node (null at the start, at the root, or when detached). | |
| Public Member Functions inherited from RefCounted | |
| virtual void | AddRef () const =0 |
| Increment the reference count (thread-safe). | |
| virtual void | Release () const =0 |
| Decrement the reference count (thread-safe). | |
| virtual int | ref_count () const =0 |
| Get the current reference count. | |
| virtual WeakControlBlock * | weak_control_block () const |
| Get the control block used to track weak references to this object. | |
Protected Member Functions | |
| virtual | ~Container () |
| Protected Member Functions inherited from LayoutNode | |
| virtual | ~LayoutNode () |
| Protected Member Functions inherited from RefCounted | |
| virtual | ~RefCounted () |
|
protectedvirtual |
|
pure virtual |
Create a child column container.
| options | The container's declared options. |
| position | Where to insert the container (default: append at the end). |
|
pure virtual |
Create a panel with a caller-supplied ViewConfig.
The fields describing the hosting window are filled in from the window for you. Every other field is yours:
To host a deliberately CPU-rendered View on a GPU window, create the View with Renderer::CreateView() and use AdoptPanel().
| options | The panel's declared options. |
| view_config | The configuration for the new View. The window-describing fields listed above are overwritten. |
| position | Where to insert the panel (default: append at the end). |
|
pure virtual |
Create a panel with a new View (window-default view configuration).
| options | The panel's declared options. |
| position | Where to insert the panel (default: append at the end). |
|
inline |
Adopt an existing View (shorthand for AdoptPanel()).
| view | The View to host. |
| options | The panel's declared options. |
| position | Where to insert the panel (default: append at the end). |
|
pure virtual |
Create a child row container.
| options | The container's declared options. |
| position | Where to insert the container (default: append at the end). |
|
pure virtual |
Create a panel that adopts an existing View (including a View created through a Session).
The panel takes a reference to the View and resizes it to the panel's bounds.
| view | The View to host. |
| options | The panel's declared options. |
| position | Where to insert the panel (default: append at the end). |
|
inline |
Append builder elements (see <AppCore/layout/Builder.h>) to this container.
Build appends, so calling twice appends twice. For a fresh start, call RemoveAll() first.
| children | The builder elements to append, in order. |
|
pure virtual |
Get the child at an index.
| index | The zero-based index within this container's child list. |
|
pure virtual |
Get the number of children.
|
inline |
Get a forward range over the children.
|
pure virtual |
Find a descendant by key.
| key | The key to look for. |
Find a descendant container by key.
| key | The key to look for. |
Find a descendant panel by key.
| key | The key to look for. |
|
pure virtual |
Whether or not this container has a layout delegate installed.
|
pure virtual |
Reorder a direct child within this container.
A node from a different container (or window) is a no-op with a warning. A position anchor that is not a direct child falls back to the end, also with a warning.
| node | The direct child to move. |
| position | The new position (default: move to the end). |
|
pure virtual |
Remove a direct child (and, for a container child, its whole subtree) from the tree.
Removal detaches the child and drops each removed panel's reference to its View. A View the application holds a RefPtr to survives removal and can be adopted into another panel or window. For what removed handles do afterwards, see LayoutNode.
| node | The direct child to remove. |
|
pure virtual |
Remove every child.
Equivalent to Remove() on each child in turn.
|
pure virtual |
Set this container's divider style (see <AppCore/layout/DividerStyle.h>).
Fields left unset fall back to the window's style (Window::SetDividerStyle()), then to the built-in defaults.
| style | The style to apply. A default-constructed style clears the override. |
|
pure virtual |
Override this container's layout with a layout delegate.
The delegate runs each time the window performs layout (after a layout change, a resize, or a display scale change), but never while the container has no children.
The delegate positions the container's direct children by calling LayoutNode::SetBounds():
content_box is the container's content box (inside its padding) in container-local logical pixels.
Placed rectangles are snapped and clipped to this box.
A placed rectangle persists until the delegate places that child again– the delegate may place only what changed.
Children that the delegate has never placed occupy no region.
Changing the tree from inside the delegate is allowed.
Setting a new delegate replaces the existing one, and every child resets to never-placed.
Replacing the delegate destroys the previous delegate's user data. If replaced from inside the delegate, destruction is deferred until the delegate returns.
| callback | The delegate to install. Pass nullptr to restore ordinary layout. |
| user_data | Passed back to the delegate on every run (can be nullptr). |
| destroy_user_data | Called once when the delegate drops user_data (can be nullptr). |