diff --git a/ImGuiWidgets/Grid.cs b/ImGuiWidgets/Grid.cs
index f01343b..9d7ae2c 100644
--- a/ImGuiWidgets/Grid.cs
+++ b/ImGuiWidgets/Grid.cs
@@ -1,5 +1,6 @@
namespace ktsu.ImGuiWidgets;
+using System.Drawing;
using System.Numerics;
using ImGuiNET;
@@ -36,21 +37,35 @@ public enum GridOrder
///
/// Items are displayed top to bottom before moving to the next column.
/// Recommended when displaying tables of data.
- /// Note: This will never display uneven rows that have more than 1 item
- /// missing relative to them.
/// Example:
- /// [ [1] [3] [5] ]
- /// [ [2] [4] [6] ]
+ /// [ [1] [4] ]
+ /// [ [2] [5] ]
+ /// [ [3] [6] ]
/// OR
- /// [ [1] [3] [5] ]
- /// [ [2] [4] ]
- /// NEVER
- /// [ [1] [3] [5] ]
- /// [ [2] ]
+ /// [ [1] [5] ]
+ /// [ [2] [6] ]
+ /// [ [3] ]
+ /// [ [4] ]
///
ColumnMajor,
}
+ ///
+ /// Options for changing how the grid is laid out.
+ ///
+ public class GridOptions
+ {
+ ///
+ /// Size of the grid. Setting any axis to 0 will use the available space.
+ ///
+ public Vector2 GridSize { get; set; } = new(0, 0);
+
+ ///
+ /// Size the content region to cover all the items.
+ ///
+ public bool FitToContents { get; init; }
+ }
+
///
/// Delegate to measure the size of a grid cell.
///
@@ -72,17 +87,72 @@ public enum GridOrder
/// Renders a grid with the specified items and delegates.
///
/// The type of the items.
+ /// Id for the grid.
/// The items to be displayed in the grid.
/// The delegate to measure the size of each item.
/// The delegate to draw each item.
- /// What ordering should grid items use
- public static void Grid(IEnumerable items, MeasureGridCell measureDelegate, DrawGridCell drawDelegate, GridOrder gridOrder)
+ public static void RowMajorGrid(string id, IEnumerable items, MeasureGridCell measureDelegate, DrawGridCell drawDelegate)
{
ArgumentNullException.ThrowIfNull(items);
ArgumentNullException.ThrowIfNull(measureDelegate);
ArgumentNullException.ThrowIfNull(drawDelegate);
- GridImpl.Show(items, measureDelegate, drawDelegate, gridOrder);
+ GridImpl.ShowRowMajor(id, items, measureDelegate, drawDelegate, new());
+ }
+
+ ///
+ /// Renders a grid with the specified items and delegates.
+ ///
+ /// The type of the items.
+ /// Id for the grid.
+ /// The items to be displayed in the grid.
+ /// The delegate to measure the size of each item.
+ /// The delegate to draw each item.
+ /// Additional options to modify the grid behaviour
+ public static void RowMajorGrid(string id, IEnumerable items, MeasureGridCell measureDelegate, DrawGridCell drawDelegate, GridOptions gridOptions)
+ {
+ ArgumentNullException.ThrowIfNull(items);
+ ArgumentNullException.ThrowIfNull(measureDelegate);
+ ArgumentNullException.ThrowIfNull(drawDelegate);
+ ArgumentNullException.ThrowIfNull(gridOptions);
+
+ GridImpl.ShowRowMajor(id, items, measureDelegate, drawDelegate, gridOptions);
+ }
+
+ ///
+ /// Renders a grid with the specified items and delegates.
+ ///
+ /// The type of the items.
+ /// Id for the grid.
+ /// The items to be displayed in the grid.
+ /// The delegate to measure the size of each item.
+ /// The delegate to draw each item.
+ public static void ColumnMajorGrid(string id, IEnumerable items, MeasureGridCell measureDelegate, DrawGridCell drawDelegate)
+ {
+ ArgumentNullException.ThrowIfNull(items);
+ ArgumentNullException.ThrowIfNull(measureDelegate);
+ ArgumentNullException.ThrowIfNull(drawDelegate);
+
+ GridImpl.ShowColumnMajor(id, items, measureDelegate, drawDelegate, new());
+ }
+
+ ///
+ /// Renders a grid with the specified items and delegates.
+ ///
+ /// The type of the items.
+ /// Id for the grid.
+ /// The items to be displayed in the grid.
+ /// The delegate to measure the size of each item.
+ /// The delegate to draw each item.
+ /// Additional options to modify the grid behaviour
+ public static void ColumnMajorGrid(string id, IEnumerable items, MeasureGridCell measureDelegate, DrawGridCell drawDelegate, GridOptions gridOptions)
+ {
+ ArgumentNullException.ThrowIfNull(items);
+ ArgumentNullException.ThrowIfNull(measureDelegate);
+ ArgumentNullException.ThrowIfNull(drawDelegate);
+ ArgumentNullException.ThrowIfNull(gridOptions);
+
+ GridImpl.ShowColumnMajor(id, items, measureDelegate, drawDelegate, gridOptions);
}
///
@@ -90,191 +160,275 @@ public static void Grid(IEnumerable items, MeasureGridCell measureDeleg
///
internal static class GridImpl
{
- ///
- /// Shows the grid with the specified items and delegates.
- ///
- /// The type of the items.
- /// The items to be displayed in the grid.
- /// The delegate to measure the size of each item.
- /// The delegate to draw each item.
- /// What ordering should grid items use
- public static void Show(IEnumerable items, MeasureGridCell measureDelegate, DrawGridCell drawDelegate, GridOrder gridOrder)
+ internal class GridLayout()
{
- var itemSpacing = ImGui.GetStyle().ItemSpacing;
- var itemList = items.ToArray();
- var itemDimensions = itemList.Select(i => measureDelegate(i) + itemSpacing).ToArray();
- var contentRegionAvailable = ImGui.GetContentRegionAvail();
- int numColumns = 1;
+ internal Point Dimensions { private get; init; }
+ internal float[] ColumnWidths { get; init; } = [];
+ internal float[] RowHeights { get; init; } = [];
+ internal int ColumnCount => Dimensions.X;
+ internal int RowCount => Dimensions.Y;
+ }
- while (numColumns <= itemList.Length)
- {
- int numRowsForColumns = (int)Math.Ceiling((float)itemList.Length / numColumns);
+ #region RowMajor
+ private static Point CalculateRowMajorCellLocation(int itemIndex, int columnCount)
+ {
+ int columnIndex = itemIndex % columnCount;
+ int rowIndex = itemIndex / columnCount;
+ return new(columnIndex, rowIndex);
+ }
- float maxRowWidth = 0f;
+ private static GridLayout CalculateRowMajorGridLayout(Vector2[] itemSizes, float containerWidth)
+ {
+ float widestElementHeight = itemSizes.Max(itemSize => itemSize.X);
+ GridLayout currentGridLayout = new()
+ {
+ Dimensions = new(1, itemSizes.Length),
+ ColumnWidths = [widestElementHeight],
+ RowHeights = itemSizes.Select(itemSize => itemSize.Y).ToArray()
+ };
- switch (gridOrder)
+ var previousGridLayout = currentGridLayout;
+ while (currentGridLayout.ColumnCount < itemSizes.Length)
+ {
+ int newColumnCount = currentGridLayout.ColumnCount + 1;
+ int newRowCount = (int)MathF.Ceiling(itemSizes.Length / (float)newColumnCount);
+ currentGridLayout = new()
{
- case GridOrder.RowMajor:
- float rowWidth = 0f;
-
- for (int i = 0; i < itemList.Length; i++)
- {
- if (i % numColumns == 0)
- {
- rowWidth = 0f;
- }
+ Dimensions = new(newColumnCount, newRowCount),
+ ColumnWidths = new float[newColumnCount],
+ RowHeights = new float[newRowCount],
+ };
- rowWidth += itemDimensions[i].X + itemSpacing.X;
- maxRowWidth = Math.Max(maxRowWidth, rowWidth);
- }
- break;
+ for (int i = 0; i < itemSizes.Length; i++)
+ {
+ var itemSize = itemSizes[i];
+ var cellLocation = CalculateRowMajorCellLocation(i, newColumnCount);
- case GridOrder.ColumnMajor:
- for (int i = 0; i < numColumns; i++)
- {
- int colOffset = i * numRowsForColumns;
- var colItems = itemDimensions.Skip(colOffset).Take(numRowsForColumns).ToArray();
- if (colItems.Length != 0)
- {
- maxRowWidth += colItems.Max(item => item.X) + itemSpacing.X;
- }
- }
- break;
+ float maxColumnWidth = currentGridLayout.ColumnWidths[cellLocation.X];
+ maxColumnWidth = Math.Max(maxColumnWidth, itemSize.X);
+ currentGridLayout.ColumnWidths[cellLocation.X] = maxColumnWidth;
- default:
- throw new NotImplementedException($"GridOrder '{gridOrder}' not implemented in ImGuiWidgets.Grid.Show");
+ float maxRowHeight = currentGridLayout.RowHeights[cellLocation.Y];
+ maxRowHeight = Math.Max(maxRowHeight, itemSize.Y);
+ currentGridLayout.RowHeights[cellLocation.Y] = maxRowHeight;
}
- if (maxRowWidth > contentRegionAvailable.X)
+ if (currentGridLayout.ColumnWidths.Sum() > containerWidth)
{
- numColumns--;
+ currentGridLayout = previousGridLayout;
break;
}
- // Once we have iterated all items without exceeding the contentRegionAvailable.X we
- // want to break without incrementing the number of columns because the content will fit
- else if (numColumns == itemList.Length)
+ previousGridLayout = currentGridLayout;
+ }
+
+ return currentGridLayout;
+ }
+
+ internal static void ShowRowMajor(string id, IEnumerable items, MeasureGridCell measureDelegate, DrawGridCell drawDelegate, GridOptions gridOptions)
+ {
+ if (gridOptions.GridSize.X <= 0)
+ {
+ gridOptions.GridSize = new(ImGui.GetContentRegionAvail().X, gridOptions.GridSize.Y);
+ }
+ if (gridOptions.GridSize.Y <= 0)
+ {
+ gridOptions.GridSize = new(gridOptions.GridSize.X, ImGui.GetContentRegionAvail().Y);
+ }
+
+ var itemSpacing = ImGui.GetStyle().ItemSpacing;
+ var itemList = items.ToArray();
+ int itemListCount = itemList.Length;
+ var itemDimensions = itemList.Select(i => measureDelegate(i)).ToArray();
+ var itemDimensionsWithSpacing = itemDimensions.Select(d => d + itemSpacing).ToArray();
+ var gridLayout = CalculateRowMajorGridLayout(itemDimensionsWithSpacing, gridOptions.GridSize.X);
+
+ if (gridOptions.FitToContents)
+ {
+ float width = gridLayout.ColumnWidths.Sum();
+ float height = gridLayout.RowHeights.Sum();
+ gridOptions.GridSize = new(width, height);
+ }
+
+ var drawList = ImGui.GetWindowDrawList();
+ uint borderColor = ImGui.GetColorU32(ImGui.GetStyle().Colors[(int)ImGuiCol.Border]);
+ if (ImGui.BeginChild($"rowMajorGrid_{id}", gridOptions.GridSize, ImGuiChildFlags.None))
+ {
+ var gridTopLeft = ImGui.GetCursorScreenPos();
+ if (EnableGridDebugDraw)
{
- break;
+ drawList.AddRect(gridTopLeft, gridTopLeft + gridOptions.GridSize, borderColor);
}
- // ColumnMajor grids are not allowed to have any rows with 2 or more unused cells. If we tried
- // to draw such a case we would end up displaying items that were meant for the end cells on a
- // different row which would then cause the grid to be misaligned.
- // [1] [2] [3] => [1] [3] [X]
- // [4] [2] [4]
- // Don't check for uneven columns if there is only 1 column as it isn't possible for them
- // to be uneven (an simplifies the checking logic)
- else if (gridOrder == GridOrder.ColumnMajor && numColumns != 1)
- {
- int maxItemsPerRow = numColumns;
- int minItemsPerRow = numColumns - 1;
- List itemsPerRow = [];
- int itemCount = 0;
- for (int i = 0; i < itemList.Length; i++)
+ var rowTopleft = gridTopLeft;
+ for (int rowIndex = 0; rowIndex < gridLayout.RowCount; rowIndex++)
+ {
+ bool isFirstRow = rowIndex == 0;
+ float previousRowHeight = isFirstRow ? 0f : gridLayout.RowHeights[rowIndex - 1];
+
+ float columnCursorX = rowTopleft.X;
+ float columnCursorY = rowTopleft.Y + previousRowHeight;
+ rowTopleft = new(columnCursorX, columnCursorY);
+ ImGui.SetCursorScreenPos(rowTopleft);
+
+ var cellTopLeft = ImGui.GetCursorScreenPos();
+ int itemBeginIndex = rowIndex * gridLayout.ColumnCount;
+ int itemEndIndex = Math.Min(itemBeginIndex + gridLayout.ColumnCount, itemListCount);
+ for (int itemIndex = itemBeginIndex; itemIndex < itemEndIndex; itemIndex++)
{
- itemCount++;
- // The first item will trigger the end of row log (0 % 1 == 0) and we only get in here
- // if numColumns > 1 so we can safely ignore the end of row check in that situation
- bool endOfRow = (i != 0) && (i % numColumns == 0);
- if (endOfRow)
+ int columnIndex = itemIndex - itemBeginIndex;
+ bool isFirstColumn = itemIndex == itemBeginIndex;
+ float previousCellWidth = isFirstColumn ? 0f : gridLayout.ColumnWidths[columnIndex - 1];
+
+ float cellCursorX = cellTopLeft.X + previousCellWidth;
+ float cellCursorY = cellTopLeft.Y;
+ cellTopLeft = new(cellCursorX, cellCursorY);
+ ImGui.SetCursorScreenPos(cellTopLeft);
+
+ float cellWidth = gridLayout.ColumnWidths[columnIndex];
+ float cellHeight = gridLayout.RowHeights[rowIndex];
+ Vector2 cellSize = new(cellWidth, cellHeight);
+
+ if (EnableGridDebugDraw)
{
- itemsPerRow.Add(itemCount);
- itemCount = 0;
+ drawList.AddRect(cellTopLeft, cellTopLeft + cellSize, borderColor);
}
- }
-
- if (itemsPerRow.Any(c => c < minItemsPerRow))
- {
- numColumns--;
- break;
+ drawDelegate(itemList[itemIndex], cellSize, itemDimensions[itemIndex]);
}
}
- numColumns++;
- }
-
- if (numColumns < 1)
- {
- numColumns = 1;
}
+ ImGui.EndChild();
+ }
+ #endregion
- int numRows = (int)Math.Ceiling((float)itemList.Length / numColumns);
-
- // calculate column widths and row heights
- float[] columnWidths = new float[numColumns];
- float[] rowHeights = new float[numRows];
+ #region ColumnMajor
+ private static Point CalculateColumnMajorCellLocation(int itemIndex, int rowCount)
+ {
+ int columnIndex = itemIndex / rowCount;
+ int rowIndex = itemIndex % rowCount;
+ return new(columnIndex, rowIndex);
+ }
- for (int i = 0; i < numColumns * numRows; i++)
+ private static GridLayout CalculateColumnMajorGridLayout(Vector2[] itemSizes, float containerHeight)
+ {
+ float tallestElementHeight = itemSizes.Max(itemSize => itemSize.Y);
+ GridLayout currentGridLayout = new()
{
- int column = i % numColumns;
- int row = i / numColumns;
+ Dimensions = new(itemSizes.Length, 1),
+ ColumnWidths = itemSizes.Select(itemSize => itemSize.X).ToArray(),
+ RowHeights = [tallestElementHeight],
+ };
- int itemIndex = gridOrder switch
+ var previousGridLayout = currentGridLayout;
+ while (currentGridLayout.RowCount < itemSizes.Length)
+ {
+ int newRowCount = currentGridLayout.RowCount + 1;
+ int newColumnCount = (int)MathF.Ceiling(itemSizes.Length / (float)newRowCount);
+ currentGridLayout = new()
{
- GridOrder.RowMajor => i,
- GridOrder.ColumnMajor => (column * numRows) + row,
- _ => throw new NotImplementedException()
+ Dimensions = new(newColumnCount, newRowCount),
+ ColumnWidths = new float[newColumnCount],
+ RowHeights = new float[newRowCount],
};
- if (itemIndex < itemList.Length)
+ for (int i = 0; i < itemSizes.Length; i++)
{
- var thisItemSize = itemDimensions[itemIndex];
+ var itemSize = itemSizes[i];
+ var cellLocation = CalculateColumnMajorCellLocation(i, newRowCount);
- columnWidths[column] = Math.Max(columnWidths[column], thisItemSize.X);
- rowHeights[row] = Math.Max(rowHeights[row], thisItemSize.Y);
+ float maxColumnWidth = currentGridLayout.ColumnWidths[cellLocation.X];
+ maxColumnWidth = Math.Max(maxColumnWidth, itemSize.X);
+ currentGridLayout.ColumnWidths[cellLocation.X] = maxColumnWidth;
+
+ float maxRowHeight = currentGridLayout.RowHeights[cellLocation.Y];
+ maxRowHeight = Math.Max(maxRowHeight, itemSize.Y);
+ currentGridLayout.RowHeights[cellLocation.Y] = maxRowHeight;
+ }
+
+ if (currentGridLayout.RowHeights.Sum() > containerHeight)
+ {
+ currentGridLayout = previousGridLayout;
+ break;
}
+ previousGridLayout = currentGridLayout;
}
- float totalContentWidth = columnWidths.Sum();
- float extraSpace = contentRegionAvailable.X - totalContentWidth;
- float extraSpacePerColumn = extraSpace / numColumns;
+ return currentGridLayout;
+ }
- for (int i = 0; i < numColumns; i++)
+ internal static void ShowColumnMajor(string id, IEnumerable items, MeasureGridCell measureDelegate, DrawGridCell drawDelegate, GridOptions gridOptions)
+ {
+ if (gridOptions.GridSize.X <= 0)
+ {
+ gridOptions.GridSize = new(ImGui.GetContentRegionAvail().X, gridOptions.GridSize.Y);
+ }
+ if (gridOptions.GridSize.Y <= 0)
{
- columnWidths[i] += extraSpacePerColumn;
+ gridOptions.GridSize = new(gridOptions.GridSize.X, ImGui.GetContentRegionAvail().Y);
}
- var marginTopLeftCursor = ImGui.GetCursorScreenPos();
- float gridWidth = contentRegionAvailable.X;
- float gridHeight = rowHeights.Sum(h => h);
+ var itemSpacing = ImGui.GetStyle().ItemSpacing;
+ var itemList = items.ToArray();
+ int itemListCount = itemList.Length;
+ var itemDimensions = itemList.Select(i => measureDelegate(i)).ToArray();
+ var itemDimensionsWithSpacing = itemDimensions.Select(d => d + itemSpacing).ToArray();
+ var gridLayout = CalculateColumnMajorGridLayout(itemDimensionsWithSpacing, gridOptions.GridSize.Y);
- int numCells = numColumns * numRows;
- for (int i = 0; i < numCells; i++)
+ if (gridOptions.FitToContents)
{
- var itemStartCursor = ImGui.GetCursorScreenPos();
- int column = i % numColumns;
- int row = i / numColumns;
+ float width = gridLayout.ColumnWidths.Sum();
+ float height = gridLayout.RowHeights.Sum();
+ gridOptions.GridSize = new(width, height);
+ }
- int itemIndex = gridOrder switch
+ var drawList = ImGui.GetWindowDrawList();
+ uint borderColor = ImGui.GetColorU32(ImGui.GetStyle().Colors[(int)ImGuiCol.Border]);
+ if (ImGui.BeginChild($"columnMajorGrid_{id}", gridOptions.GridSize, ImGuiChildFlags.None, ImGuiWindowFlags.HorizontalScrollbar))
+ {
+ var gridTopLeft = ImGui.GetCursorScreenPos();
+ if (EnableGridDebugDraw)
{
- GridOrder.RowMajor => i,
- GridOrder.ColumnMajor => (column * numRows) + row,
- _ => throw new NotImplementedException()
- };
-
- var cellSize = new Vector2(columnWidths[column], rowHeights[row]);
+ drawList.AddRect(gridTopLeft, gridTopLeft + gridOptions.GridSize, borderColor);
+ }
- if (itemIndex < itemList.Length)
+ var columnTopLeft = gridTopLeft;
+ for (int columnIndex = 0; columnIndex < gridLayout.ColumnCount; columnIndex++)
{
- if (EnableGridDebugDraw)
+ bool isFirstColumn = columnIndex == 0;
+ float previousColumnWidth = isFirstColumn ? 0f : gridLayout.ColumnWidths[columnIndex - 1];
+
+ float columnCursorX = columnTopLeft.X + previousColumnWidth;
+ float columnCursorY = columnTopLeft.Y;
+ columnTopLeft = new(columnCursorX, columnCursorY);
+ ImGui.SetCursorScreenPos(columnTopLeft);
+
+ var cellTopLeft = ImGui.GetCursorScreenPos();
+ int itemBeginIndex = columnIndex * gridLayout.RowCount;
+ int itemEndIndex = Math.Min(itemBeginIndex + gridLayout.RowCount, itemListCount);
+ for (int itemIndex = itemBeginIndex; itemIndex < itemEndIndex; itemIndex++)
{
- uint borderColor = ImGui.GetColorU32(ImGui.GetStyle().Colors[(int)ImGuiCol.Border]);
- var drawList = ImGui.GetWindowDrawList();
- drawList.AddRect(itemStartCursor, itemStartCursor + cellSize, ImGui.GetColorU32(borderColor));
- }
+ int rowIndex = itemIndex - itemBeginIndex;
+ bool isFirstRow = itemIndex == itemBeginIndex;
+ float previousCellHeight = isFirstRow ? 0f : itemDimensionsWithSpacing[rowIndex - 1].Y;
- drawDelegate(itemList[itemIndex], cellSize, itemDimensions[itemIndex]);
- }
+ float cellCursorX = cellTopLeft.X;
+ float cellCursorY = cellTopLeft.Y + previousCellHeight;
+ cellTopLeft = new(cellCursorX, cellCursorY);
+ ImGui.SetCursorScreenPos(cellTopLeft);
- var advance = new Vector2(marginTopLeftCursor.X, itemStartCursor.Y + cellSize.Y);
- if (column < numColumns - 1)
- {
- advance = new Vector2(itemStartCursor.X + cellSize.X, itemStartCursor.Y);
+ float cellWidth = gridLayout.ColumnWidths[columnIndex];
+ float cellHeight = gridLayout.RowHeights[rowIndex];
+ Vector2 cellSize = new(cellWidth, cellHeight);
+
+ if (EnableGridDebugDraw)
+ {
+ drawList.AddRect(cellTopLeft, cellTopLeft + cellSize, borderColor);
+ }
+ drawDelegate(itemList[itemIndex], cellSize, itemDimensions[itemIndex]);
+ }
}
- ImGui.SetCursorScreenPos(advance);
}
-
- ImGui.SetCursorScreenPos(marginTopLeftCursor + new Vector2(gridWidth, 0f));
- ImGui.Dummy(new Vector2(0, gridHeight));
+ ImGui.EndChild();
}
+ #endregion
}
}
diff --git a/ImGuiWidgets/ImGuiWidgets.csproj b/ImGuiWidgets/ImGuiWidgets.csproj
index 7b6348b..1b304f5 100644
--- a/ImGuiWidgets/ImGuiWidgets.csproj
+++ b/ImGuiWidgets/ImGuiWidgets.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/ImGuiWidgetsDemo/ImGuiWidgetsDemo.cs b/ImGuiWidgetsDemo/ImGuiWidgetsDemo.cs
index b05815f..0d0c286 100644
--- a/ImGuiWidgetsDemo/ImGuiWidgetsDemo.cs
+++ b/ImGuiWidgetsDemo/ImGuiWidgetsDemo.cs
@@ -46,8 +46,14 @@ private static void Main()
private ImGuiPopups.MessageOK MessageOK { get; } = new();
private List GridStrings { get; } = [];
- private static int InitialGridSize { get; } = 32;
- private int gridItemsToShow = InitialGridSize;
+ private static int InitialGridItemCount { get; } = 32;
+ private int GridItemsToShow { get; set; } = InitialGridItemCount;
+ private float GridHeight { get; set; } = 500f;
+ private ImGuiWidgets.GridOrder GridOrder { get; set; } = ImGuiWidgets.GridOrder.RowMajor;
+ private ImGuiWidgets.IconAlignment GridIconAlignment { get; set; } = ImGuiWidgets.IconAlignment.Vertical;
+ private bool GridIconSizeBig { get; set; } = true;
+ private bool GridIconCenterWithinCell { get; set; } = true;
+ private bool GridFitToContents { get; set; }
private EnumValues selectedEnumValue = EnumValues.Value1;
private string selectedStringValue = "Hello";
private readonly Collection possibleStringValues = ["Hello", "World", "Goodbye"];
@@ -61,7 +67,7 @@ private void OnStart()
DividerContainer.Add(new("Left", 0.25f, ShowLeftPanel));
DividerContainer.Add(new("Right", 0.75f, ShowRightPanel));
- for (int i = 0; i < InitialGridSize; i++)
+ for (int i = 0; i < InitialGridItemCount; i++)
{
string randomString = $"{i}:";
int randomAmount = new Random().Next(2, 32);
@@ -149,11 +155,11 @@ private void ShowLeftPanel(float size)
private void ShowRightPanel(float size)
{
- ImGui.Text("Right Divider Zone");
-
var ktsuIconPath = (AbsoluteDirectoryPath)Environment.CurrentDirectory / (FileName)"ktsu.png";
var ktsuTexture = ImGuiApp.GetOrLoadTexture(ktsuIconPath);
+ ImGui.Text("Right Divider Zone");
+
if (ImGuiWidgets.Image(ktsuTexture.TextureId, new(128, 128)))
{
MessageOK.Open("Click", "You chose the image");
@@ -196,37 +202,104 @@ private void ShowRightPanel(float size)
Tooltip = "You hovered over me"
});
- float iconSizePx = ImGuiApp.EmsToPx(2.5f);
ImGui.NewLine();
- bool showGridDebug = ImGuiWidgets.EnableGridDebugDraw;
- if (ImGui.Checkbox("Show Grid Debug", ref showGridDebug))
+ if (ImGui.CollapsingHeader("Grid Settings"))
{
- ImGuiWidgets.EnableGridDebugDraw = showGridDebug;
- }
- bool showIconDebug = ImGuiWidgets.EnableIconDebugDraw;
- if (ImGui.Checkbox("Show Icon Debug", ref showIconDebug))
- {
- ImGuiWidgets.EnableIconDebugDraw = showIconDebug;
+ bool showGridDebug = ImGuiWidgets.EnableGridDebugDraw;
+ if (ImGui.Checkbox("Show Grid Debug", ref showGridDebug))
+ {
+ ImGuiWidgets.EnableGridDebugDraw = showGridDebug;
+ }
+ bool showIconDebug = ImGuiWidgets.EnableIconDebugDraw;
+ if (ImGui.Checkbox("Show Icon Debug", ref showIconDebug))
+ {
+ ImGuiWidgets.EnableIconDebugDraw = showIconDebug;
+ }
+
+ {
+ bool gridIconCenterWithinCell = GridIconCenterWithinCell;
+ bool gridIconSizeBig = GridIconSizeBig;
+ bool gridFitToContents = GridFitToContents;
+ int gridItemsToShow = GridItemsToShow;
+ var gridOrder = GridOrder;
+ var gridIconAlignment = GridIconAlignment;
+ float gridHeight = GridHeight;
+
+ if (ImGui.Checkbox("Use Big Grid Icons", ref gridIconSizeBig))
+ {
+ GridIconSizeBig = gridIconSizeBig;
+ }
+ if (ImGui.Checkbox("Center within cell", ref gridIconCenterWithinCell))
+ {
+ GridIconCenterWithinCell = gridIconCenterWithinCell;
+ }
+ if (ImGui.Checkbox("Fit to contents", ref gridFitToContents))
+ {
+ GridFitToContents = gridFitToContents;
+ }
+ if (ImGui.SliderInt("Items to show", ref gridItemsToShow, 1, GridStrings.Count))
+ {
+ GridItemsToShow = gridItemsToShow;
+ }
+ if (ImGuiWidgets.Combo("Order", ref gridOrder))
+ {
+ GridOrder = gridOrder;
+ }
+ if (ImGuiWidgets.Combo("Icon Alignment", ref gridIconAlignment))
+ {
+ GridIconAlignment = gridIconAlignment;
+ }
+ if (ImGui.SliderFloat("Grid Height", ref gridHeight, 1f, 1000f))
+ {
+ GridHeight = gridHeight;
+ }
+ }
}
- ImGui.SliderInt("Grid items to show", ref gridItemsToShow, 1, GridStrings.Count);
- ImGui.SeparatorText("Grid (Column Major) Icon Alignment Horizontal");
- ImGuiWidgets.Grid(GridStrings.Take(gridItemsToShow), i => ImGuiWidgets.CalcIconSize(i, iconSizePx, ImGuiWidgets.IconAlignment.Horizontal), (item, cellSize, itemSize) =>
- {
- ImGuiWidgets.Icon(item, ktsuTexture.TextureId, iconSizePx, ImGuiWidgets.IconAlignment.Horizontal);
- }, ImGuiWidgets.GridOrder.ColumnMajor);
+ float iconSizePx = ImGuiApp.EmsToPx(2.5f);
+ float bigIconSizePx = iconSizePx * 2;
+ float gridIconSize = GridIconSizeBig ? bigIconSizePx : iconSizePx;
+ var gridSize = new Vector2(ImGui.GetContentRegionAvail().X, GridHeight);
- ImGui.NewLine();
- ImGui.SeparatorText("Grid (Row Major) Icon Alignment Vertical");
- float bigIconSize = iconSizePx * 2;
- ImGuiWidgets.Grid(GridStrings.Take(gridItemsToShow), i => ImGuiWidgets.CalcIconSize(i, bigIconSize, ImGuiWidgets.IconAlignment.Vertical), (item, cellSize, itemSize) =>
+ ImGui.Separator();
+
+ Vector2 MeasureGridSize(string item) => ImGuiWidgets.CalcIconSize(item, gridIconSize, GridIconAlignment);
+ void DrawGridCell(string item, Vector2 cellSize, Vector2 itemSize)
{
- using (new Alignment.CenterWithin(itemSize, cellSize))
+ if (GridIconCenterWithinCell)
+ {
+ using (new Alignment.CenterWithin(itemSize, cellSize))
+ {
+ ImGuiWidgets.Icon(item, ktsuTexture.TextureId, gridIconSize, GridIconAlignment);
+ }
+ }
+ else
{
- ImGuiWidgets.Icon(item, ktsuTexture.TextureId, bigIconSize, ImGuiWidgets.IconAlignment.Vertical);
+ ImGuiWidgets.Icon(item, ktsuTexture.TextureId, gridIconSize, GridIconAlignment);
}
- }, ImGuiWidgets.GridOrder.RowMajor);
+ }
+
+ ImGuiWidgets.GridOptions gridOptions = new()
+ {
+ GridSize = new(ImGui.GetContentRegionAvail().X, GridHeight),
+ FitToContents = GridFitToContents,
+ };
+ switch (GridOrder)
+ {
+ case ImGuiWidgets.GridOrder.RowMajor:
+ ImGuiWidgets.RowMajorGrid("demoRowMajorGrid", GridStrings.Take(GridItemsToShow), MeasureGridSize, DrawGridCell, gridOptions);
+ break;
+
+ case ImGuiWidgets.GridOrder.ColumnMajor:
+ ImGuiWidgets.ColumnMajorGrid("demoColumnMajorGrid", GridStrings.Take(GridItemsToShow), MeasureGridSize, DrawGridCell, gridOptions);
+ break;
+
+ default:
+ throw new NotImplementedException();
+ }
+
+ ImGui.Separator();
MessageOK.ShowIfOpen();
}