TachyonUI 0.1.0
High-performance UI for building tools.
Loading...
Searching...
No Matches
Docking

Four panels in a dock layout. A panel is a piece of UI with a title, shown as a tab. A dock layout arranges the panels in the window, and the user can rearrange them:

  • drag a tab to move its panel
  • drop it on another group of tabs to dock it there
  • drag it outside the window to float it in an OS window of its own

Full source: examples/docking/docking.cpp.

Panels

  • Create each panel once, in Initialize, with:
    • a title, shown on its tab
    • an icon, or IconID::Invalid for none
    • a callback that builds its content
  • The callback runs only while the panel is visible.
  • CreatePanel returns the panel's ID, which the dock tree below refers to.
// Panels are created once; each draws its content in its callback.
const tachyon::ID scene = CreatePanel(layout.panels, "Scene", noIcon, [this] { ScenePanel(); });
const tachyon::ID details = CreatePanel(layout.panels, "Details", noIcon, [this] { DetailsPanel(); });
const tachyon::ID log = CreatePanel(layout.panels, "Log", noIcon, [this] { Text("Nothing logged yet."); });
const tachyon::ID help = CreatePanel(layout.panels, "Help", noIcon, [this] { Text("Drag the tabs around."); });
IconID
Handle for an icon registered with ITextSystem::RegisterIconFromSVG / RegisterIconFromSVGFile.
Definition gui_style_text.h:15
@ Invalid
Definition gui_style_text.h:15
A 64-bit element ID whose bit layout depends on its IDMode.
Definition gui_id.h:23

The dock tree

  • The dock tree says where each panel goes. It is made of splits and leaves:
    • a split divides its space between two children, side by side or one above the other
    • a leaf holds one or more panels, shown as tabs
  • A pinned split keeps one side at a fixed size, in CSS px, and gives the rest to the other side. LeftPinned, 220 keeps the left side 220 px wide.
// Left column of 220 px, the rest split over a 150 px bottom row.
layout.root = tachyon::MakeSplit(DockSplitMode::LeftPinned, 220,
tachyon::MakeLeaf({ scene }),
tachyon::MakeSplit(DockSplitMode::BottomPinned, 150,
tachyon::MakeLeaf({ details, help }),
tachyon::MakeLeaf({ log })));
std::unique_ptr< DockNode > MakeLeaf(std::initializer_list< ID > panelIds={})
A leaf with the given panel tabs.
std::unique_ptr< DockNode > MakeSplit(DockSplitMode mode, CssPx splitSize, std::unique_ptr< DockNode > first, std::unique_ptr< DockNode > second, CssPx minFirstSize=80, CssPx minSecondSize=80)
A split node owning first and second; sizes in CSS px.
DockSplitMode
Split direction and which child is pinned to splitSize; the other child flexes.
Definition gui_dock_node.h:25

Building it each frame

  • The docking container, BeginDockingContainer, builds the panels that are visible in the window.
  • EmitFloatingDockWindows then builds the panels the user dragged out into their own windows.
void OnGUI() override
{
if (BeginWindow(windowID, "Docking", theme.mainWindowStyleRef, tachyon::LayoutOverride::FixedSize(900, 600).Centered()))
{
BeginDockingContainer(dockID, &layout, tachyon::LayoutOverride::Auto());
EndDockingContainer();
// Panels dragged out of the window get their own OS windows, owned by this one.
EmitFloatingDockWindows();
}
EndWindow();
}
LayoutOverride & Centered() &
Centered in the parent on both axes.
Definition gui_constraints.h:259
static LayoutOverride FixedSize(CssPx w, CssPx h)
Sizes in CSS px (scaled by the UI scale) or in Pixels (as they are); see gui_units....
Definition gui_constraints.h:184
static LayoutOverride Auto()
No overrides: everything comes from the style.
Definition gui_constraints.h:182

Panel content

A panel callback is ordinary UI code, the same as in OnGUI:

void DetailsPanel()
{
Text("Selected object " + std::to_string(selected));
BeginLabelGroup();
DragLabel("Scale");
Field(scale);
EndLabelGroup();
}

Keeping the arrangement

  • To keep the user's arrangement across restarts:
    • call PersistDocking("dock", Layout) once, after the panels and the dock tree exist
    • when the app quits, save the text SaveUIState returns, for example to a file
    • see Errors and saved state
// In Initialize, after layout.root is set
PersistDocking("dock", layout);
// After Run returns, before Cleanup
if (std::ofstream file("ui_state.json", std::ios::binary); file)
file << app.SaveUIState();

Previous: Controls | Examples | Next: Custom theme