roketto-launch/Windows/Forms/TileLayoutPanel.cs
2026-05-09 22:01:19 +01:00

147 lines
4.2 KiB
C#

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using RyzStudio.Windows.Forms;
namespace RokettoLaunch.Windows.Forms
{
public class TileLayoutPanel : System.Windows.Forms.TableLayoutPanel
{
public const int MIN_COLUMNS = 4;
public const int TILE_SIZE = 70;
public const int TILE_PADDING = 3;
public TileLayoutPanel() : base()
{
this.AllowDrop = true;
this.Margin = new Padding(0);
this.Padding = new Padding(0);
this.ColumnCount = 0;
this.RowCount = 0;
}
protected override void OnDragEnter(DragEventArgs e)
{
base.OnDragEnter(e);
if (e.Data.TryGetData<TilePanel>(out var data))
{
e.Effect = DragDropEffects.Move;
}
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Guid GroupId { get; set; } = Guid.Empty;
public void AddTilePanel(TilePanel tilePanel, int x, int y)
{
UIControl.Add(this, tilePanel, x, y);
}
public void SetGridSize(Size gridSize)
{
this.SetGridWidth(gridSize.Width);
this.SetGridHeight(gridSize.Height);
}
public void SetGridWidth(int width)
{
width = Math.Max(MIN_COLUMNS, width);
var diffColumns = width - this.ColumnCount;
var tileWidth = (TILE_SIZE + TILE_PADDING);
UIControl.Invoke(this, (x) =>
{
this.ColumnCount = width;
this.Width = (width * tileWidth);
// Resize columns
if (diffColumns == 0)
{
// Do nothing
}
else if (diffColumns > 0)
{
for (var i = 0; i < diffColumns; i++)
{
this.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, tileWidth));
}
}
else
{
for (var i = 0; i < (diffColumns * -1); i++)
{
this.ColumnStyles.RemoveAt((this.ColumnStyles.Count - 1));
}
}
// Update column width
foreach (ColumnStyle column in this.ColumnStyles)
{
column.SizeType = SizeType.Absolute;
column.Width = tileWidth;
}
});
}
public void SetGridHeight(int height)
{
var diffRows = height - this.RowCount;
var tileHeight = (TILE_SIZE + TILE_PADDING);
UIControl.Invoke(this, (x) =>
{
this.RowCount = height;
this.Height = (height * tileHeight) + TILE_PADDING;
// Resize rows
if (diffRows == 0)
{
// Do nothing
}
else if (diffRows > 0)
{
for (var i = 0; i < diffRows; i++)
{
this.RowStyles.Add(new RowStyle(SizeType.Absolute, tileHeight));
}
}
else
{
for (var i = 0; i < (diffRows * -1); i++)
{
this.RowStyles.RemoveAt((this.RowStyles.Count - 1));
}
}
// Update row height
foreach (RowStyle row in this.RowStyles)
{
row.SizeType = SizeType.Absolute;
row.Height = tileHeight;
}
});
}
public Point GetCellFromPoint(Point point)
{
var width = this.ClientSize.Width;
var height = this.ClientSize.Height;
var x = (int)((float)point.X / width * this.ColumnCount);
var y = (int)((float)point.Y / height * this.RowCount);
x = Math.Max(0, Math.Min(this.ColumnCount - 1, x));
y = Math.Max(0, Math.Min(this.RowCount - 1, y));
return new Point(x, y);
}
}
}