ModernUO/Projects/UOContent/Gumps/Base/Grid/GumpGrid.cs
Kamron Batman 8282b00ca2
feat: Moves gumps out of the core (#1916)
> [!Important]
> **Developer Note**
> This code change will **completely move gumps out of the core**


### Summary

- Adds `GetGumps()` convenience which exposes methods to Find/Close/Send multiple gumps. This helper is a performance improvement by eliminating the Dictionary<Player, List> lookup for gumps.
2024-08-09 19:07:32 -07:00

525 lines
14 KiB
C#

/*************************************************************************
* ModernUO *
* Copyright 2019-2023 - ModernUO Development Team *
* Email: hi@modernuo.com *
* File: GumpGrid.cs *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*************************************************************************/
using System;
using System.Collections.Generic;
using Server.Collections;
namespace Server.Gumps;
public class GumpGrid : Gump
{
private Dictionary<string, Grid> _grids = new();
public GumpGrid(int x, int y) : base(x, y)
{
}
private void AddColumn(string name, int x, int width)
{
_grids[name].Columns.Add(new Col { X = x, Width = width, });
}
private void AddRow(string name, int y, int height)
{
_grids[name].Rows.Add(new Row { Y = y, Height = height });
}
private void InitColumn(string name, int column, int w, int x)
{
var width = w / column;
for (int i = 0; i < column; i++)
{
AddColumn(name, i * width + x, width);
}
}
private void InitRow(string name, int row, int h, int y)
{
var height = h / row;
for (int i = 0; i < row; i++)
{
AddRow(name, i * height + y, height);
}
}
private static Swap Exist(ref PooledRefList<Swap> list, int index)
{
for (int i = 0; i < list.Count; i++)
{
var item = list[i];
if (item.Index == index)
{
return item;
}
}
return null;
}
private static int CalculateCustom(int column, int len, string[] sizes, ref PooledRefList<Swap> list)
{
var cropSize = 0;
for (int i = 0; i < column; i++)
{
if (sizes[i] == "*")
{
continue;
}
//percent
var percent = sizes[i].RemoveOrdinal("*");
var size = sizes[i] != percent ? len / 100 * int.Parse(percent) : int.Parse(percent);
list.Add(new Swap { Index = i, Size = size });
cropSize += size;
}
return cropSize;
}
private void InitCustomSizeRow(string name, int height, int row, string[] sizes, int y)
{
var list = PooledRefList<Swap>.Create();
var cropHeight = CalculateCustom(row, height, sizes, ref list);
var Height = height - cropHeight;
var factor = row - list.Count;
for (int i = 0; i < row; i++)
{
var swap = Exist(ref list, i);
if (swap != null)
{
var size = swap.Size;
if (i == 0)
{
AddRow(name, y, size);
}
else
{
var col = _grids[name].Rows[i - 1];
AddRow(name, col.Height + col.Y + y, size);
}
}
else
{
var size = Height / factor;
if (i == 0)
{
AddRow(name, y, size);
}
else
{
var col = _grids[name].Rows[i - 1];
AddRow(name, col.Height + col.Y + y, size);
}
}
}
list.Dispose();
}
private void InitCustomSizeColumn(string name, int width, int column, string[] sizes, int x)
{
var list = PooledRefList<Swap>.Create();
var cropWidth = CalculateCustom(column, width, sizes, ref list);
var Width = width - cropWidth;
var factor = column - list.Count;
for (int i = 0; i < column; i++)
{
var swap = Exist(ref list, i);
if (swap != null)
{
var size = swap.Size;
if (i == 0)
{
AddColumn(name, x, size);
}
else
{
var col = _grids[name].Columns[i - 1];
AddColumn(name, col.Width + col.X + x, size);
}
}
else
{
var size = Width / factor;
if (i == 0)
{
AddColumn(name, x, size);
}
else
{
var col = _grids[name].Columns[i - 1];
AddColumn(name, col.Width + col.X + x, size);
}
}
}
}
public Grid SubGrid(
string name,
string destGridName,
int columnStart,
int rowStart,
int createColumnsCount,
int createRowsCount,
int columnSpan = 0,
int rowSpan = 0,
string createColumnSize = "",
string createRowSize = "",
int marginX = 0,
int marginY = 0
)
{
if (CalculateCord(
destGridName,
columnStart,
rowStart,
columnSpan,
rowSpan,
out var x,
out var y,
out var width,
out var height
))
{
Grid(
name,
width,
height,
createColumnsCount,
createRowsCount,
createColumnSize,
createRowSize,
x + marginX,
y + marginY
);
}
return CreateGrid(name, 0, 0);
}
public Grid CreateGrid(string name, int width, int height)
{
if (!_grids.TryGetValue(name, out var grid))
{
grid = new Grid { Name = name, Width = width, Height = height };
_grids.Add(name, grid);
}
return grid;
}
public Grid Grid(
string name,
int width,
int height,
int columns,
int rows,
string columnSize = "",
string rowSize = "",
int x = 0,
int y = 0
)
{
if (columns < 1)
{
throw new Exception(nameof(columns));
}
if (rows < 1)
{
throw new Exception(nameof(columns));
}
var Grid = CreateGrid(name, width, height);
if (columnSize.Length > 0)
{
var buffer = columnSize.Split(' ');
if (buffer.Length == columns)
{
InitCustomSizeColumn(name, width, columns, buffer, x);
}
else
{
throw new Exception(nameof(columnSize));
}
}
else
{
InitColumn(name, columns, width, x);
}
if (rowSize.Length > 0)
{
var buffer = rowSize.Split(' ');
if (buffer.Length == rows)
{
InitCustomSizeRow(name, height, rows, buffer, y);
}
else
{
throw new Exception(nameof(rowSize));
}
}
else
{
InitRow(name, rows, height, y);
}
return Grid;
}
public bool CalculateCord(
string name,
int column,
int row,
int columnSpan,
int rowSpan,
out int x,
out int y,
out int width,
out int height
)
{
x = 0; y = 0; width = 0; height = 0;
if (_grids.TryGetValue(name, out var grid))
{
var count = columnSpan == 0 ? column + 1 : row + columnSpan;
for (int i = column; i < count; i++)
{
if (i >= grid.Columns.Count)
{
break;
}
var dcol = grid.Columns[i];
if (i == column)
{
x = dcol.X;
}
width += dcol.Width;
}
count = rowSpan == 0 ? row + 1 : row + rowSpan;
for (int i = row; i < count; i++)
{
if (i >= grid.Rows.Count)
{
break;
}
var drow = grid.Rows[i];
if (i == row)
{
y = drow.Y;
}
height += drow.Height;
}
if (width == 0)
{
width = grid.Width;
}
if (height == 0)
{
height = grid.Height;
}
return true;
}
return false;
}
public class ListView
{
public int LineCount { get; }
public int ItemsCount { get; }
public ListItem[] Items { get; }
public ListItem Header { get; }
public int Page { get; }
public int TotalPages { get; }
public int ColHeight { get; }
public bool CanNext { get; }
public bool CanBack { get; }
public int ColsCount { get; }
public ListView(
int itemsCount,
int columns,
int heightPerItem,
int page,
int x,
int y,
int height,
int pageItemCount,
int[] ColWidth,
int marginX = 0,
int marginY = 0,
int headerHeight = 0
)
{
ItemsCount = itemsCount;
var itemsPerPageCount = pageItemCount == 0 ? (height - marginY) / heightPerItem : pageItemCount;
LineCount = itemsPerPageCount;
if (itemsCount > 0)
{
TotalPages = itemsCount / itemsPerPageCount;
if (itemsCount % itemsPerPageCount == 0)
{
TotalPages--;
}
}
Page = page > TotalPages ? TotalPages : page;
ColsCount = columns;
ColHeight = heightPerItem;
var index = Page * itemsPerPageCount > 0 ? Page * itemsPerPageCount : 0;
var nowPageItems = index + itemsPerPageCount;
if (index > 0)
{
CanBack = true;
}
if (nowPageItems < itemsCount)
{
CanNext = true;
}
if (nowPageItems > itemsCount)
{
itemsPerPageCount = Page > 0 ? itemsCount - Page * itemsPerPageCount : itemsCount;
}
//header
Header = new ListItem
{
X = x,
Y = y + marginY,
Index = -1,
Cols = new Col[columns],
};
var length = x + marginX;
for (int col = 0; col < columns; col++)
{
Header.Cols[col] = new Col();
Header.Cols[col].Width = ColWidth[col];
Header.Cols[col].X = length;
length += ColWidth[col];
}
Items = new ListItem[itemsPerPageCount];
for (int i = 0; i < itemsPerPageCount; i++)
{
Items[i] = new ListItem
{
X = x,
Y = y + i * heightPerItem + marginY + headerHeight,
Index = index + i,
Cols = Header.Cols
};
}
}
}
public ListView AddListView(
string name,
int column,
int row,
int itemsCount,
int page,
int heightPerItem,
int createColumn,
int columnSpan = 0,
int rowSpan = 0,
int width = 0,
int height = 0,
int pageItemCount = 0,
int marginX = 0,
int marginY = 0,
int headerHeight = 0,
string colSize = ""
)
{
if (CalculateCord(name, column, row, columnSpan, rowSpan, out var x, out var y, out var w, out var h))
{
w = width > 0 ? width : w;
h = height > 0 ? height : h;
int[] colWidth = new int[createColumn];
if (colSize == string.Empty)
{
for (int i = 0; i < createColumn; i++)
{
colWidth[i] = w / createColumn;
}
}
else
{
var buffer = colSize.Split(' ');
if (buffer.Length > 0)
{
const string listName = "listView";
_grids.Add(listName, new Grid());
if (createColumn < buffer.Length)
{
Array.Resize(ref buffer, createColumn);
}
InitCustomSizeColumn(listName, w, createColumn, buffer, x);
var cols = _grids[listName].Columns;
for (var i = 0; i < createColumn; i++)
{
colWidth[i] = cols[i].Width;
}
_grids.Remove(listName);
}
}
return new ListView(
itemsCount,
createColumn,
heightPerItem,
page,
x,
y,
h,
pageItemCount,
colWidth,
marginX,
marginY,
headerHeight
);
}
return null;
}
}