diff --git a/Dalamud/Interface/Utility/ImGuiClip.cs b/Dalamud/Interface/Utility/ImGuiClip.cs index e36970885..fafd026f0 100644 --- a/Dalamud/Interface/Utility/ImGuiClip.cs +++ b/Dalamud/Interface/Utility/ImGuiClip.cs @@ -59,6 +59,56 @@ public static class ImGuiClip clipper.Destroy(); } + /// + /// Draws the enumerable data with number of items per line. + /// + /// Enumerable containing data to draw. + /// The function to draw a single item. + /// How many items to draw per line. + /// How tall each line is. + /// The type of data to draw. + public static void ClippedDraw(IReadOnlyList data, Action draw, int itemsPerLine, float lineHeight) + { + ImGuiListClipperPtr clipper; + unsafe + { + clipper = new ImGuiListClipperPtr(ImGuiNative.ImGuiListClipper_ImGuiListClipper()); + } + + var maxRows = (int)MathF.Ceiling((float)data.Count / itemsPerLine); + + clipper.Begin(maxRows, lineHeight); + while (clipper.Step()) + { + for (var actualRow = clipper.DisplayStart; actualRow < clipper.DisplayEnd; actualRow++) + { + if (actualRow >= maxRows) + return; + + if (actualRow < 0) + continue; + + var itemsForRow = data + .Skip(actualRow * itemsPerLine) + .Take(itemsPerLine); + + var currentIndex = 0; + foreach (var item in itemsForRow) + { + if (currentIndex++ != 0 && currentIndex < itemsPerLine + 1) + { + ImGui.SameLine(); + } + + draw(item); + } + } + } + + clipper.End(); + clipper.Destroy(); + } + // Draw a clipped random-access collection of consistent height lineHeight. // Uses ImGuiListClipper and thus handles start- and end-dummies itself, but acts on type and index. public static void ClippedDraw(IReadOnlyList data, Action draw, float lineHeight)