docs
Loading...
Searching...
No Matches
LayoutNodeabstract

#include <AppCore/layout/LayoutNode.h>

Overview

Base class for Panels and Containers in a window layout tree.

An AppCore window arranges web views and native drawing regions into a tree of rows and columns, where each node shares space along its parent container's axis. LayoutNode represents an individual element in that hierarchy, whether it's a Container grouping child nodes or a Panel hosting a single View.

You use node handles to manage panes and containers dynamically at runtime, adapting the interface without rebuilding the layout tree.

This helper toggles a sidebar panel on and off:

void ToggleSidebar(RefPtr<Panel> sidebar) {
if (sidebar->is_hidden())
sidebar->Show(); // back at its previous size
else
sidebar->Hide(); // its siblings take the space
}
A nullable smart pointer.
Definition RefPtr.h:126

Showing and Hiding

Calling Hide() takes a node off screen and redistributes its space to sibling nodes, and Show() restores the node at its remembered size.

Hiding affects different node types:

  • Hiding a Container hides its entire subtree.
  • Hiding a Panel suspends its hosted View. Painting and animations pause, and the page receives a visibilitychange event.

Declared Sizes

Call SetSize(), SetMinSize(), or SetMaxSize() to update a node's declared size constraints at runtime. In a resizable container, double-clicking an adjacent divider restores both neighboring panes to the declared sizes set here (discarding any divider drags made since).

Layout Geometry

Accessors report layout rectangles across different coordinate spaces:

  • bounds() returns container-local logical pixels.
  • device_bounds() returns window back-buffer device pixels. Native rendering passes use this coordinate space to draw beneath or above web content.

Both rectangles remain zero until the window completes its first layout pass. Calling SetSize() queues a layout pass for an upcoming frame.

This registration reads the updated dimensions once the layout pass completes:

sidebar->SetSize("320px");
// bounds() still holds the old rect here. Read it once the layout runs:
on_resize_ = sidebar->OnLayoutChange([](LayoutNode& node) {
Log("sidebar is now " + std::to_string(node.bounds().width()) + "px wide");
});
Base class for Panels and Containers in a window layout tree.
Definition LayoutNode.h:108
virtual Rect bounds() const =0
Get the node's rect from the most recent layout in container-local logical pixels (the same space Set...
float width() const
Definition Geometry.h:428

Callback registrations report geometry changes:

  • OnLayoutChange() fires when layout changes the node's bounds. It runs at most once per frame after the layout pass completes.
  • OnUserResize() fires when a user resizes the node with a divider. It fires on drag release and after a double-click restores declared sizes, only when the node's size changed.

Both methods return a LayoutCallback that manages the registration (destroying it unregisters the callback).

Node Lifetimes and Handles

A handle never keeps its node or its window alive (releasing one doesn't remove the node from the layout tree). To remove a node, call Container::Remove() or Foreground::Remove().

After a node is removed or its window closes, handles remain safe to call. Mutations do nothing, and accessors return safe fallback values.

Adding a child to a removed container or a closed window logs a warning and returns a handle that isn't attached to any window.

Note
A View kept after its panel is removed loses its listeners– register them again after adopting it into another panel.
See also
Panel, Container, Container::Remove(), Foreground::Remove(), LayoutCallback
Inheritance diagram for LayoutNode:
RefCounted Container Panel

Public Member Functions

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 ~LayoutNode ()
Protected Member Functions inherited from RefCounted
virtual ~RefCounted ()

Constructor & Destructor Documentation

◆ ~LayoutNode()

virtual ~LayoutNode ( )
protectedvirtual

Member Function Documentation

◆ AsContainer()

virtual RefPtr< Container > AsContainer ( )
pure virtual

Get this node as a Container (null if it is not one).

◆ AsPanel()

virtual RefPtr< Panel > AsPanel ( )
pure virtual

Get this node as a Panel (null if it is not one).

◆ bounds()

virtual Rect bounds ( ) const
pure virtual

Get the node's rect from the most recent layout in container-local logical pixels (the same space SetBounds() takes).

Note
This value is zero until the node's first layout.

◆ device_bounds()

virtual IntRect device_bounds ( ) const
pure virtual

Get the node's rect from the most recent layout in window back-buffer device pixels (the space your own drawing uses).

Note
This value is zero until the node's first layout.

◆ Hide()

virtual void Hide ( )
pure virtual

Hide the node and redistribute its space to its siblings.

The node remembers its declared size, and Show() restores it.

Hiding a Container hides its entire subtree.

A hidden Panel's View stops rendering entirely– painting and animations suspend. The page receives a visibilitychange event.

Note
The visibilitychange event fires per panel rather than per window. Page code written for tab-background semantics receives this event on every Hide() and Show().

◆ index()

virtual int index ( ) const
pure virtual

Get the node's index within its parent (-1 when detached).

◆ is_hidden()

virtual bool is_hidden ( ) const
pure virtual

Whether or not the node is hidden.

This reports the node's own flag, so a node inside a hidden container still reports its own state even though it is not on screen.

◆ key()

virtual String key ( ) const
pure virtual

Get the node's key (empty if unkeyed).

◆ next_sibling()

RefPtr< LayoutNode > next_sibling ( ) const
inline

Get the sibling after this node (null at the end, at the root, or when detached).

◆ OnLayoutChange() [1/2]

template<typename Callback>
requires std::invocable<Callback&, LayoutNode&> || std::invocable<Callback&>
LayoutCallback OnLayoutChange ( Callback callback)
inlinenodiscard

Register a layout-change callback (invocable form).

Parameters
callbackAny invocable. It may take the node as LayoutNode&, or nothing at all.
Returns
Returns a LayoutCallback controlling how long the callback stays registered.

◆ OnLayoutChange() [2/2]

virtual LayoutCallback OnLayoutChange ( LayoutNodeCallback callback,
void * user_data,
LayoutDestroyUserDataCallback destroy_user_data )
nodiscardpure virtual

Register a callback that fires after layout changes this node's bounds (at most once per frame).

Use this to follow a node's geometry (eg, a reserved region that your own drawing fills).

Parameters
callbackThe function to call. It receives user_data and this node.
user_dataPassed back to the callback on every fire (can be nullptr).
destroy_user_dataCalled once when the registration drops user_data (can be nullptr).
Returns
Returns a LayoutCallback controlling how long the callback stays registered.
Note
Callbacks must not let exceptions propagate.

◆ OnUserResize() [1/2]

template<typename Callback>
requires std::invocable<Callback&, LayoutNode&> || std::invocable<Callback&>
LayoutCallback OnUserResize ( Callback callback)
inlinenodiscard

Register a user-resize callback (invocable form).

Parameters
callbackAny invocable. It may take the node as LayoutNode&, or nothing at all.
Returns
Returns a LayoutCallback controlling how long the callback stays registered.

◆ OnUserResize() [2/2]

virtual LayoutCallback OnUserResize ( LayoutNodeCallback callback,
void * user_data,
LayoutDestroyUserDataCallback destroy_user_data )
nodiscardpure virtual

Register a callback fired when the user resizes this node with a divider.

It fires on drag release, and again after a double-click resets the node to its declared size. Either way it fires only when the node's size changed.

Parameters
callbackThe function to call. It receives user_data and this node.
user_dataPassed back to the callback on every fire (can be nullptr).
destroy_user_dataCalled once when the registration drops user_data (can be nullptr).
Returns
Returns a LayoutCallback controlling how long the callback stays registered.
Note
Callbacks must not let exceptions propagate.

◆ parent()

virtual RefPtr< Container > parent ( ) const
pure virtual

Get the node's parent container (null at the root or when detached).

◆ previous_sibling()

RefPtr< LayoutNode > previous_sibling ( ) const
inline

Get the sibling before this node (null at the start, at the root, or when detached).

◆ SetBounds()

virtual void SetBounds ( const Rect & bounds)
pure virtual

Place this node manually.

Parameters
boundsThe node's new rect, in container-local logical pixels.
Note
This is only legal inside its container's layout delegate (see Container::SetLayoutOverride()). Anywhere else it is a no-op with a warning.

◆ SetMaxSize()

virtual void SetMaxSize ( Length max_size)
pure virtual

Set the node's maximum size constraint.

Parameters
max_sizeThe new maximum. An unset Length means no maximum.

◆ SetMinSize()

virtual void SetMinSize ( Length min_size)
pure virtual

Set the node's minimum size constraint.

Parameters
min_sizeThe new minimum. An unset Length means no minimum.

◆ SetSize()

virtual void SetSize ( Size size)
pure virtual

Set the node's declared size along its container's axis.

This acts like the size in the creation options– double-clicking an adjacent divider restores the node to the size declared here, discarding any user divider drags made since.

Parameters
sizeThe new declared size. An unset Size means one flex share (1fr).
Note
A floating panel's size is fixed at creation. Calling SetSize(), SetMinSize(), or SetMaxSize() on a floating panel does nothing and logs a warning.

◆ Show()

virtual void Show ( )
pure virtual

Show the node again, restoring its remembered size exactly.


The documentation for this class was generated from the following files: