Skip to main content

Shaper

shapre

See the ShaperDemo.cs.

using Gridrand.Contracts;
using Gridrand.Contracts.Rendering;
using System;

namespace Gridrand.RimGui.Manual
{
/// <summary>
/// <see cref="Shaper"/> demo.
///
/// For <see cref="Gui.CustomDelegate(Action{Shaper, CustomDelegateWidget}, bool, int)"/>, please refer to <see cref="CustomDemo"/>
/// </summary>
class ShaperDemo : ManualBase, IManual
{
static readonly Color32 s_baseColor = new Color32(180, 180, 180, 255);

readonly VerticesTextSettings textSettings1 = new();
readonly VerticesTextSettings textSettings2 = new();

// Bezier curve points
readonly Vector3[] bezierPoints = new Vector3[3]
{
new(0f, 0f),
new(0f, 70f),
new(70f,70f)
};

// Anti-aliased closed line points
readonly Vector2[] closedLineAAPoints = new Vector2[6]
{
new(0f, 20f),
new(5f, 40f),
new(30f, 70f),
new(70f, 30f),
new(50f, 0f),
new(20f, 5f),
};

// Anti-aliased convex polygon points
readonly Vector2[] convexPolygonAAPoints = new Vector2[6]
{
new(0f, 20f),
new(5f, 40f),
new(30f, 70f),
new(70f, 30f),
new(50f, 0f),
new(20f, 5f),
};

public ShaperDemo(ManualBaseResource p) : base(p)
{
textSettings1.AlignmentX = AlignmentX.Center;
textSettings2.AlignmentX = AlignmentX.Center;
}

public void Draw()
{
textSettings1.FontSize = 18f * Style.ScaleFactor;
textSettings2.FontSize = 10f * Style.ScaleFactor;

Gui.Spacing();
DrawLines();
Gui.Spacing();
DrawTriangles();
Gui.Spacing();
DrawRects();
Gui.Spacing();
DrawPolygonAndClosedLine();
Gui.Spacing();
DrawStyledRects();
Gui.Spacing();
DrawGridAndBezierCurve();
Gui.Spacing();
DrawColors();
Gui.Spacing();
DrawTexts();
}

// Draws two diagonal lines: one anti-aliased, one without AA
void DrawLines()
{
// Create a horizontal layout with padding and two fixed-width elements
using var rects = LayoutBuilder.Fit(1f).Fixed(70f).Fit(1f).Fixed(70f).Fit(1f).BuildAllocatedHorizontal(height: 70f);

// Draw an anti-aliased line with a thickness
Gui.NextRect(rects.R1).CustomDelegate(
Style.ScaleFactor,
static (shaper, widget) =>
{
var p = widget.Rect.Position;
ReadOnlySpan<Vector2> span = stackalloc Vector2[2]
{
p,
p + new Vector2(70f, 70f) * widget.State
};
shaper.AddLineAA(
span,
5f,
1f,
s_baseColor);
},
true);

// Draw a non-AA line (sharp) from top-left to bottom-right
Gui.NextRect(rects.R3).CustomDelegate(
Style.ScaleFactor,
static (shaper, widget) =>
{
// Floor() for beautiful rendering
var p = new Vector2(MathF.Floor(widget.Rect.Position.x), MathF.Floor(widget.Rect.Position.y));
shaper.AddLine(
p,
p + new Vector2(70f, 70f) * widget.State,
1f,
s_baseColor);
},
true);
}

void DrawTriangles()
{
using var rects = LayoutBuilder.Fit(1f).Fixed(70f).Fit(1f).Fixed(70f).Fit(1f).BuildAllocatedHorizontal(height: 70f);

Gui.NextRect(rects.R1).CustomDelegate(
static (shaper, widget) =>
{
var rect = widget.Rect;
var p = widget.Rect.Position;
shaper.AddTriangle(
rect.BL,
new Vector2(rect.Center.x, rect.YMax),
rect.BR,
s_baseColor,
s_baseColor,
s_baseColor);
},
true);
Gui.NextRect(rects.R3).CustomDelegate(
static (shaper, widget) =>
{
// Floor() for beautiful rendering
var p = widget.Rect.Position.Floor() - Vector2.One / 2f;
var rect = widget.Rect;
ReadOnlySpan<Vector2> span = stackalloc Vector2[4]
{
p,
p+new Vector2(rect.width/2f,rect.height),
p+new Vector2(rect.width, 0f),
p,
};
shaper.AddLineAA(
span,
1f,
1f,
s_baseColor);
},
true);
}
void DrawRects()
{
using var rects = LayoutBuilder.Fit(1f).Fixed(70f).Fit(1f).Fixed(70f).Fit(1f).BuildAllocatedHorizontal(height: 70f);
Gui.NextRect(rects.R1).CustomDelegate(
static (shaper, widget) =>
{
shaper.AddRect(widget.Rect, s_baseColor);
},
true);

Gui.NextRect(rects.R3).CustomDelegate(
static (shaper, widget) =>
{
Span<Vector2> points = stackalloc Vector2[4];
// Floor() for beautiful rendering
points[0] = widget.Rect.BL.Floor() - Vector2.One / 2f;
points[1] = widget.Rect.BR.Floor() - Vector2.One / 2f;
points[2] = widget.Rect.TR.Floor() - Vector2.One / 2f;
points[3] = widget.Rect.TL.Floor() - Vector2.One / 2f;

shaper.AddClosedLineAA(points, 1f, 0.5f, s_baseColor);
},
true);
}
void DrawPolygonAndClosedLine()
{
using var rects = LayoutBuilder.Fit(1f).Fixed(70f).Fit(1f).Fixed(70f).Fit(1f).BuildAllocatedHorizontal(height: 70f);


Gui.NextRect(rects.R1).CustomDelegate(
convexPolygonAAPoints,
Style.ScaleFactor,
static (shaper, widget) =>
{
using var points = PooledArray<Vector2>.Rent(widget.State1.Length);

var localPoints = widget.State1;
var scale = widget.State2;
for (int i = 0; i < localPoints.Length; i++)
{
points[i] = widget.Rect.Position + localPoints[i] * scale;
}
shaper.AddConvexPolygonAA(points.AsSpan(), 1f, s_baseColor);
},
true);

Gui.NextRect(rects.R3).CustomDelegate(
closedLineAAPoints,
Style.ScaleFactor,
static (shaper, widget) =>
{
using var points = PooledArray<Vector2>.Rent(widget.State1.Length);

var localPoints = widget.State1;
var scale = widget.State2;
for (int i = 0; i < localPoints.Length; i++)
{
points[i] = widget.Rect.Position + localPoints[i] * scale;
}
shaper.AddClosedLineAA(points.AsSpan(), 1f, 1f, s_baseColor);
},
true);
}
void DrawStyledRects()
{
using var rects = LayoutBuilder.Fit(1f).Fixed(70f).Fit(1f).Fixed(70f).Fit(1f).BuildAllocatedHorizontal(height: 70f);

Gui.NextRect(rects.R1).CustomDelegate(
static (shaper, widget) =>
{
var p = widget.Rect.Position;
shaper.AddStyledRect(
widget.Rect,
2f,
widget.Rect.height / 4f,
s_baseColor,
Color32.White);
},
true);
Gui.NextRect(rects.R3).CustomDelegate(
static (shaper, widget) =>
{
var p = widget.Rect.Position;
shaper.AddStyledRect(
widget.Rect,
2f,
widget.Rect.height / 2f,
new Color32(50, 50, 50, 255),
new Color32(150, 150, 150, 255));
},
true);
}
void DrawGridAndBezierCurve()
{
using var rects = LayoutBuilder.Fit(1f).Fixed(70f).Fit(1f).Fixed(70f).Fit(1f).BuildAllocatedHorizontal(height: 70f);

Gui.NextRect(rects.R1).CustomDelegate(
Style.ScaleFactor,
static (shaper, widget) =>
{
shaper.AddGrid(
new Grid(
7,
7,
10 * widget.State,
10 * widget.State),
widget.Rect.Position,
1f,
s_baseColor);
},
true);

Gui.NextRect(rects.R3).CustomDelegate(
5,
bezierPoints,
Style.ScaleFactor,
static (shaper, widget) =>
{
using var points = PooledArray<Vector3>.Rent(widget.State2.Length);
// Floor() for beautiful rendering
var p = (Vector3)widget.Rect.Position.Floor();

var localPoints = widget.State2;
for (int i = 0; i < localPoints.Length; i++)
{
points[i] = p + localPoints[i] * widget.State3;
}

shaper.AddBezierCurve(
points.AsSpan(),
widget.State1,
1f,
s_baseColor);
},
true);
}
void DrawColors()
{
using var rects = LayoutBuilder.Fit(1f).Fixed(70f).Fixed(10f).Fit(1f).Fixed(70f).Fit(1f).BuildAllocatedHorizontal(height: 70f);

Gui.NextRect(rects.R1).CustomDelegate(
static (shaper, widget) =>
{
shaper.AddSVPanel(widget.Rect, 1d);
},
true);

Gui.NextRect(rects.R2).CustomDelegate(
static (shaper, widget) =>
{
shaper.AddHueBar(widget.Rect);
},
true);

Ctx.AddSpaceIfNeeded();

using var rects2 = LayoutBuilder.Fit(1f).Fit(1f).Fit(1f).BuildVertical(rects.R4);

Gui.NextRect(rects2.R0).CustomDelegate(
static (shaper, widget) =>
{
var left = new Color32(20, 20, 100, 255);
var right = new Color32(100, 100, 200, 255);
shaper.AddGradient(widget.Rect, left, right, left, right);
},
true);
Gui.NextRect(rects2.R1).CustomDelegate(
static (shaper, widget) =>
{
var left = new Color32(100, 20, 20, 255);
var right = new Color32(200, 100, 100, 255);
shaper.AddGradient(widget.Rect, left, right, left, right);
},
true);
Gui.NextRect(rects2.R2).CustomDelegate(
static (shaper, widget) =>
{
var left = new Color32(20, 100, 20, 255);
var right = new Color32(100, 200, 100, 255);
shaper.AddGradient(widget.Rect, left, right, left, right);
},
true);
}
void DrawTexts()
{
using var rects = LayoutBuilder.Fit(1f).Fixed(70f).Fit(1f).Fixed(70f).Fit(1f).BuildAllocatedHorizontal(height: 70f);

Gui.NextRect(rects.R1).CustomDelegate(
textSettings1,
static (shaper, widget) =>
{
shaper.AddText(widget.Rect, "abc012", widget.State);
},
true);

Gui.NextRect(rects.R3).CustomDelegate(
textSettings2,
static (shaper, widget) =>
{
shaper.AddText(widget.Rect, "abc012", widget.State);
},
true);
}
}
}