LayoutBuilder
See the LayoutBuilderDemo.cs.
using Gridrand.RimGui.Manual.Utility;
namespace Gridrand.RimGui.Manual
{
/// <summary>
/// This is a <see cref="ILayoutBuilder"/> demo.
///
/// When you want to render at a specific position, you can primarily use
/// <see cref="Gui.LayoutBuilder"/> to generate a Rect and specify that Rect
/// with <see cref="Gui.NextRect(Contracts.Rect)"/> to render the widget
/// at the desired position.
/// </summary>
class LayoutBuilderDemo : ManualBase, IManual
{
bool showCheckBox = true;
public LayoutBuilderDemo(ManualBaseResource p) : base(p)
{
}
public void Draw()
{
Gui.Heading("NextXXX()");
DrawNext();
Gui.Heading("Fixed And Fit");
DrawUsingFixedAndFit();
Gui.Heading("Min");
DrawUsingMin();
Gui.Heading("Max");
DrawUsingMax();
Gui.Heading("Swiching");
DrawSwitching();
Gui.Heading("Misc");
DrawMisc();
}
void DrawNext()
{
// Specify the height for the next widget
Gui.NextHeight(30).Button("NextFixedHeight(30)");
Gui.NextWidth(200).Button("NextFixedWidth(200)");
var lastRect = Ctx.GetLastWidgetRect();
// Specify the rect for the next widget.
Gui.NextRect(lastRect.MoveX(220f)).Button("NextRect()");
}
void DrawSwitching()
{
Gui.LabelInput("Show Center", ref showCheckBox);
using var rects = LayoutBuilder
.Fixed(50f)
// By passing a bool as an argument, you can toggle enable/disable.
// Useful for dynamically changing layouts.
.Fixed(100f, showCheckBox)
.Fixed(50f)
// Allocate horizontally
.BuildAllocatedHorizontal();
// By specifying the Rect for the next widget, the widget is rendered within that Rect.
Gui.FrameText(rects.R0, "Left");
if (showCheckBox)
Gui.FrameText(rects.R1, "Center");
Gui.FrameText(rects.R2, "Right");
}
void DrawUsingFixedAndFit()
{
// Fixed: A specified width
// Fit: The remaining width is divided among other Fit elements. The argument represents the ratio relative to other Fits.
const float width = 300f;
using var s = Style.SpacingXs.Begin(0f);
Gui.Text("Width:300");
Gui.Text($"Fixed(100) Fit(1f) Fit(2f)");
// Fixed is assigned 100,, and the remaining width is split between Fit with a 1:2 ratio.
using var rects1 = LayoutBuilder.Fixed(100).Fit(1f).Fit(2f).BuildAllocatedHorizontal(width);
Gui.FrameText(rects1.R0, $"{rects1.R0.width}");
Gui.FrameText(rects1.R1, $"{rects1.R1.width}");
Gui.FrameText(rects1.R2, $"{rects1.R2.width}");
}
void DrawUsingMin()
{
// Min: Uses the smaller value between the given ratio and fixed value.
const float width = 300f;
using var s = Style.SpacingXs.Begin(0f);
Gui.Text("Width:300");
Gui.Text($"Min(ratio:0.4,fixed:200) Fixed(100)");
// Since the total width is 300, ratio 0.4 results in 120, which is smaller than fixed 200, so Min is 120.
using var rects1 = LayoutBuilder.Min(ratio: 0.4f, @fixed: 200).Fixed(100).BuildAllocatedHorizontal(width);
Gui.FrameText(rects1.R0, $"{rects1.R0.width}");
Gui.FrameText(rects1.R1, $"{rects1.R1.width}");
}
void DrawUsingMax()
{
// Max: Uses the larger value between the given ratio and fixed value.
const float width = 300f;
using var s = Style.SpacingXs.Begin(0f);
Gui.Text("Width:300");
Gui.Text($"Max(ratio:0.4,fixed:200) Fixed(100)");
// Since the total width is 300, ratio 0.4 results in 120, but fixed is 200, so Max is 200.
using var rects2 = LayoutBuilder.Max(ratio: 0.4f, @fixed: 200).Fixed(100).BuildAllocatedHorizontal(width);
Gui.FrameText(rects2.R0, $"{rects2.R0.width}");
Gui.FrameText(rects2.R1, $"{rects2.R1.width}");
}
void DrawMisc()
{
// Building a horizontal layout with fixed and flexible sections.
using var horiRects = LayoutBuilder
.Fixed(50)
.Fit(1)
.BuildAllocatedHorizontal(height: 300f);
Gui.FrameBoxText(horiRects.R0, "Left");
// Right section, split into two parts (top and bottom)
using var rightRects = LayoutBuilder
.Fixed(50)
.Fit(1)
.BuildVertical(horiRects.R1);
Gui.FrameBoxText(rightRects.R0, "Right Top");
Gui.FrameBoxText(rightRects.R1, "Right Bottom");
}
}
}