Skip to content

Layout Helpers

The pieces that structure a window, as opposed to the controls that fill it.

Headers and sections

StyleDrawer.DrawTabHeader("Title", "Description");
StyleDrawer.DrawPanelHeader("Panel", "Description");
StyleDrawer.DrawSubHeader("Subsection");
StyleDrawer.DrawSectionBreak();

DrawTabHeader is the largest and intended once per window or tab. DrawPanelHeader titles a panel within it. DrawSubHeader is for a group inside a panel. DrawSectionBreak draws a themed horizontal rule.

The description argument on the first two is optional and draws in the themed description colour underneath the title.

Boxed groups

DrawStyled draws a titled, boxed group and runs your callback inside it:

StyleDrawer.DrawStyled("Advanced", () =>
{
    CustomGUIElements.ThemedIntSlider("Iterations", ref _iterations, 1, 64);
    CustomGUIElements.ThemedToggle("Verbose", ref _verbose);
});

CustomGUIElements.DrawGroup is the equivalent without the panel chrome, and DrawIndented indents a block without titling it:

CustomGUIElements.DrawGroup("Output", () => { /* contents */ });

CustomGUIElements.DrawIndented(() =>
{
    CustomGUIElements.ThemedTextField("Suffix", ref _suffix);
});

Panels

EditorGUILayout.BeginVertical(StyleCache.OuterPanelStyle);
EditorGUILayout.BeginVertical(StyleCache.GetPanelStyle("Middle"));
EditorGUILayout.BeginVertical(StyleCache.GetPanelStyle("Interface"));

OuterPanelStyle is the window's outermost container. GetPanelStyle returns the inner panel styles — "Middle" and "Interface" are themed separately so a user can distinguish nested regions.

Separators

CustomGUIElements.DrawSeparator();

A themed horizontal line, using the theme's separator colour.

A note on OnGUI safety

IMGUI runs Layout and Repaint as separate passes over the same code, and both must emit the same number of layout groups. Two consequences worth knowing:

Do not change layout based on Event.current.type

Branching your layout on whether the current event is Layout or Repaint makes the two passes disagree, which produces "You are pushing more GUIClips than you are popping" and a corrupted window. If you need a measurement to affect layout, take it during Repaint, store it, and let it take effect on the next frame — which is what SKINT's own designer does for its column count.

Do not let exceptions escape OnGUI

An exception thrown mid-layout leaves IMGUI's group stack unbalanced, so the window breaks in a way that outlives the original error. Wrap risky work in a try/catch that rethrows ExitGUIException and logs everything else.

Refreshing after a theme change in code

If you change the theme outside the designer, invalidate the cached styles:

StyleDrawer.ApplyLiveStyleRefresh();

It is safe to call from OnGUI — it defers the rebuild rather than doing it mid-pass.

Next