mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-15 02:25:32 -04:00
Bold selected name, some minor cleanup.
This commit is contained in:
parent
09faf5c45e
commit
8130d91fc3
@ -53,7 +53,9 @@ namespace ClassicalSharp {
|
|||||||
void DrawTextImpl( FastBitmap fastBmp, ref DrawTextArgs args, int x, int y ) {
|
void DrawTextImpl( FastBitmap fastBmp, ref DrawTextArgs args, int x, int y ) {
|
||||||
bool italic = args.Font.Style == FontStyle.Italic;
|
bool italic = args.Font.Style == FontStyle.Italic;
|
||||||
if( args.UseShadow ) {
|
if( args.UseShadow ) {
|
||||||
int shadowX = x + 2, shadowY = y + 2;
|
int offset = ShaowOffset( args.Font.Size );
|
||||||
|
int shadowX = x + offset, shadowY = y + offset;
|
||||||
|
|
||||||
for( int i = 0; i < parts.Count; i++ ) {
|
for( int i = 0; i < parts.Count; i++ ) {
|
||||||
TextPart part = parts[i];
|
TextPart part = parts[i];
|
||||||
part.TextColour = FastColour.Black;
|
part.TextColour = FastColour.Black;
|
||||||
@ -118,7 +120,8 @@ namespace ClassicalSharp {
|
|||||||
if( args.Font.Style == FontStyle.Italic )
|
if( args.Font.Style == FontStyle.Italic )
|
||||||
total.Width += Utils.CeilDiv( total.Height, italicSize );
|
total.Width += Utils.CeilDiv( total.Height, italicSize );
|
||||||
if( args.UseShadow && parts.Count > 0 ) {
|
if( args.UseShadow && parts.Count > 0 ) {
|
||||||
total.Width += 2; total.Height += 2;
|
int offset = ShaowOffset( args.Font.Size );
|
||||||
|
total.Width += offset; total.Height += offset;
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
@ -134,6 +137,12 @@ namespace ClassicalSharp {
|
|||||||
return (int)'?';
|
return (int)'?';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ShaowOffset( float fontSize ) {
|
||||||
|
if( fontSize < 9.9f ) return 1;
|
||||||
|
if( fontSize < 24.9f ) return 2;
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
int PtToPx( int point ) {
|
int PtToPx( int point ) {
|
||||||
return (int)Math.Ceiling( (float)point / 72 * 96 ); // TODO: non 96 dpi?
|
return (int)Math.Ceiling( (float)point / 72 * 96 ); // TODO: non 96 dpi?
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,8 @@ namespace ClassicalSharp {
|
|||||||
(g, v) => g.Map.SetFogColour( FastColour.Parse( v ) ) ),
|
(g, v) => g.Map.SetFogColour( FastColour.Parse( v ) ) ),
|
||||||
|
|
||||||
Make( -140, 0, "Clouds speed", Anchor.Centre, OnWidgetClick,
|
Make( -140, 0, "Clouds speed", Anchor.Centre, OnWidgetClick,
|
||||||
g => { StandardEnvRenderer env = game.EnvRenderer as StandardEnvRenderer;
|
g => g.Map.CloudsSpeed.ToString(),
|
||||||
return env == null ? "(not active)" : env.CloudsSpeed.ToString(); },
|
(g, v) => g.Map.SetCloudsSpeed( Single.Parse( v ) ) ),
|
||||||
(g, v) => { StandardEnvRenderer env = game.EnvRenderer as StandardEnvRenderer;
|
|
||||||
if( env != null )
|
|
||||||
env.CloudsSpeed = Single.Parse( v ); } ),
|
|
||||||
|
|
||||||
Make( -140, 50, "Clouds height", Anchor.Centre, OnWidgetClick,
|
Make( -140, 50, "Clouds height", Anchor.Centre, OnWidgetClick,
|
||||||
g => g.Map.CloudHeight.ToString(),
|
g => g.Map.CloudHeight.ToString(),
|
||||||
|
@ -16,13 +16,13 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
this.font = font;
|
this.font = font;
|
||||||
this.boldFont = boldFont;
|
this.boldFont = boldFont;
|
||||||
chatInputText = new StringBuffer( len );
|
chatInputText = new WrappableStringBuffer( len );
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture chatInputTexture, caretTexture;
|
Texture chatInputTexture, caretTexture;
|
||||||
int caretPos = -1, typingLogPos = 0;
|
int caretPos = -1, typingLogPos = 0;
|
||||||
public int YOffset;
|
public int YOffset;
|
||||||
internal StringBuffer chatInputText;
|
internal WrappableStringBuffer chatInputText;
|
||||||
readonly Font font, boldFont;
|
readonly Font font, boldFont;
|
||||||
|
|
||||||
static FastColour normalCaretCol = FastColour.White,
|
static FastColour normalCaretCol = FastColour.White,
|
||||||
|
@ -218,6 +218,7 @@
|
|||||||
<Compile Include="Utils\StringBuffer.cs" />
|
<Compile Include="Utils\StringBuffer.cs" />
|
||||||
<Compile Include="Utils\Utils.cs" />
|
<Compile Include="Utils\Utils.cs" />
|
||||||
<Compile Include="Utils\Vector3I.cs" />
|
<Compile Include="Utils\Vector3I.cs" />
|
||||||
|
<Compile Include="Utils\WrappableStringBuffer.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="app.config" />
|
<None Include="app.config" />
|
||||||
|
@ -124,6 +124,7 @@ namespace ClassicalSharp {
|
|||||||
EdgeBlock,
|
EdgeBlock,
|
||||||
EdgeLevel,
|
EdgeLevel,
|
||||||
CloudsLevel,
|
CloudsLevel,
|
||||||
|
CloudsSpeed,
|
||||||
Weather,
|
Weather,
|
||||||
|
|
||||||
SkyColour,
|
SkyColour,
|
||||||
|
@ -114,10 +114,10 @@ namespace ClassicalSharp.GraphicsAPI {
|
|||||||
/// <summary> Sets the depth test compare function that is used when depth testing is enabled. </summary>
|
/// <summary> Sets the depth test compare function that is used when depth testing is enabled. </summary>
|
||||||
public abstract void DepthTestFunc( CompareFunc func );
|
public abstract void DepthTestFunc( CompareFunc func );
|
||||||
|
|
||||||
/// <summary> Sets whether writing to the colour buffer is enabled. </summary>
|
/// <summary> Whether writing to the colour buffer is enabled. </summary>
|
||||||
public abstract bool ColourWrite { set; }
|
public abstract bool ColourWrite { set; }
|
||||||
|
|
||||||
/// <summary> Sets whether writing to the depth buffer is enabled. </summary>
|
/// <summary> Whether writing to the depth buffer is enabled. </summary>
|
||||||
public abstract bool DepthWrite { set; }
|
public abstract bool DepthWrite { set; }
|
||||||
|
|
||||||
/// <summary> Creates a vertex buffer that can have its data dynamically updated. </summary>
|
/// <summary> Creates a vertex buffer that can have its data dynamically updated. </summary>
|
||||||
@ -135,7 +135,7 @@ namespace ClassicalSharp.GraphicsAPI {
|
|||||||
/// but the index buffer's data cannot be updated after creation. </summary>
|
/// but the index buffer's data cannot be updated after creation. </summary>
|
||||||
public abstract int CreateIb( ushort[] indices, int indicesCount );
|
public abstract int CreateIb( ushort[] indices, int indicesCount );
|
||||||
|
|
||||||
/// <summary> Creates a static vertex buffer that has its data set at creation,
|
/// <summary> Creates a static index buffer that has its data set at creation,
|
||||||
/// but the index buffer's data cannot be updated after creation. </summary>
|
/// but the index buffer's data cannot be updated after creation. </summary>
|
||||||
public abstract int CreateIb( IntPtr indices, int indicesCount );
|
public abstract int CreateIb( IntPtr indices, int indicesCount );
|
||||||
|
|
||||||
|
@ -29,6 +29,9 @@ namespace ClassicalSharp {
|
|||||||
/// <summary> Height of the clouds in world space. </summary>
|
/// <summary> Height of the clouds in world space. </summary>
|
||||||
public int CloudHeight;
|
public int CloudHeight;
|
||||||
|
|
||||||
|
/// <summary> How fast clouds should travel across the map, defaults to 1. </summary>
|
||||||
|
public float CloudsSpeed = 1;
|
||||||
|
|
||||||
/// <summary> Colour applied to blocks located in direct sunlight. </summary>
|
/// <summary> Colour applied to blocks located in direct sunlight. </summary>
|
||||||
public FastColour Sunlight;
|
public FastColour Sunlight;
|
||||||
public FastColour SunlightXSide, SunlightZSide, SunlightYBottom;
|
public FastColour SunlightXSide, SunlightZSide, SunlightYBottom;
|
||||||
@ -45,14 +48,14 @@ namespace ClassicalSharp {
|
|||||||
/// <summary> Unique uuid/guid of this particular map. </summary>
|
/// <summary> Unique uuid/guid of this particular map. </summary>
|
||||||
public Guid Uuid;
|
public Guid Uuid;
|
||||||
|
|
||||||
/// <summary> Block that surrounds map and is perpendicular to the Y plane. (default water) </summary>
|
/// <summary> Block that surrounds map the map horizontally (default water) </summary>
|
||||||
public Block EdgeBlock = Block.StillWater;
|
public Block EdgeBlock = Block.StillWater;
|
||||||
|
|
||||||
/// <summary> Height of the map edge in world space. </summary>
|
/// <summary> Height of the map edge in world space. </summary>
|
||||||
public int EdgeHeight;
|
public int EdgeHeight;
|
||||||
|
|
||||||
/// <summary> Block that surrounds the map that is below the map, fills part of the vertical sides,
|
/// <summary> Block that surrounds the map that fills the bottom of the map horizontally,
|
||||||
/// and also perpendicular to the Y plane. (default bedrock) </summary>
|
/// fills part of the vertical sides of the map, and also surrounds map the map horizontally. (default bedrock) </summary>
|
||||||
public Block SidesBlock = Block.Bedrock;
|
public Block SidesBlock = Block.Bedrock;
|
||||||
|
|
||||||
/// <summary> Maximum height of the various parts of the map sides, in world space. </summary>
|
/// <summary> Maximum height of the various parts of the map sides, in world space. </summary>
|
||||||
@ -79,6 +82,7 @@ namespace ClassicalSharp {
|
|||||||
Uuid = Guid.NewGuid();
|
Uuid = Guid.NewGuid();
|
||||||
EdgeBlock = Block.StillWater;
|
EdgeBlock = Block.StillWater;
|
||||||
SidesBlock = Block.Bedrock;
|
SidesBlock = Block.Bedrock;
|
||||||
|
CloudsSpeed = 1;
|
||||||
|
|
||||||
ResetLight();
|
ResetLight();
|
||||||
SkyCol = DefaultSkyColour;
|
SkyCol = DefaultSkyColour;
|
||||||
@ -125,6 +129,10 @@ namespace ClassicalSharp {
|
|||||||
/// EnvVariableChanged event with the variable 'CloudsLevel'. </summary>
|
/// EnvVariableChanged event with the variable 'CloudsLevel'. </summary>
|
||||||
public void SetCloudsLevel( int level ) { Set( level, ref CloudHeight, EnvVar.CloudsLevel ); }
|
public void SetCloudsLevel( int level ) { Set( level, ref CloudHeight, EnvVar.CloudsLevel ); }
|
||||||
|
|
||||||
|
/// <summary> Sets the current clouds speed, and raises the
|
||||||
|
/// EnvVariableChanged event with the variable 'CloudsSpeed'. </summary>
|
||||||
|
public void SetCloudsSpeed( float speed ) { Set( speed, ref CloudsSpeed, EnvVar.CloudsSpeed ); }
|
||||||
|
|
||||||
/// <summary> Sets the height of the map edges in world space, and raises the
|
/// <summary> Sets the height of the map edges in world space, and raises the
|
||||||
/// EnvVariableChanged event with the variable 'EdgeLevel'. </summary>
|
/// EnvVariableChanged event with the variable 'EdgeLevel'. </summary>
|
||||||
public void SetEdgeLevel( int level ) { Set( level, ref EdgeHeight, EnvVar.EdgeLevel ); }
|
public void SetEdgeLevel( int level ) { Set( level, ref EdgeHeight, EnvVar.EdgeLevel ); }
|
||||||
@ -214,14 +222,14 @@ namespace ClassicalSharp {
|
|||||||
return mapData[(p.Y * Length + p.Z) * Width + p.X];
|
return mapData[(p.Y * Length + p.Z) * Width + p.X];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Returns the block at the given world coordinates withbounds checking,
|
/// <summary> Returns the block at the given world coordinates with bounds checking,
|
||||||
/// returning 0 is the coordinates were outside the map. </summary>
|
/// returning 0 is the coordinates were outside the map. </summary>
|
||||||
public byte SafeGetBlock( int x, int y, int z ) {
|
public byte SafeGetBlock( int x, int y, int z ) {
|
||||||
return IsValidPos( x, y, z ) ?
|
return IsValidPos( x, y, z ) ?
|
||||||
mapData[(y * Length + z) * Width + x] : (byte)0;
|
mapData[(y * Length + z) * Width + x] : (byte)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Returns the block at the given world coordinates withbounds checking,
|
/// <summary> Returns the block at the given world coordinates with bounds checking,
|
||||||
/// returning 0 is the coordinates were outside the map. </summary>
|
/// returning 0 is the coordinates were outside the map. </summary>
|
||||||
public byte SafeGetBlock( Vector3I p ) {
|
public byte SafeGetBlock( Vector3I p ) {
|
||||||
return IsValidPos( p.X, p.Y, p.Z ) ?
|
return IsValidPos( p.X, p.Y, p.Z ) ?
|
||||||
|
@ -108,7 +108,6 @@ namespace ClassicalSharp {
|
|||||||
|
|
||||||
while( reader.size > 0 ) {
|
while( reader.size > 0 ) {
|
||||||
byte opcode = reader.buffer[0];
|
byte opcode = reader.buffer[0];
|
||||||
Console.WriteLine( (PacketId)opcode );
|
|
||||||
// Fix for older D3 servers which wrote one byte too many for HackControl packets.
|
// Fix for older D3 servers which wrote one byte too many for HackControl packets.
|
||||||
if( opcode == 0xFF && lastOpcode == PacketId.CpeHackControl ) {
|
if( opcode == 0xFF && lastOpcode == PacketId.CpeHackControl ) {
|
||||||
reader.Remove( 1 );
|
reader.Remove( 1 );
|
||||||
|
@ -12,7 +12,6 @@ namespace ClassicalSharp.Renderers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int cloudsVb = -1, cloudVertices, skyVb = -1, skyVertices;
|
int cloudsVb = -1, cloudVertices, skyVb = -1, skyVertices;
|
||||||
public float CloudsSpeed = 1;
|
|
||||||
bool legacy;
|
bool legacy;
|
||||||
|
|
||||||
public void SetUseLegacyMode( bool legacy ) {
|
public void SetUseLegacyMode( bool legacy ) {
|
||||||
@ -92,7 +91,7 @@ namespace ClassicalSharp.Renderers {
|
|||||||
|
|
||||||
void RenderClouds( double delta ) {
|
void RenderClouds( double delta ) {
|
||||||
double time = game.accumulator;
|
double time = game.accumulator;
|
||||||
float offset = (float)( time / 2048f * 0.6f * CloudsSpeed );
|
float offset = (float)( time / 2048f * 0.6f * map.CloudsSpeed );
|
||||||
graphics.SetMatrixMode( MatrixType.Texture );
|
graphics.SetMatrixMode( MatrixType.Texture );
|
||||||
Matrix4 matrix = Matrix4.Translate( offset, 0, 0 );
|
Matrix4 matrix = Matrix4.Translate( offset, 0, 0 );
|
||||||
graphics.LoadMatrix( ref matrix );
|
graphics.LoadMatrix( ref matrix );
|
||||||
|
@ -2,15 +2,14 @@
|
|||||||
|
|
||||||
namespace ClassicalSharp {
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
public sealed class StringBuffer {
|
public class StringBuffer {
|
||||||
|
|
||||||
char[] value, wrap;
|
protected char[] value;
|
||||||
int capacity;
|
protected int capacity;
|
||||||
|
|
||||||
public StringBuffer( int capacity ) {
|
public StringBuffer( int capacity ) {
|
||||||
this.capacity = capacity;
|
this.capacity = capacity;
|
||||||
value = new char[capacity];
|
value = new char[capacity];
|
||||||
wrap = new char[capacity];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringBuffer Append( int index, char c ) {
|
public StringBuffer Append( int index, char c ) {
|
||||||
@ -97,84 +96,6 @@ namespace ClassicalSharp {
|
|||||||
return new String( value, 0, length );
|
return new String( value, 0, length );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WordWrap( ref string[] lines, ref int[] lineLens, int lineSize ) {
|
|
||||||
int len = Length;
|
|
||||||
for( int i = 0; i < lines.Length; i++ ) {
|
|
||||||
lines[i] = null;
|
|
||||||
lineLens[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Need to make a copy because we mutate the characters.
|
|
||||||
char[] realText = value;
|
|
||||||
MakeWrapCopy();
|
|
||||||
|
|
||||||
int linesCount = 0;
|
|
||||||
for( int index = 0; index < capacity; index += lineSize ) {
|
|
||||||
if( value[index] == '\0' )
|
|
||||||
break;
|
|
||||||
|
|
||||||
int lineEnd = index + (lineSize - 1);
|
|
||||||
int nextLine = index + lineSize;
|
|
||||||
linesCount++;
|
|
||||||
|
|
||||||
// Do we need word wrapping?
|
|
||||||
bool needWrap = !IsWrapper( value[lineEnd] ) && nextLine < capacity && !IsWrapper( value[nextLine] );
|
|
||||||
int wrappedLen = needWrap ? WrapLine( index, lineSize ) : lineSize;
|
|
||||||
|
|
||||||
// Calculate the maximum size of this line
|
|
||||||
int lineLen = lineSize;
|
|
||||||
for( int i = lineEnd; i >= index; i-- ) {
|
|
||||||
if( value[i] != '\0' ) break;
|
|
||||||
lineLen--;
|
|
||||||
}
|
|
||||||
lineLens[index / lineSize] = Math.Min( lineLen, wrappedLen );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output the used lines
|
|
||||||
OutputLines( ref lines, linesCount, lineSize );
|
|
||||||
value = realText;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MakeWrapCopy() {
|
|
||||||
int len = Length;
|
|
||||||
for( int i = 0; i < len; i++ )
|
|
||||||
wrap[i] = value[i];
|
|
||||||
|
|
||||||
for( int i = len; i < capacity; i++ )
|
|
||||||
wrap[i] = '\0';
|
|
||||||
value = wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputLines( ref string[] lines, int linesCount, int lineSize ) {
|
|
||||||
for( int i = 0; i < capacity; i++ ) {
|
|
||||||
if( value[i] == '\0' ) value[i] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
for( int i = 0; i < Math.Max( 1, linesCount ); i++ ) {
|
|
||||||
lines[i] = new String( value, i * lineSize, lineSize );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int WrapLine( int index, int lineSize ) {
|
|
||||||
int lineEnd = index + (lineSize - 1);
|
|
||||||
// wrap - but we don't want to wrap if the entire line is filled.
|
|
||||||
for( int i = lineEnd; i >= index + 1; i-- ) {
|
|
||||||
if( IsWrapper( value[i] ) ) {
|
|
||||||
for( int j = lineEnd; j >= i + 1; j-- ) {
|
|
||||||
InsertAt( index + lineSize, value[j] );
|
|
||||||
value[j] = ' ';
|
|
||||||
}
|
|
||||||
return (i + 1) - index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lineSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsWrapper( char c ) {
|
|
||||||
return c == '\0' || c == ' ' || c == '-' || c == '>'
|
|
||||||
|| c == '<' || c == '/' || c == '\\';
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return new String( value, 0, Length );
|
return new String( value, 0, Length );
|
||||||
}
|
}
|
||||||
|
91
ClassicalSharp/Utils/WrappableStringBuffer.cs
Normal file
91
ClassicalSharp/Utils/WrappableStringBuffer.cs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace ClassicalSharp {
|
||||||
|
|
||||||
|
public sealed class WrappableStringBuffer : StringBuffer {
|
||||||
|
|
||||||
|
char[] wrap;
|
||||||
|
|
||||||
|
public WrappableStringBuffer( int capacity ) : base( capacity ) {
|
||||||
|
wrap = new char[capacity];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WordWrap( ref string[] lines, ref int[] lineLens, int lineSize ) {
|
||||||
|
int len = Length;
|
||||||
|
for( int i = 0; i < lines.Length; i++ ) {
|
||||||
|
lines[i] = null;
|
||||||
|
lineLens[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to make a copy because we mutate the characters.
|
||||||
|
char[] realText = value;
|
||||||
|
MakeWrapCopy();
|
||||||
|
|
||||||
|
int linesCount = 0;
|
||||||
|
for( int index = 0; index < capacity; index += lineSize ) {
|
||||||
|
if( value[index] == '\0' )
|
||||||
|
break;
|
||||||
|
|
||||||
|
int lineEnd = index + (lineSize - 1);
|
||||||
|
int nextLine = index + lineSize;
|
||||||
|
linesCount++;
|
||||||
|
|
||||||
|
// Do we need word wrapping?
|
||||||
|
bool needWrap = !IsWrapper( value[lineEnd] ) && nextLine < capacity && !IsWrapper( value[nextLine] );
|
||||||
|
int wrappedLen = needWrap ? WrapLine( index, lineSize ) : lineSize;
|
||||||
|
|
||||||
|
// Calculate the maximum size of this line
|
||||||
|
int lineLen = lineSize;
|
||||||
|
for( int i = lineEnd; i >= index; i-- ) {
|
||||||
|
if( value[i] != '\0' ) break;
|
||||||
|
lineLen--;
|
||||||
|
}
|
||||||
|
lineLens[index / lineSize] = Math.Min( lineLen, wrappedLen );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output the used lines
|
||||||
|
OutputLines( ref lines, linesCount, lineSize );
|
||||||
|
value = realText;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakeWrapCopy() {
|
||||||
|
int len = Length;
|
||||||
|
for( int i = 0; i < len; i++ )
|
||||||
|
wrap[i] = value[i];
|
||||||
|
|
||||||
|
for( int i = len; i < capacity; i++ )
|
||||||
|
wrap[i] = '\0';
|
||||||
|
value = wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OutputLines( ref string[] lines, int linesCount, int lineSize ) {
|
||||||
|
for( int i = 0; i < capacity; i++ ) {
|
||||||
|
if( value[i] == '\0' ) value[i] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int i = 0; i < Math.Max( 1, linesCount ); i++ ) {
|
||||||
|
lines[i] = new String( value, i * lineSize, lineSize );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int WrapLine( int index, int lineSize ) {
|
||||||
|
int lineEnd = index + (lineSize - 1);
|
||||||
|
// wrap - but we don't want to wrap if the entire line is filled.
|
||||||
|
for( int i = lineEnd; i >= index + 1; i-- ) {
|
||||||
|
if( IsWrapper( value[i] ) ) {
|
||||||
|
for( int j = lineEnd; j >= i + 1; j-- ) {
|
||||||
|
InsertAt( index + lineSize, value[j] );
|
||||||
|
value[j] = ' ';
|
||||||
|
}
|
||||||
|
return (i + 1) - index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lineSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsWrapper( char c ) {
|
||||||
|
return c == '\0' || c == ' ' || c == '-' || c == '>'
|
||||||
|
|| c == '<' || c == '/' || c == '\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,9 +8,11 @@ namespace Launcher2 {
|
|||||||
public sealed class ClassiCubeServersScreen : LauncherInputScreen {
|
public sealed class ClassiCubeServersScreen : LauncherInputScreen {
|
||||||
|
|
||||||
const int tableIndex = 6;
|
const int tableIndex = 6;
|
||||||
|
Font boldInputFont;
|
||||||
public ClassiCubeServersScreen( LauncherWindow game ) : base( game ) {
|
public ClassiCubeServersScreen( LauncherWindow game ) : base( game ) {
|
||||||
titleFont = new Font( "Arial", 16, FontStyle.Bold );
|
titleFont = new Font( "Arial", 16, FontStyle.Bold );
|
||||||
inputFont = new Font( "Arial", 13, FontStyle.Regular );
|
inputFont = new Font( "Arial", 13, FontStyle.Regular );
|
||||||
|
boldInputFont = new Font( "Arial", 13, FontStyle.Bold );
|
||||||
enterIndex = 4;
|
enterIndex = 4;
|
||||||
widgets = new LauncherWidget[7];
|
widgets = new LauncherWidget[7];
|
||||||
}
|
}
|
||||||
@ -43,6 +45,15 @@ namespace Launcher2 {
|
|||||||
Resize();
|
Resize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void RedrawLastInput() {
|
||||||
|
base.RedrawLastInput();
|
||||||
|
if( lastInput == widgets[3] ) {
|
||||||
|
LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex];
|
||||||
|
table.SelectedHash = widgets[3].Text;
|
||||||
|
Resize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void Init() {
|
public override void Init() {
|
||||||
base.Init();
|
base.Init();
|
||||||
@ -55,13 +66,13 @@ namespace Launcher2 {
|
|||||||
using( drawer ) {
|
using( drawer ) {
|
||||||
drawer.SetBitmap( game.Framebuffer );
|
drawer.SetBitmap( game.Framebuffer );
|
||||||
game.ClearArea( 0, 0, game.Width, 100 );
|
game.ClearArea( 0, 0, game.Width, 100 );
|
||||||
drawer.Clear( game.clearColour, 0, 100,
|
drawer.Clear( game.clearColour, 0, 100,
|
||||||
game.Width, game.Height - 100 );
|
game.Width, game.Height - 100 );
|
||||||
|
|
||||||
Draw();
|
Draw();
|
||||||
LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex];
|
LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex];
|
||||||
table.ClampIndex();
|
table.ClampIndex();
|
||||||
table.Redraw( drawer, inputFont, titleFont );
|
table.Redraw( drawer, inputFont, titleFont, boldInputFont );
|
||||||
}
|
}
|
||||||
Dirty = true;
|
Dirty = true;
|
||||||
}
|
}
|
||||||
@ -69,31 +80,32 @@ namespace Launcher2 {
|
|||||||
void Draw() {
|
void Draw() {
|
||||||
widgetIndex = 0;
|
widgetIndex = 0;
|
||||||
|
|
||||||
MakeLabelAt( "Search", titleFont, Anchor.Centre, Anchor.LeftOrTop, -200, 10 );
|
MakeLabelAt( "Search", titleFont, Anchor.Centre, Anchor.LeftOrTop, -190, 10 );
|
||||||
MakeInput( Get(), 270, Anchor.LeftOrTop, false, -25, 5, 32 );
|
MakeInput( Get(), 270, Anchor.LeftOrTop, false, -5, 5, 32 );
|
||||||
|
|
||||||
MakeLabelAt( "../play/", inputFont, Anchor.Centre, Anchor.LeftOrTop, -210, 55 );
|
MakeLabelAt( "/play/", inputFont, Anchor.Centre, Anchor.LeftOrTop, -215, 55 );
|
||||||
MakeInput( Get(), 320, Anchor.LeftOrTop, false, -20, 50, 32 );
|
MakeInput( Get(), 310, Anchor.LeftOrTop, false, -35, 50, 32 );
|
||||||
((LauncherInputWidget)widgets[3]).ClipboardFilter = HashFilter;
|
((LauncherInputWidget)widgets[3]).ClipboardFilter = HashFilter;
|
||||||
|
|
||||||
MakeButtonAt( "Connect", 100, 30, titleFont, Anchor.LeftOrTop,
|
|
||||||
180, 5, ConnectToServer );
|
|
||||||
MakeButtonAt( "Back", 70, 30, titleFont, Anchor.LeftOrTop,
|
MakeButtonAt( "Back", 70, 30, titleFont, Anchor.LeftOrTop,
|
||||||
195, 50, (x, y) => game.SetScreen( new ClassiCubeScreen( game ) ) );
|
195, 5, (x, y) => game.SetScreen( new ClassiCubeScreen( game ) ) );
|
||||||
|
MakeButtonAt( "Connect", 100, 30, titleFont, Anchor.LeftOrTop,
|
||||||
|
180, 50, ConnectToServer );
|
||||||
MakeTableWidget();
|
MakeTableWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MakeTableWidget() {
|
void MakeTableWidget() {
|
||||||
if( widgets[tableIndex] != null ) {
|
if( widgets[tableIndex] != null ) {
|
||||||
LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex];
|
LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex];
|
||||||
table.Redraw( drawer, inputFont, titleFont );
|
table.Redraw( drawer, inputFont, titleFont, boldInputFont );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LauncherTableWidget widget = new LauncherTableWidget( game );
|
LauncherTableWidget widget = new LauncherTableWidget( game );
|
||||||
widget.CurrentIndex = 0;
|
widget.CurrentIndex = 0;
|
||||||
widget.SetEntries( game.Session.Servers );
|
widget.SetEntries( game.Session.Servers );
|
||||||
widget.DrawAt( drawer, inputFont, titleFont, Anchor.LeftOrTop, Anchor.LeftOrTop, 0, 100 );
|
widget.DrawAt( drawer, inputFont, titleFont, boldInputFont,
|
||||||
|
Anchor.LeftOrTop, Anchor.LeftOrTop, 0, 100 );
|
||||||
|
|
||||||
widget.NeedRedraw = Resize;
|
widget.NeedRedraw = Resize;
|
||||||
widget.SelectedChanged = SelectedChanged;
|
widget.SelectedChanged = SelectedChanged;
|
||||||
@ -136,6 +148,7 @@ namespace Launcher2 {
|
|||||||
|
|
||||||
public override void Dispose() {
|
public override void Dispose() {
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
|
boldInputFont.Dispose();
|
||||||
game.Window.Mouse.WheelChanged -= MouseWheelChanged;
|
game.Window.Mouse.WheelChanged -= MouseWheelChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ namespace Launcher2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void RedrawLastInput() {
|
protected virtual void RedrawLastInput() {
|
||||||
using( drawer ) {
|
using( drawer ) {
|
||||||
drawer.SetBitmap( game.Framebuffer );
|
drawer.SetBitmap( game.Framebuffer );
|
||||||
if( lastInput.Width > lastInput.ButtonWidth )
|
if( lastInput.Width > lastInput.ButtonWidth )
|
||||||
@ -94,7 +94,7 @@ namespace Launcher2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected LauncherInputWidget lastInput;
|
protected LauncherInputWidget lastInput;
|
||||||
protected void InputClick( int mouseX, int mouseY ) {
|
protected virtual void InputClick( int mouseX, int mouseY ) {
|
||||||
LauncherInputWidget input = (LauncherInputWidget)selectedWidget;
|
LauncherInputWidget input = (LauncherInputWidget)selectedWidget;
|
||||||
using( drawer ) {
|
using( drawer ) {
|
||||||
drawer.SetBitmap( game.Framebuffer );
|
drawer.SetBitmap( game.Framebuffer );
|
||||||
|
@ -41,6 +41,9 @@ namespace Launcher2 {
|
|||||||
lastPress = DateTime.UtcNow;
|
lastPress = DateTime.UtcNow;
|
||||||
}
|
}
|
||||||
SelectedChanged( entry.Hash );
|
SelectedChanged( entry.Hash );
|
||||||
|
SelectedHash = entry.Hash;
|
||||||
|
|
||||||
|
NeedRedraw();
|
||||||
lastIndex = i;
|
lastIndex = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ namespace Launcher2 {
|
|||||||
|
|
||||||
public Action NeedRedraw;
|
public Action NeedRedraw;
|
||||||
public Action<string> SelectedChanged;
|
public Action<string> SelectedChanged;
|
||||||
|
public string SelectedHash;
|
||||||
|
|
||||||
TableEntry[] entries, usedEntries;
|
TableEntry[] entries, usedEntries;
|
||||||
internal List<ServerListEntry> servers;
|
internal List<ServerListEntry> servers;
|
||||||
@ -58,26 +59,26 @@ namespace Launcher2 {
|
|||||||
public int Y, Height;
|
public int Y, Height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawAt( IDrawer2D drawer, Font font, Font titleFont,
|
public void DrawAt( IDrawer2D drawer, Font font, Font titleFont, Font boldFont,
|
||||||
Anchor horAnchor, Anchor verAnchor, int x, int y ) {
|
Anchor horAnchor, Anchor verAnchor, int x, int y ) {
|
||||||
CalculateOffset( x, y, horAnchor, verAnchor );
|
CalculateOffset( x, y, horAnchor, verAnchor );
|
||||||
Redraw( drawer, font, titleFont );
|
Redraw( drawer, font, titleFont, boldFont );
|
||||||
}
|
}
|
||||||
|
|
||||||
static FastColour backCol = new FastColour( 120, 85, 151 ), foreCol = new FastColour( 160, 133, 186 );
|
static FastColour backCol = new FastColour( 120, 85, 151 ), foreCol = new FastColour( 160, 133, 186 );
|
||||||
static FastColour scrollCol = new FastColour( 200, 184, 216 );
|
static FastColour scrollCol = new FastColour( 200, 184, 216 );
|
||||||
public void Redraw( IDrawer2D drawer, Font font, Font titleFont ) {
|
public void Redraw( IDrawer2D drawer, Font font, Font titleFont, Font boldFont ) {
|
||||||
Utils.Clamp( ref ColumnWidths[0], 20, Window.Width - 20 );
|
Utils.Clamp( ref ColumnWidths[0], 20, Window.Width - 20 );
|
||||||
int x = X + 5;
|
int x = X + 5;
|
||||||
DrawGrid( drawer, font, titleFont );
|
DrawGrid( drawer, font, titleFont );
|
||||||
x += DrawColumn( drawer, true, font, titleFont, "Name", ColumnWidths[0], x, e => e.Name ) + 5;
|
x += DrawColumn( drawer, true, font, titleFont, boldFont, "Name", ColumnWidths[0], x, e => e.Name ) + 5;
|
||||||
x += DrawColumn( drawer, false, font, titleFont, "Players", ColumnWidths[1], x, e => e.Players ) + 5;
|
x += DrawColumn( drawer, false, font, titleFont, boldFont, "Players", ColumnWidths[1], x, e => e.Players ) + 5;
|
||||||
|
|
||||||
Width = Window.Width;
|
Width = Window.Width;
|
||||||
DrawScrollbar( drawer );
|
DrawScrollbar( drawer );
|
||||||
}
|
}
|
||||||
|
|
||||||
int DrawColumn( IDrawer2D drawer, bool separator, Font font, Font titleFont,
|
int DrawColumn( IDrawer2D drawer, bool separator, Font font, Font titleFont, Font boldFont,
|
||||||
string header, int maxWidth, int x, Func<TableEntry, string> filter ) {
|
string header, int maxWidth, int x, Func<TableEntry, string> filter ) {
|
||||||
int y = Y + 10;
|
int y = Y + 10;
|
||||||
DrawTextArgs args = new DrawTextArgs( header, titleFont, true );
|
DrawTextArgs args = new DrawTextArgs( header, titleFont, true );
|
||||||
@ -87,6 +88,9 @@ namespace Launcher2 {
|
|||||||
|
|
||||||
for( int i = CurrentIndex; i < Count; i++ ) {
|
for( int i = CurrentIndex; i < Count; i++ ) {
|
||||||
args = new DrawTextArgs( filter( usedEntries[i] ), font, true );
|
args = new DrawTextArgs( filter( usedEntries[i] ), font, true );
|
||||||
|
if( usedEntries[i].Hash == SelectedHash ) {
|
||||||
|
args.Font = boldFont;
|
||||||
|
}
|
||||||
if( !DrawColumnEntry( drawer, ref args, maxWidth, x, ref y, ref usedEntries[i] ) ) {
|
if( !DrawColumnEntry( drawer, ref args, maxWidth, x, ref y, ref usedEntries[i] ) ) {
|
||||||
maxIndex = i;
|
maxIndex = i;
|
||||||
break;
|
break;
|
||||||
|
@ -46,7 +46,8 @@ namespace Launcher2 {
|
|||||||
drawer.DrawRect( FastColour.Black, X + 2, Y + 2, Width - 4, Height - 4 );
|
drawer.DrawRect( FastColour.Black, X + 2, Y + 2, Width - 4, Height - 4 );
|
||||||
|
|
||||||
args.SkipPartsCheck = true;
|
args.SkipPartsCheck = true;
|
||||||
drawer.DrawText( ref args, X + 7, Y + 2 );
|
int y = Y + 2 + (Height - size.Height ) / 2;
|
||||||
|
drawer.DrawText( ref args, X + 5, y );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Appends a character to the end of the currently entered text. </summary>
|
/// <summary> Appends a character to the end of the currently entered text. </summary>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user