mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-10-07 04:56:04 -04:00
168 lines
4.4 KiB
C#
168 lines
4.4 KiB
C#
// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
|
|
using System;
|
|
using System.Drawing;
|
|
|
|
namespace ClassicalSharp.Gui {
|
|
|
|
public abstract class PlayerListWidget : Widget {
|
|
|
|
protected readonly Font font;
|
|
public PlayerListWidget( Game game, Font font ) : base( game ) {
|
|
HorizontalAnchor = Anchor.Centre;
|
|
VerticalAnchor = Anchor.Centre;
|
|
this.font = font;
|
|
}
|
|
|
|
protected int columnPadding = 5;
|
|
protected int elementOffset = 0;
|
|
|
|
protected const int boundsSize = 10;
|
|
protected const int namesPerColumn = 20;
|
|
protected int namesCount = 0;
|
|
protected Texture[] textures;
|
|
protected int columns;
|
|
protected int xMin, xMax, yHeight;
|
|
protected static FastColour tableCol = new FastColour( 50, 50, 50, 205 );
|
|
|
|
public override void Init() {
|
|
CreateInitialPlayerInfo();
|
|
SortPlayerInfo();
|
|
}
|
|
|
|
public abstract string GetNameUnder( int mouseX, int mouseY );
|
|
|
|
public override void Render( double delta ) {
|
|
api.Texturing = false;
|
|
api.Draw2DQuad( X, Y, Width, Height, tableCol );
|
|
api.Texturing = true;
|
|
for( int i = 0; i < namesCount; i++ ) {
|
|
Texture texture = textures[i];
|
|
if( texture.IsValid )
|
|
texture.Render( api );
|
|
}
|
|
}
|
|
|
|
public override void Dispose() {
|
|
for( int i = 0; i < namesCount; i++ ) {
|
|
Texture tex = textures[i];
|
|
api.DeleteTexture( ref tex );
|
|
textures[i] = tex;
|
|
}
|
|
}
|
|
|
|
protected void UpdateTableDimensions() {
|
|
int width = xMax - xMin;
|
|
X = xMin - boundsSize;
|
|
Y = game.Height / 2 - yHeight / 2 - boundsSize;
|
|
Width = width + boundsSize * 2;
|
|
Height = yHeight + boundsSize * 2;
|
|
}
|
|
|
|
protected void CalcMaxColumnHeight() {
|
|
yHeight = 0;
|
|
for( int col = 0; col < columns; col++ ) {
|
|
yHeight = Math.Max( GetColumnHeight( col ), yHeight );
|
|
}
|
|
}
|
|
|
|
protected int GetColumnWidth( int column ) {
|
|
int i = column * namesPerColumn;
|
|
int maxWidth = 0;
|
|
int maxIndex = Math.Min( namesCount, i + namesPerColumn );
|
|
|
|
for( ; i < maxIndex; i++ )
|
|
maxWidth = Math.Max( maxWidth, textures[i].Width );
|
|
return maxWidth + columnPadding + elementOffset;
|
|
}
|
|
|
|
protected int GetColumnHeight( int column ) {
|
|
int i = column * namesPerColumn;
|
|
int total = 0;
|
|
int maxIndex = Math.Min( namesCount, i + namesPerColumn );
|
|
|
|
for( ; i < maxIndex; i++ )
|
|
total += textures[i].Height + 1;
|
|
return total;
|
|
}
|
|
|
|
protected void SetColumnPos( int column, int x, int y ) {
|
|
int i = column * namesPerColumn;
|
|
int maxIndex = Math.Min( namesCount, i + namesPerColumn );
|
|
|
|
for( ; i < maxIndex; i++ ) {
|
|
Texture tex = textures[i];
|
|
tex.X1 = x; tex.Y1 = y;
|
|
|
|
y += tex.Height + 1;
|
|
if( ShouldOffset( i ) )
|
|
tex.X1 += elementOffset;
|
|
textures[i] = tex;
|
|
}
|
|
}
|
|
|
|
protected virtual bool ShouldOffset( int i ) { return true; }
|
|
|
|
public override void MoveTo( int newX, int newY ) {
|
|
int diffX = newX - X; int diffY = newY - Y;
|
|
for( int i = 0; i < namesCount; i++ ) {
|
|
textures[i].X1 += diffX;
|
|
textures[i].Y1 += diffY;
|
|
}
|
|
X = newX; Y = newY;
|
|
}
|
|
|
|
protected abstract void CreateInitialPlayerInfo();
|
|
|
|
protected abstract void SortInfoList();
|
|
|
|
protected void RemoveInfoAt<T>( T[] info, int i ) {
|
|
Texture tex = textures[i];
|
|
api.DeleteTexture( ref tex );
|
|
RemoveItemAt( info, i );
|
|
RemoveItemAt( textures, i );
|
|
namesCount--;
|
|
SortPlayerInfo();
|
|
}
|
|
|
|
protected void RemoveItemAt<T>( T[] array, int index ) {
|
|
for( int i = index; i < namesCount - 1; i++ ) {
|
|
array[i] = array[i + 1];
|
|
}
|
|
array[namesCount - 1] = default( T );
|
|
}
|
|
|
|
protected void SortPlayerInfo() {
|
|
columns = Utils.CeilDiv( namesCount, namesPerColumn );
|
|
SortInfoList();
|
|
columns = Utils.CeilDiv( namesCount, namesPerColumn );
|
|
CalcMaxColumnHeight();
|
|
int y = game.Height / 2 - yHeight / 2;
|
|
int midCol = columns / 2;
|
|
|
|
int centreX = game.Width / 2;
|
|
int offset = 0;
|
|
if( columns % 2 != 0 ) {
|
|
// For an odd number of columns, the middle column is centred.
|
|
offset = Utils.CeilDiv( GetColumnWidth( midCol ), 2 );
|
|
}
|
|
|
|
xMin = centreX - offset;
|
|
for( int col = midCol - 1; col >= 0; col-- ) {
|
|
xMin -= GetColumnWidth( col );
|
|
SetColumnPos( col, xMin, y );
|
|
}
|
|
xMax = centreX - offset;
|
|
for( int col = midCol; col < columns; col++ ) {
|
|
SetColumnPos( col, xMax, y );
|
|
xMax += GetColumnWidth( col );
|
|
}
|
|
|
|
OnSort();
|
|
UpdateTableDimensions();
|
|
MoveTo( X, game.Height / 4 );
|
|
}
|
|
|
|
protected virtual void OnSort() {
|
|
}
|
|
}
|
|
} |