Skip to main content

List

list

See the ListDemo.cs.

using Gridrand.RimGui.Manual;
using System.Collections.Generic;

namespace Gridrand.RimGui.Extensions.Manual
{
/// <summary>
/// Demonstrates a list view with both non-scrolling and scrolling items.
/// </summary>
class ListDemo : ManualBase, IManual
{
readonly ListSet nonScrollList = new();
readonly ListSet fixedScrollList = new();

public ListDemo(ManualBaseResource p) : base(p)
{
}

public void Draw()
{
// Display non-scrolling list view
Gui.Heading("NonScroll");
DrawNonScroll(nonScrollList);

// Display scrolling list view
Gui.Heading("Scroll");
DrawFixedScroll(fixedScrollList);
}

void DrawNonScroll(ListSet listSet)
{
using (Style.Frame.Paddings.Begin(new(1, 1, 1, 1)))
using (Gui.BeginFrame())
{
// Set vertical spacing between items to 0.
using var s = Style.SpacingYs.Begin(0f);

// Iterate and draw each item in the list.
for (int i = 0; i < listSet.Items.Count; i++)
{
DrawItem(listSet, listSet.Items[i]);
// Handle item selection based on user input.
listSet.SelectedItems.HandlePress(Input, listSet.Items[i], Ctx.WasLastPressedThisFrame());
}
}
}

void DrawFixedScroll(ListSet listSet)
{
using (Style.Frame.Paddings.Begin(new(1, 1, 1, 1)))
using (Gui.BeginFrame())
using (Style.SpacingYs.Begin(0f))
using (Gui.NextHeight(100f).BeginFixedScroll(listSet.Items.Count))
{
// Loop while there are more items to draw within the fixed scroll view.
while (Ctx.AdvanceFixedScrollItem())
{
// Get the current item to draw based on the scroll index.
var node = listSet.Items[Ctx.GetFixedScrollIndex()];
DrawItem(listSet, node);
// Handle item selection based on user input.
listSet.SelectedItems.HandlePress(Input, node, Ctx.WasLastPressedThisFrame());
}
}
// Get the rectangle of the last drawn scroll area and set it as a deselection area.
var scrollRect = Ctx.GetLastWidgetRect();
Gui.NextRect(scrollRect).DeselectionArea(listSet.SelectedItems);
}

/// <summary>
/// Draws a list item with a checkbox and an index label.
/// </summary>
/// <param name="listSet"></param>
/// <param name="item"></param>
void DrawItem(ListSet listSet, Item item)
{
using var s = Ctx.PushId(item.GetHashCode());
var nodeRect = Ctx.AllocateRect();

using (Ctx.BeginDeferredBuilding())
{
var paddedRect = nodeRect.Shrink(Style.InteractiveItem.Paddings.Get());

// note:Unscaled because the scale has already been taken into account.
using var rects = Ctx.LayoutBuilder
.FixedUnscaled(paddedRect.height)
.Fit(1)
.BuildHorizontal(paddedRect);

var isChecked = item.IsChecked;

// Draws a checkbox, updating item state if changed
if (Gui.NextRect(rects.R0).CheckBox(ref isChecked))
{
item.IsChecked = isChecked;
}

Gui.NextRect(rects.R1).Text(item.Name);
}

Gui.NextRect(nodeRect)
.InteractiveItem(listSet.SelectedItems.IsSelected(item));
}

/// <summary>
/// Represents an item in the list.
/// </summary>
class Item
{
public string Name { get; }
public bool IsChecked { get; set; }

public Item(string name)
{
Name = name;
}
}

/// <summary>
/// Manages a collection of <see cref="Item"/> objects and their selection state.
/// </summary>
class ListSet
{
public List<Item> Items { get; } = new();
// Manages item selection
public ItemSelection<Item> SelectedItems { get; } = new();

public ListSet()
{
for (int i = 0; i < 10; i++)
{
Items.Add(new Item(i.ToString()));
}

SelectedItems.Select(Items[1]);
SelectedItems.Select(Items[3]);
SelectedItems.Select(Items[4]);
}
}
}
}