mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 11:35:08 -04:00
Text input now properly wraps colour codes across multiple lines. (Thanks xnotx123)
This commit is contained in:
parent
d70851a1b9
commit
7af045f9a9
@ -184,8 +184,9 @@ namespace ClassicalSharp {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Splits the input string by recognised colour codes. (e.g &f) </summary>
|
||||
protected void SplitText( string value ) {
|
||||
char code = 'F';
|
||||
char code = 'f';
|
||||
for( int i = 0; i < value.Length; i++ ) {
|
||||
int nextAnd = value.IndexOf( '&', i );
|
||||
int partLength = nextAnd == -1 ? value.Length - i : nextAnd - i;
|
||||
@ -199,8 +200,8 @@ namespace ClassicalSharp {
|
||||
|
||||
if( nextAnd >= 0 && nextAnd + 1 < value.Length ) {
|
||||
if( !ValidColour( value[nextAnd + 1] ) ) {
|
||||
code = 'F';
|
||||
i--; // include the character that isn't a colour code.
|
||||
code = 'f';
|
||||
i--; // include character that isn't a valid colour code.
|
||||
} else {
|
||||
code = value[nextAnd + 1];
|
||||
}
|
||||
@ -208,8 +209,27 @@ namespace ClassicalSharp {
|
||||
}
|
||||
}
|
||||
|
||||
internal bool ValidColour( char c ) {
|
||||
/// <summary> Returns whenever the given character is a valid colour code. </summary>
|
||||
public bool ValidColour( char c ) {
|
||||
return (int)c < 256 && Colours[c].A > 0;
|
||||
}
|
||||
|
||||
/// <summary> Returns the last valid colour code in the given input,
|
||||
/// or \0 if no valid colour code was found. </summary>
|
||||
public char LastColour( string input, int start ) {
|
||||
if( start >= input.Length )
|
||||
start = input.Length - 1;
|
||||
|
||||
for( int i = start; i >= 0; i--) {
|
||||
if( input[i] != '&' ) continue;
|
||||
if( i < input.Length - 1 && ValidColour( input[i + 1] ) )
|
||||
return input[i + 1];
|
||||
}
|
||||
return '\0';
|
||||
}
|
||||
|
||||
public static bool IsWhiteColour( char c ) {
|
||||
return c == '\0' || c == 'f' || c == 'F';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ namespace ClassicalSharp {
|
||||
buffer.Append( ref index, " matching names: " );
|
||||
|
||||
foreach( string match in matches ) {
|
||||
if( (match.Length + 1 + buffer.Length) > 64 ) break;
|
||||
if( (match.Length + 1 + buffer.Length) > LineLength ) break;
|
||||
buffer.Append( ref index, match );
|
||||
buffer.Append( ref index, ' ' );
|
||||
}
|
||||
@ -163,9 +163,9 @@ namespace ClassicalSharp {
|
||||
void UpKey( bool controlDown ) {
|
||||
if( controlDown ) {
|
||||
int pos = caretPos == -1 ? chatInputText.Length : caretPos;
|
||||
if( pos < 64 ) return;
|
||||
if( pos < LineLength ) return;
|
||||
|
||||
caretPos = pos - 64;
|
||||
caretPos = pos - LineLength;
|
||||
CalculateCaretData();
|
||||
return;
|
||||
}
|
||||
@ -185,8 +185,8 @@ namespace ClassicalSharp {
|
||||
|
||||
void DownKey( bool controlDown ) {
|
||||
if( controlDown ) {
|
||||
if( caretPos == -1 || caretPos >= (lines - 1) * 64 ) return;
|
||||
caretPos += 64;
|
||||
if( caretPos == -1 || caretPos >= (lines - 1) * LineLength ) return;
|
||||
caretPos += LineLength;
|
||||
CalculateCaretData();
|
||||
return;
|
||||
}
|
||||
@ -290,7 +290,7 @@ namespace ClassicalSharp {
|
||||
CalculateCaretData(); return;
|
||||
}
|
||||
}
|
||||
offset += partLens[y];
|
||||
offset += line.Length;
|
||||
}
|
||||
caretPos = -1;
|
||||
CalculateCaretData();
|
||||
|
@ -42,7 +42,7 @@ namespace ClassicalSharp {
|
||||
graphicsApi.Texturing = false;
|
||||
int y = Y, x = X;
|
||||
for( int i = 0; i < sizes.Length; i++ ) {
|
||||
bool caretAtEnd = caretTex.Y1 == y && (indexX == 64 || caretPos == -1);
|
||||
bool caretAtEnd = caretTex.Y1 == y && (indexX == LineLength || caretPos == -1);
|
||||
int offset = caretAtEnd ? defaultWidth : 0;
|
||||
graphicsApi.Draw2DQuad( x + 5, y, sizes[i].Width + offset, sizes[i].Height, backColour );
|
||||
y += sizes[i].Height;
|
||||
@ -64,9 +64,11 @@ namespace ClassicalSharp {
|
||||
int indexX, indexY;
|
||||
bool shownWarning;
|
||||
|
||||
int LineLength { get { return game.Network.ServerSupportsPartialMessages ? 64 : 62; } }
|
||||
|
||||
public override void Init() {
|
||||
X = 5;
|
||||
chatInputText.WordWrap( game.Drawer2D, ref parts, ref partLens, 64 );
|
||||
chatInputText.WordWrap( game.Drawer2D, ref parts, ref partLens, LineLength );
|
||||
|
||||
maxWidth = 0;
|
||||
DrawTextArgs args = new DrawTextArgs( null, font, true );
|
||||
@ -77,10 +79,10 @@ namespace ClassicalSharp {
|
||||
}
|
||||
|
||||
bool supports = game.Network.ServerSupportsPartialMessages;
|
||||
if( chatInputText.Length > 64 && !shownWarning && !supports ) {
|
||||
if( chatInputText.Length > LineLength && !shownWarning && !supports ) {
|
||||
game.Chat.Add( "&eNote: Each line will be sent as a separate packet.", MessageType.ClientStatus6 );
|
||||
shownWarning = true;
|
||||
} else if( chatInputText.Length <= 64 && shownWarning ) {
|
||||
} else if( chatInputText.Length <= LineLength && shownWarning ) {
|
||||
game.Chat.Add( null, MessageType.ClientStatus6 );
|
||||
shownWarning = false;
|
||||
}
|
||||
@ -89,14 +91,14 @@ namespace ClassicalSharp {
|
||||
altText.texture.Y1 = game.Height - (YOffset + Height + altText.texture.Height);
|
||||
altText.Y = altText.texture.Y1;
|
||||
CalculateCaretData();
|
||||
}
|
||||
}
|
||||
|
||||
void CalculateCaretData() {
|
||||
if( caretPos >= chatInputText.Length ) caretPos = -1;
|
||||
chatInputText.MakeCoords( caretPos, partLens, out indexX, out indexY );
|
||||
DrawTextArgs args = new DrawTextArgs( null, font, true );
|
||||
|
||||
if( indexX == 64 ) {
|
||||
if( indexX == LineLength ) {
|
||||
caretTex.X1 = 10 + sizes[indexY].Width;
|
||||
caretCol = FastColour.Yellow;
|
||||
} else {
|
||||
@ -111,7 +113,7 @@ namespace ClassicalSharp {
|
||||
caretCol = FastColour.Scale( FastColour.White, 0.8f );
|
||||
}
|
||||
caretTex.Y1 = sizes[0].Height * indexY + Y;
|
||||
CalculateCaretCol();
|
||||
CalcCaretColour();
|
||||
}
|
||||
|
||||
void DrawString() {
|
||||
@ -130,6 +132,9 @@ namespace ClassicalSharp {
|
||||
for( int i = 0; i < parts.Length; i++ ) {
|
||||
if( parts[i] == null ) break;
|
||||
args.Text = parts[i];
|
||||
char lastCol = GetLastColour( 0, i );
|
||||
if( !IDrawer2D.IsWhiteColour( lastCol ) )
|
||||
args.Text = "&" + lastCol + args.Text;
|
||||
|
||||
drawer.DrawChatText( ref args, 0, realHeight );
|
||||
realHeight += sizes[i].Height;
|
||||
@ -143,20 +148,23 @@ namespace ClassicalSharp {
|
||||
Width = size.Width;
|
||||
}
|
||||
|
||||
void CalculateCaretCol() {
|
||||
void CalcCaretColour() {
|
||||
IDrawer2D drawer = game.Drawer2D;
|
||||
char code = GetLastColour( indexX, indexY );
|
||||
if( code != '\0' )
|
||||
caretCol = drawer.Colours[code];
|
||||
}
|
||||
|
||||
char GetLastColour( int indexX, int indexY ) {
|
||||
int x = indexX;
|
||||
IDrawer2D drawer = game.Drawer2D;
|
||||
for( int y = indexY; y >= 0; y-- ) {
|
||||
string part = parts[y];
|
||||
if( x == partLens[y] ) x = partLens[y] - 1;
|
||||
int start = part.LastIndexOf( '&', x, x + 1 );
|
||||
bool validIndex = start >= 0 && start < partLens[y] - 1;
|
||||
|
||||
if( validIndex && drawer.ValidColour( part[start + 1] ) ) {
|
||||
caretCol = drawer.Colours[part[start + 1]]; return;
|
||||
}
|
||||
if( y > 0 ) x = partLens[y - 1] - 1;
|
||||
char code = drawer.LastColour( part, x );
|
||||
if( code != '\0' ) return code;
|
||||
if( y > 0 ) x = parts[y - 1].Length;
|
||||
}
|
||||
return '\0';
|
||||
}
|
||||
|
||||
public override void Dispose() {
|
||||
@ -197,26 +205,40 @@ namespace ClassicalSharp {
|
||||
string allText = chatInputText.GetString();
|
||||
game.Chat.InputLog.Add( allText );
|
||||
|
||||
if( game.Network.ServerSupportsPartialMessages ) {
|
||||
// don't automatically word wrap the message.
|
||||
while( allText.Length > 64 ) {
|
||||
game.Chat.Send( allText.Substring( 0, 64 ), true );
|
||||
allText = allText.Substring( 64 );
|
||||
}
|
||||
game.Chat.Send( allText, false );
|
||||
return;
|
||||
if( game.Network.ServerSupportsPartialMessages )
|
||||
SendWithPartial( allText );
|
||||
else
|
||||
SendNormal();
|
||||
}
|
||||
|
||||
void SendWithPartial( string allText ) {
|
||||
// don't automatically word wrap the message.
|
||||
while( allText.Length > 64 ) {
|
||||
game.Chat.Send( allText.Substring( 0, 64 ), true );
|
||||
allText = allText.Substring( 64 );
|
||||
}
|
||||
|
||||
game.Chat.Send( allText, false );
|
||||
}
|
||||
|
||||
void SendNormal() {
|
||||
int packetsCount = 0;
|
||||
for( int i = 0; i < parts.Length; i++ ) {
|
||||
if( parts[i] == null ) break;
|
||||
packetsCount++;
|
||||
}
|
||||
|
||||
// split up into both partial and final packet.
|
||||
for( int i = 0; i < packetsCount - 1; i++ ) {
|
||||
game.Chat.Send( parts[i], true );
|
||||
}
|
||||
game.Chat.Send( parts[packetsCount - 1], false );
|
||||
for( int i = 0; i < packetsCount - 1; i++ )
|
||||
SendNormalText( i, true );
|
||||
SendNormalText( packetsCount - 1, false );
|
||||
}
|
||||
|
||||
void SendNormalText( int i, bool partial ) {
|
||||
string text = parts[i];
|
||||
char lastCol = GetLastColour( 0, i );
|
||||
if( !IDrawer2D.IsWhiteColour( lastCol ) )
|
||||
text = "&" + lastCol + text;
|
||||
game.Chat.Send( text, partial );
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
|
@ -4,7 +4,7 @@
|
||||
<ProjectGuid>{BEB1C785-5CAD-48FF-A886-876BF0A318D4}</ProjectGuid>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<OutputType>Exe</OutputType>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>ClassicalSharp</RootNamespace>
|
||||
<AssemblyName>ClassicalSharp</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
|
@ -137,7 +137,6 @@ namespace ClassicalSharp {
|
||||
lastOpcode = (PacketId)opcode;
|
||||
Action handler = handlers[opcode];
|
||||
lastPacket = DateTime.UtcNow;
|
||||
Console.WriteLine( "IN " + lastOpcode );
|
||||
|
||||
if( handler == null )
|
||||
throw new NotImplementedException( "Unsupported packet:" + (PacketId)opcode );
|
||||
|
@ -37,9 +37,20 @@ namespace ClassicalSharp.Singleplayer {
|
||||
GenMap( 128, 64, 128, seed, new NotchyGenerator() );
|
||||
}
|
||||
|
||||
char lastCol = '\0';
|
||||
public override void SendChat( string text, bool partial ) {
|
||||
if( String.IsNullOrEmpty( text ) ) return;
|
||||
if( !String.IsNullOrEmpty( text ) )
|
||||
AddChat( text );
|
||||
if( !partial ) lastCol = '\0';
|
||||
}
|
||||
|
||||
void AddChat( string text ) {
|
||||
text = text.TrimEnd().Replace( '%', '&' );
|
||||
if( !IDrawer2D.IsWhiteColour( lastCol ) )
|
||||
text = "&" + lastCol + text;
|
||||
|
||||
char col = game.Drawer2D.LastColour( text, text.Length );
|
||||
if( col != '\0' ) lastCol = col;
|
||||
game.Chat.Add( text, MessageType.Normal );
|
||||
}
|
||||
|
||||
|
@ -68,9 +68,8 @@ namespace ClassicalSharp {
|
||||
value[i] = '&';
|
||||
}
|
||||
|
||||
for( int i = 0; i < Math.Max( 1, linesCount ); i++ ) {
|
||||
for( int i = 0; i < Math.Max( 1, linesCount ); i++ )
|
||||
lines[i] = new String( value, i * lineSize, lineLens[i] );
|
||||
}
|
||||
}
|
||||
|
||||
int WrapLine( int index, int lineSize ) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user