/************************************************************************* * 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 . * *************************************************************************/ using System; using System.Collections.Generic; using Server.Collections; namespace Server.Gumps; public class GumpGrid : Gump { private Dictionary _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 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 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.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.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; } }