diff --git a/ClassicalSharp/2D/Drawing/IDrawer2D.cs b/ClassicalSharp/2D/Drawing/IDrawer2D.cs
index feda480df..91efe4cb4 100644
--- a/ClassicalSharp/2D/Drawing/IDrawer2D.cs
+++ b/ClassicalSharp/2D/Drawing/IDrawer2D.cs
@@ -64,7 +64,7 @@ namespace ClassicalSharp {
public abstract void DrawBitmappedText( ref DrawTextArgs args, int x, int y );
/// Draws a string using the specified arguments, using the specified font or
- /// the current bitmapped font depending on the 'useFont' argument, at the
+ /// the current bitmapped font depending on 'UseBitmappedChat', at the
/// specified coordinates in the currently bound bitmap.
public void DrawChatText( ref DrawTextArgs args, int windowX, int windowY ) {
if( !UseBitmappedChat )
@@ -81,7 +81,7 @@ namespace ClassicalSharp {
public abstract Size MeasureBitmappedSize( ref DrawTextArgs args );
/// Returns the size of a bitmap needed to contain the specified text with the given arguments,
- /// when drawn with the specified font or the current bitmapped font depending on the 'useFont' argument.
+ /// when drawn with the specified font or the current bitmapped font depending on 'UseBitmappedChat'.
public Size MeasureChatSize( ref DrawTextArgs args ) {
return !UseBitmappedChat ? MeasureSize( ref args ) :
MeasureBitmappedSize( ref args );
@@ -94,24 +94,28 @@ namespace ClassicalSharp {
/// Draws the specified string from the arguments into a new bitmap,
/// then creates a 2D texture with origin at the specified window coordinates.
public Texture MakeTextTexture( ref DrawTextArgs args, int windowX, int windowY ) {
- Size size = MeasureSize( ref args );
- if( parts.Count == 0 )
- return new Texture( -1, windowX, windowY, 0, 0, 1, 1 );
- return MakeTextureImpl( size, ref args, windowX, windowY, false );
+ return MakeTextureImpl( ref args, windowX, windowY, false );
}
/// Draws the specified string from the arguments into a new bitmap,
/// using the current bitmap font, then creates a 2D texture with origin at the
/// specified window coordinates.
public Texture MakeBitmappedTextTexture( ref DrawTextArgs args, int windowX, int windowY ) {
- Size size = MeasureBitmappedSize( ref args );
- if( parts.Count == 0 )
- return new Texture( -1, windowX, windowY, 0, 0, 1, 1 );
- return MakeTextureImpl( size, ref args, windowX, windowY, true );
+ return MakeTextureImpl( ref args, windowX, windowY, true );
}
- Texture MakeTextureImpl( Size size, ref DrawTextArgs args,
- int windowX, int windowY, bool bitmapped ) {
+ /// Draws the specified string from the arguments into a new bitmap,
+ /// using the specified font or the current bitmapped font depending on 'UseBitmappedChat',
+ /// then creates a 2D texture with origin at the specified window coordinates.
+ public Texture MakeChatTextTexture( ref DrawTextArgs args, int windowX, int windowY ) {
+ return MakeTextureImpl( ref args, windowX, windowY, UseBitmappedChat );
+ }
+
+ Texture MakeTextureImpl( ref DrawTextArgs args, int windowX, int windowY, bool bitmapped ) {
+ Size size = bitmapped ? MeasureBitmappedSize( ref args ) : MeasureSize( ref args );
+ if( parts.Count == 0 )
+ return new Texture( -1, windowX, windowY, 0, 0, 1, 1 );
+
using( Bitmap bmp = CreatePow2Bitmap( size ) ) {
SetBitmap( bmp );
args.SkipPartsCheck = true;
diff --git a/ClassicalSharp/2D/Screens/ChatScreen.cs b/ClassicalSharp/2D/Screens/ChatScreen.cs
index ddee33af0..30762755e 100644
--- a/ClassicalSharp/2D/Screens/ChatScreen.cs
+++ b/ClassicalSharp/2D/Screens/ChatScreen.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Drawing;
using OpenTK.Input;
@@ -76,25 +77,27 @@ namespace ClassicalSharp {
}
}
- Font chatFont, chatInputFont, announcementFont;
+ Font chatFont, chatInputFont, chatUnderlineFont, announcementFont;
public override void Init() {
- chatFont = new Font( "Arial", game.Chat.FontSize );
- chatInputFont = new Font( "Arial", game.Chat.FontSize, FontStyle.Bold );
+ int fontSize = game.Chat.FontSize;//(int)(14 * Utils.GuiScale( game.Width, game.Height ));
+ chatFont = new Font( "Arial", fontSize );
+ chatInputFont = new Font( "Arial", fontSize, FontStyle.Bold );
+ chatUnderlineFont = new Font( "Arial", fontSize, FontStyle.Underline );
announcementFont = new Font( "Arial", 14 );
blockSize = (int)(40 * Utils.GuiScale( game.Width, game.Height ));
textInput = new TextInputWidget( game, chatFont, chatInputFont );
textInput.YOffset = blockSize + 5;
- status = new TextGroupWidget( game, 3, chatFont );
+ status = new TextGroupWidget( game, 3, chatFont, chatUnderlineFont );
status.VerticalAnchor = Anchor.LeftOrTop;
status.HorizontalAnchor = Anchor.BottomOrRight;
status.Init();
- bottomRight = new TextGroupWidget( game, 3, chatFont );
+ bottomRight = new TextGroupWidget( game, 3, chatFont, chatUnderlineFont );
bottomRight.VerticalAnchor = Anchor.BottomOrRight;
bottomRight.HorizontalAnchor = Anchor.BottomOrRight;
bottomRight.YOffset = blockSize * 3 / 2;
bottomRight.Init();
- normalChat = new TextGroupWidget( game, chatLines, chatFont );
+ normalChat = new TextGroupWidget( game, chatLines, chatFont, chatUnderlineFont );
normalChat.XOffset = 10;
normalChat.YOffset = blockSize * 2 + 15;
normalChat.HorizontalAnchor = Anchor.LeftOrTop;
@@ -152,6 +155,7 @@ namespace ClassicalSharp {
}
chatFont.Dispose();
chatInputFont.Dispose();
+ chatUnderlineFont.Dispose();
announcementFont.Dispose();
normalChat.Dispose();
@@ -280,21 +284,41 @@ namespace ClassicalSharp {
return true;
}
- public override bool HandlesMouseClick( int mouseX, int mouseY, MouseButton button ) {
- if( !HandlesAllInput ) return false;
- if( normalChat.Bounds.Contains( mouseX, mouseY ) ) {
- int height = normalChat.GetUsedHeight();
- int y = normalChat.Y + normalChat.Height - height;
- if( new Rectangle( normalChat.X, y, normalChat.Width, height ).Contains( mouseX, mouseY ) ) {
- string text = normalChat.GetSelected( mouseX, mouseY );
- if( text != null ) {
- textInput.AppendText(text);
- return true;
- }
- }
- return false;
- }
- return textInput.HandlesMouseClick( mouseX, mouseY, button );
+ public override bool HandlesMouseClick( int mouseX, int mouseY, MouseButton button ) {
+ if( !HandlesAllInput ) return false;
+ if( normalChat.Bounds.Contains( mouseX, mouseY ) ) {
+ int height = normalChat.GetUsedHeight();
+ int y = normalChat.Y + normalChat.Height - height;
+ if( new Rectangle( normalChat.X, y, normalChat.Width, height ).Contains( mouseX, mouseY ) ) {
+ string text = normalChat.GetSelected( mouseX, mouseY );
+ if( text != null ) {
+ if( Utils.IsUrlPrefix( text ) ) {
+ game.ShowWarning( new WarningScreen(
+ game, text, OpenUrl, AppendUrl,
+ "Are you sure you want to go to this url?",
+ text,
+ "Be careful - urls from strangers may link to websites that",
+ " may have viruses, or things you may not want to open/see."
+ ) );
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+ return textInput.HandlesMouseClick( mouseX, mouseY, button );
+ }
+
+ void OpenUrl( object metadata ) {
+ try {
+ Process.Start( (string)metadata );
+ } catch( Exception ex ) {
+ ErrorHandler.LogError( "ChatScreen.OpenUrl", ex );
+ }
+ }
+
+ void AppendUrl( object metadata ) {
+ textInput.AppendText( (string)metadata );
}
void ResetIndex() {
diff --git a/ClassicalSharp/2D/Screens/HudScreen.cs b/ClassicalSharp/2D/Screens/HudScreen.cs
index 3e3ba6d77..488405399 100644
--- a/ClassicalSharp/2D/Screens/HudScreen.cs
+++ b/ClassicalSharp/2D/Screens/HudScreen.cs
@@ -72,20 +72,17 @@ namespace ClassicalSharp {
}
public void LoseFocus() {
- if( playerList != null ) {
+ if( playerList != null )
playerList.Dispose();
- }
if( !game.CursorVisible )
game.CursorVisible = true;
}
public override void OnResize( int oldWidth, int oldHeight, int width, int height ) {
- chat.OnResize( oldWidth, oldHeight, width, height );
- hotbar.OnResize( oldWidth, oldHeight, width, height );
- if( playerList != null ) {
- int deltaX = CalcDelta( width, oldWidth, Anchor.Centre );
- playerList.MoveTo( playerList.X + deltaX, height / 4 );
- }
+ PlayerListWidget widget = playerList;
+ game.RefreshHud();
+ if( widget != null )
+ CreatePlayerListWidget();
}
public override void Init() {
@@ -113,22 +110,26 @@ namespace ClassicalSharp {
public override bool HandlesKeyDown( Key key ) {
if( key == game.Mapping( KeyBinding.PlayerList ) ) {
- if( playerList == null ) {
- if( game.Network.UsingExtPlayerList ) {
- playerList = new ExtPlayerListWidget( game, playerFont );
- } else {
- playerList = new NormalPlayerListWidget( game, playerFont );
- }
- playerList.Init();
- playerList.MoveTo( playerList.X, game.Height / 4 );
- }
- }
- if( chat.HandlesKeyDown( key ) ) {
+ if( playerList == null )
+ CreatePlayerListWidget();
return true;
}
+
+ if( chat.HandlesKeyDown( key ) )
+ return true;
return hotbar.HandlesKeyDown( key );
}
+ void CreatePlayerListWidget() {
+ if( game.Network.UsingExtPlayerList ) {
+ playerList = new ExtPlayerListWidget( game, playerFont );
+ } else {
+ playerList = new NormalPlayerListWidget( game, playerFont );
+ }
+ playerList.Init();
+ playerList.MoveTo( playerList.X, game.Height / 4 );
+ }
+
public override bool HandlesKeyUp( Key key ) {
if( key == game.Mapping( KeyBinding.PlayerList ) ) {
if( playerList != null ) {
diff --git a/ClassicalSharp/2D/Widgets/BlockHotbarWidget.cs b/ClassicalSharp/2D/Widgets/BlockHotbarWidget.cs
index 93538e1ef..c93ff8723 100644
--- a/ClassicalSharp/2D/Widgets/BlockHotbarWidget.cs
+++ b/ClassicalSharp/2D/Widgets/BlockHotbarWidget.cs
@@ -40,21 +40,21 @@ namespace ClassicalSharp {
MakeBackgroundTexture( width );
MakeSelectionTexture();
}
-
+
public override void Render( double delta ) {
graphicsApi.Texturing = true;
background.Render( graphicsApi );
- graphicsApi.BindTexture( game.TerrainAtlas.TexId );
+ graphicsApi.BindTexture( game.TerrainAtlas.TexId );
graphicsApi.SetBatchFormat( VertexFormat.Pos3fTex2fCol4b );
for( int i = 0; i < hotbarCount; i++ ) {
int x = X + i * blockSize;
- IsometricBlockDrawer.Draw( game, (byte)game.Inventory.Hotbar[i], blockSize / 2 - borderSize - 2,
+ IsometricBlockDrawer.Draw( game, (byte)game.Inventory.Hotbar[i], blockSize / 2 - borderSize - 2,
x + 1 + blockSize / 2, game.Height - blockSize / 2 );
if( i == game.Inventory.HeldBlockIndex )
selectedBlock.X1 = x;
- }
-
+ }
+
selectedBlock.Render( graphicsApi );
graphicsApi.Texturing = false;
}
@@ -73,27 +73,27 @@ namespace ClassicalSharp {
void MakeBackgroundTexture( int width ) {
Size size = new Size( width, blockSize );
- using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) {
- using( IDrawer2D drawer = game.Drawer2D ) {
- drawer.SetBitmap( bmp );
- drawer.Clear( backCol );
- for( int xx = 0; xx < hotbarCount; xx++ ) {
- drawer.DrawRectBounds( outlineCol, borderSize, xx * blockSize,
- 0, blockSize, blockSize );
- }
- background = drawer.Make2DTexture( bmp, size, X, Y );
+ using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) )
+ using( IDrawer2D drawer = game.Drawer2D )
+ {
+ drawer.SetBitmap( bmp );
+ drawer.Clear( backCol );
+ for( int xx = 0; xx < hotbarCount; xx++ ) {
+ drawer.DrawRectBounds( outlineCol, borderSize, xx * blockSize,
+ 0, blockSize, blockSize );
}
+ background = drawer.Make2DTexture( bmp, size, X, Y );
}
}
void MakeSelectionTexture() {
Size size = new Size( blockSize, blockSize );
- using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) {
- using( IDrawer2D drawer = game.Drawer2D ) {
- drawer.SetBitmap( bmp );
- drawer.DrawRectBounds( selCol, borderSize, 0, 0, blockSize, blockSize );
- selectedBlock = drawer.Make2DTexture( bmp, size, 0, Y );
- }
+ using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) )
+ using( IDrawer2D drawer = game.Drawer2D )
+ {
+ drawer.SetBitmap( bmp );
+ drawer.DrawRectBounds( selCol, borderSize, 0, 0, blockSize, blockSize );
+ selectedBlock = drawer.Make2DTexture( bmp, size, 0, Y );
}
}
}
diff --git a/ClassicalSharp/2D/Widgets/ButtonWidget.cs b/ClassicalSharp/2D/Widgets/ButtonWidget.cs
index b5c597317..8410a70c0 100644
--- a/ClassicalSharp/2D/Widgets/ButtonWidget.cs
+++ b/ClassicalSharp/2D/Widgets/ButtonWidget.cs
@@ -88,17 +88,17 @@ namespace ClassicalSharp {
const int borderSize = 3; // 1 px for base border, 2 px for shadow, 1 px for offset text
size.Width += borderSize; size.Height += borderSize;
- using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) {
- using( IDrawer2D drawer = game.Drawer2D ) {
- drawer.SetBitmap( bmp );
- drawer.DrawRoundedRect( shadowCol, 3, IDrawer2D.Offset, IDrawer2D.Offset,
- baseSize.Width, baseSize.Height );
- drawer.DrawRoundedRect( boxCol, 3, 0, 0, baseSize.Width, baseSize.Height );
-
- args.SkipPartsCheck = true;
- drawer.DrawText( ref args, 1 + xOffset / 2, 1 + yOffset / 2 );
- texture = drawer.Make2DTexture( bmp, size, 0, 0 );
- }
+ using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) )
+ using( IDrawer2D drawer = game.Drawer2D )
+ {
+ drawer.SetBitmap( bmp );
+ drawer.DrawRoundedRect( shadowCol, 3, IDrawer2D.Offset, IDrawer2D.Offset,
+ baseSize.Width, baseSize.Height );
+ drawer.DrawRoundedRect( boxCol, 3, 0, 0, baseSize.Width, baseSize.Height );
+
+ args.SkipPartsCheck = true;
+ drawer.DrawText( ref args, 1 + xOffset / 2, 1 + yOffset / 2 );
+ texture = drawer.Make2DTexture( bmp, size, 0, 0 );
}
}
}
diff --git a/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.cs b/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.cs
index 6f011fbe9..2467b36e3 100644
--- a/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.cs
+++ b/ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.cs
@@ -39,7 +39,7 @@ namespace ClassicalSharp {
public void Redraw() {
Make( elements[selectedIndex], font );
Width = texture.Width;
- Height = texture.Height;
+ Height = texture.Height;
}
unsafe void Make( Element e, Font font ) {
@@ -49,16 +49,16 @@ namespace ClassicalSharp {
int titleWidth = MeasureTitles( font ), titleHeight = elements[0].TitleSize.Height;
Size size = new Size( Math.Max( bodySize.Width, titleWidth ), bodySize.Height + titleHeight );
- using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) {
- using( IDrawer2D drawer = game.Drawer2D ) {
- drawer.SetBitmap( bmp );
- DrawTitles( drawer, font );
- drawer.Clear( new FastColour( 30, 30, 30, 200 ), 0, titleHeight,
- size.Width, bodySize.Height );
-
- DrawContent( drawer, font, e, titleHeight );
- texture = drawer.Make2DTexture( bmp, size, X, Y );
- }
+ using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) )
+ using( IDrawer2D drawer = game.Drawer2D )
+ {
+ drawer.SetBitmap( bmp );
+ DrawTitles( drawer, font );
+ drawer.Clear( new FastColour( 30, 30, 30, 200 ), 0, titleHeight,
+ size.Width, bodySize.Height );
+
+ DrawContent( drawer, font, e, titleHeight );
+ texture = drawer.Make2DTexture( bmp, size, X, Y );
}
}
@@ -96,8 +96,8 @@ namespace ClassicalSharp {
if( index < e.Contents.Length ) {
if( selectedIndex == 0 ) {
// TODO: need to insert characters that don't affect caret index, adjust caret colour
- //parent.AppendChar( e.Contents[index * e.CharsPerItem] );
- //parent.AppendChar( e.Contents[index * e.CharsPerItem + 1] );
+ parent.AppendChar( e.Contents[index * e.CharsPerItem] );
+ parent.AppendChar( e.Contents[index * e.CharsPerItem + 1] );
} else {
parent.AppendChar( e.Contents[index] );
}
diff --git a/ClassicalSharp/2D/Widgets/Chat/ChatTextWidget.cs b/ClassicalSharp/2D/Widgets/Chat/ChatTextWidget.cs
index a32a2568d..0dc7c9bf3 100644
--- a/ClassicalSharp/2D/Widgets/Chat/ChatTextWidget.cs
+++ b/ClassicalSharp/2D/Widgets/Chat/ChatTextWidget.cs
@@ -32,9 +32,7 @@ namespace ClassicalSharp {
Height = defaultHeight;
} else {
DrawTextArgs args = new DrawTextArgs( text, font, true );
- texture = game.Drawer2D.UseBitmappedChat ?
- game.Drawer2D.MakeBitmappedTextTexture( ref args, 0, 0 ) :
- game.Drawer2D.MakeTextTexture( ref args, 0, 0 );
+ texture = game.Drawer2D.MakeChatTextTexture( ref args, 0, 0 );
X = texture.X1 = CalcOffset( game.Width, texture.Width, XOffset, HorizontalAnchor );
Y = texture.Y1 = CalcOffset( game.Height, texture.Height, YOffset, VerticalAnchor );
diff --git a/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.Formatter.cs b/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.Formatter.cs
new file mode 100644
index 000000000..af1038d50
--- /dev/null
+++ b/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.Formatter.cs
@@ -0,0 +1,115 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+
+namespace ClassicalSharp {
+
+ public sealed partial class TextGroupWidget : Widget {
+
+ public void SetText( int index, string text ) {
+ graphicsApi.DeleteTexture( ref Textures[index] );
+ DrawTextArgs args = new DrawTextArgs( text, font, true );
+ Font underlineFont = new Font( font, FontStyle.Underline );
+ urlBounds[index] = null;
+
+ if( !String.IsNullOrEmpty( text ) ) {
+ Texture tex = NextToken( text, 0 ) == -1 ? DrawSimple( ref args ) :
+ DrawAdvanced( ref args, index, text );
+ tex.X1 = CalcOffset( game.Width, tex.Width, XOffset, HorizontalAnchor );
+ tex.Y1 = CalcY( index, tex.Height );
+ Textures[index] = tex;
+ lines[index] = text;
+ } else {
+ Textures[index] = new Texture( -1, 0, 0, 0, defaultHeight, 0, 0 );
+ lines[index] = null;
+ }
+ UpdateDimensions();
+ }
+
+ Texture DrawSimple( ref DrawTextArgs args ) {
+ return game.Drawer2D.MakeChatTextTexture( ref args, 0, 0 );
+ }
+
+ Texture DrawAdvanced( ref DrawTextArgs args, int index, string text ) {
+ string[] items = Split( index, text );
+ Size total = Size.Empty;
+ Size[] partSizes = new Size[items.Length];
+
+ for( int i = 0; i < items.Length; i++ ) {
+ args.Text = items[i];
+ args.Font = (i & 1) == 0 ? font : underlineFont;
+ partSizes[i] = game.Drawer2D.MeasureChatSize( ref args );
+ total.Height = Math.Max( partSizes[i].Height, total.Height );
+ total.Width += partSizes[i].Width;
+ }
+
+ using( IDrawer2D drawer = game.Drawer2D )
+ using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( total ) )
+ {
+ drawer.SetBitmap( bmp );
+ int x = 0;
+
+ for( int i = 0; i < items.Length; i++ ) {
+ args.Text = items[i];
+ args.Font = (i & 1) == 0 ? font : underlineFont;
+ Size size = partSizes[i];
+
+ drawer.DrawChatText( ref args, x, 0 );
+ urlBounds[index][i].X = x;
+ urlBounds[index][i].Width = size.Width;
+ x += size.Width;
+ }
+ return drawer.Make2DTexture( bmp, total, 0, 0 );
+ }
+ }
+
+ string[] Split( int index, string line ) {
+ int start = 0, lastEnd = 0, count = 0;
+ string[] items = new string[GetTokensCount( line )];
+ Rectangle[] parts = new Rectangle[items.Length];
+
+ while( (start = NextToken( line, start )) >= 0 ) {
+ int nextEnd = line.IndexOf( ' ', start );
+ if( nextEnd == -1 )
+ nextEnd = line.Length;
+
+ parts[count].Y = lastEnd << 12 | (start - lastEnd);
+ items[count++] = line.Substring( lastEnd, start - lastEnd ); // word bit
+ parts[count].Y = start << 12 | (nextEnd - start);
+ items[count++] = line.Substring( start, nextEnd - start ); // url bit
+ start = nextEnd;
+ lastEnd = nextEnd;
+ }
+
+ if( lastEnd < line.Length ) {
+ parts[count].Y = lastEnd << 12 | (line.Length - lastEnd);
+ items[count++] = line.Substring( lastEnd, line.Length - lastEnd );
+ }
+ urlBounds[index] = parts;
+ return items;
+ }
+
+ int NextToken( string line, int start ) {
+ int nextHttp = line.IndexOf( "http://", start );
+ int nextHttps = line.IndexOf( "https://", start );
+ return nextHttp == -1 ? nextHttps : nextHttp;
+ }
+
+ int GetTokensCount( string line ) {
+ int start = 0, lastEnd = 0, count = 0;
+ while( (start = NextToken( line, start )) >= 0 ) {
+ int nextEnd = line.IndexOf( ' ', start );
+ if( nextEnd == -1 )
+ nextEnd = line.Length;
+
+ start = nextEnd;
+ lastEnd = nextEnd;
+ count += 2;
+ }
+
+ if( lastEnd < line.Length )
+ count++;
+ return count;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.cs b/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.cs
index 3e8d2ebe9..c15cb26ff 100644
--- a/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.cs
+++ b/ClassicalSharp/2D/Widgets/Chat/TextGroupWidget.cs
@@ -4,22 +4,26 @@ using System.Drawing;
namespace ClassicalSharp {
- public sealed class TextGroupWidget : Widget {
+ public sealed partial class TextGroupWidget : Widget {
- public TextGroupWidget( Game game, int elementsCount, Font font ) : base( game ) {
+ public TextGroupWidget( Game game, int elementsCount,
+ Font font, Font underlineFont ) : base( game ) {
ElementsCount = elementsCount;
this.font = font;
+ this.underlineFont = underlineFont;
}
public Texture[] Textures;
string[] lines;
+ Rectangle[][] urlBounds;
int ElementsCount, defaultHeight;
public int XOffset = 0, YOffset = 0;
- readonly Font font;
+ readonly Font font, underlineFont;
public override void Init() {
Textures = new Texture[ElementsCount];
lines = new string[ElementsCount];
+ urlBounds = new Rectangle[ElementsCount][];
DrawTextArgs args = new DrawTextArgs( "I", font, true );
defaultHeight = game.Drawer2D.MeasureChatSize( ref args ).Height;
@@ -28,26 +32,6 @@ namespace ClassicalSharp {
UpdateDimensions();
}
- public void SetText( int index, string text ) {
- graphicsApi.DeleteTexture( ref Textures[index] );
- DrawTextArgs args = new DrawTextArgs( text, font, true );
-
- if( !String.IsNullOrEmpty( text ) ) {
- Texture tex = game.Drawer2D.UseBitmappedChat ?
- game.Drawer2D.MakeBitmappedTextTexture( ref args, 0, 0 ) :
- game.Drawer2D.MakeTextTexture( ref args, 0, 0 );
-
- tex.X1 = CalcOffset( game.Width, tex.Width, XOffset, HorizontalAnchor );
- tex.Y1 = CalcY( index, tex.Height );
- Textures[index] = tex;
- lines[index] = text;
- } else {
- Textures[index] = new Texture( -1, 0, 0, 0, defaultHeight, 0, 0 );
- lines[index] = null;
- }
- UpdateDimensions();
- }
-
public void PushUpAndReplaceLast( string text ) {
int y = Y;
graphicsApi.DeleteTexture( ref Textures[0] );
@@ -81,7 +65,7 @@ namespace ClassicalSharp {
y -= newHeight;
for( int i = 0; i < index; i++ ) {
Textures[i].Y1 -= deltaY;
- }
+ }
}
return y;
}
@@ -96,11 +80,11 @@ namespace ClassicalSharp {
}
void UpdateDimensions() {
- Width = 0;
+ Width = 0;
Height = 0;
for( int i = 0; i < Textures.Length; i++ ) {
Width = Math.Max( Width, Textures[i].Width );
- Height += Textures[i].Height;
+ Height += Textures[i].Height;
}
X = CalcOffset( game.Width, Width, XOffset, HorizontalAnchor );
@@ -131,9 +115,27 @@ namespace ClassicalSharp {
public string GetSelected( int mouseX, int mouseY ) {
for( int i = 0; i < Textures.Length; i++ ) {
- if( Textures[i].IsValid &&
- Textures[i].Bounds.Contains( mouseX, mouseY ) )
- return lines[i];
+ Texture tex = Textures[i];
+ if( tex.IsValid && tex.Bounds.Contains( mouseX, mouseY ) ) {
+ return GetUrl( i, mouseX ) ?? lines[i];
+ }
+ }
+ return null;
+ }
+
+ string GetUrl( int index, int mouseX ) {
+ Rectangle[] partBounds = urlBounds[index];
+ if( partBounds == null )
+ return null;
+ Texture tex = Textures[index];
+ mouseX -= tex.X1;
+ string text = lines[index];
+
+ for( int i = 1; i < partBounds.Length; i += 2 ) {
+ if( mouseX >= partBounds[i].Left && mouseX < partBounds[i].Right ) {
+ int packed = partBounds[i].Y;
+ return text.Substring( packed >> 12, packed & 0xFFF );
+ }
}
return null;
}
diff --git a/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.cs b/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.cs
index 44f14ed53..c3c7557d6 100644
--- a/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.cs
+++ b/ClassicalSharp/2D/Widgets/Chat/TextInputWidget.cs
@@ -15,21 +15,24 @@ namespace ClassicalSharp {
VerticalAnchor = Anchor.BottomOrRight;
typingLogPos = game.Chat.InputLog.Count; // Index of newest entry + 1.
+ chatInputText = new WrappableStringBuffer( len );
+ DrawTextArgs args = new DrawTextArgs( "A", boldFont, true );
+ Size defSize = game.Drawer2D.MeasureChatSize( ref args );
+ defaultWidth = defSize.Width; defaultHeight = defSize.Height;
+ Width = defaultWidth; Height = defaultHeight;
+
this.font = font;
this.boldFont = boldFont;
- chatInputText = new WrappableStringBuffer( len );
- DrawTextArgs args = new DrawTextArgs( "_", boldFont, false );
- defaultHeight = game.Drawer2D.MeasureChatSize( ref args ).Height;
- Height = defaultHeight;
altText = new AltTextInputWidget( game, font, boldFont, this );
altText.Init();
}
public int RealHeight { get { return Height + altText.Height; } }
- Texture chatInputTexture, caretTexture;
+ Texture inputTex, caretTex;
int caretPos = -1, typingLogPos = 0;
- public int YOffset, defaultHeight;
+ public int YOffset;
+ int defaultWidth, defaultHeight;
internal WrappableStringBuffer chatInputText;
readonly Font font, boldFont;
@@ -38,8 +41,19 @@ namespace ClassicalSharp {
FastColour caretCol;
static FastColour backColour = new FastColour( 60, 60, 60, 200 );
public override void Render( double delta ) {
- chatInputTexture.Render( graphicsApi );
- caretTexture.Render( graphicsApi, caretCol );
+ graphicsApi.Texturing = false;
+ int y = Y, x = X;
+ for( int i = 0; i < sizes.Length; i++ ) {
+ int offset = (caretTex.Y1 == y) ? defaultWidth : 0;
+ graphicsApi.Draw2DQuad( x + 5, y, sizes[i].Width + offset, sizes[i].Height, backColour );
+ y += sizes[i].Height;
+ }
+ if( sizes.Length == 0 || sizes[0] == Size.Empty )
+ graphicsApi.Draw2DQuad( x + 5, y, defaultWidth, defaultHeight, backColour );
+ graphicsApi.Texturing = true;
+
+ inputTex.Render( graphicsApi );
+ caretTex.Render( graphicsApi, caretCol );
if( altText.Active )
altText.Render( delta );
}
@@ -51,14 +65,12 @@ namespace ClassicalSharp {
public override void Init() {
X = 5;
- DrawTextArgs args = new DrawTextArgs( "_", boldFont, false );
- caretTexture = game.Drawer2D.UseBitmappedChat ?
- game.Drawer2D.MakeBitmappedTextTexture( ref args, 0, 0 ) :
- game.Drawer2D.MakeTextTexture( ref args, 0, 0 );
+ DrawTextArgs args = new DrawTextArgs( "_", boldFont, true );
+ caretTex = game.Drawer2D.MakeChatTextTexture( ref args, 0, 0 );
chatInputText.WordWrap( ref parts, ref partLens, 64 );
maxWidth = 0;
- args = new DrawTextArgs( null, font, false );
+ args = new DrawTextArgs( null, font, true );
for( int i = 0; i < lines; i++ ) {
args.Text = parts[i];
sizes[i] = game.Drawer2D.MeasureChatSize( ref args );
@@ -84,23 +96,23 @@ namespace ClassicalSharp {
if( indexX == -1 ) indexX = partLens[indexY];
if( indexX == 64 ) {
- caretTexture.X1 = 10 + sizes[indexY].Width;
- sizes[indexY].Width += caretTexture.Width;
+ caretTex.X1 = 10 + sizes[indexY].Width;
+ sizes[indexY].Width += caretTex.Width;
maxWidth = Math.Max( maxWidth, sizes[indexY].Width );
- caretTexture.Y1 = sizes[0].Height * indexY;
+ caretTex.Y1 = sizes[0].Height * indexY;
caretCol = nextCaretCol;
} else {
args.Text = parts[indexY].Substring( 0, indexX );
Size trimmedSize = game.Drawer2D.MeasureChatSize( ref args );
- caretTexture.X1 = 10 + trimmedSize.Width;
+ caretTex.X1 = 10 + trimmedSize.Width;
string line = parts[indexY];
args.Text = indexX < line.Length ? new String( line[indexX], 1 ) : " ";
Size charSize = game.Drawer2D.MeasureChatSize( ref args );
- caretTexture.Width = charSize.Width;
+ caretTex.Width = charSize.Width;
- caretTexture.Y1 = sizes[0].Height * indexY;
+ caretTex.Y1 = sizes[0].Height * indexY;
caretCol = normalCaretCol;
}
DrawString();
@@ -115,40 +127,39 @@ namespace ClassicalSharp {
Size size = new Size( maxWidth, totalHeight );
int realHeight = 0;
- using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) {
- using( IDrawer2D drawer = game.Drawer2D ) {
- drawer.SetBitmap( bmp );
- DrawTextArgs args = new DrawTextArgs( null, font, false );
+ using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) )
+ using( IDrawer2D drawer = game.Drawer2D )
+ {
+ drawer.SetBitmap( bmp );
+ DrawTextArgs args = new DrawTextArgs( null, font, true );
+
+ for( int i = 0; i < parts.Length; i++ ) {
+ if( parts[i] == null ) break;
+ args.Text = parts[i];
- for( int i = 0; i < parts.Length; i++ ) {
- if( parts[i] == null ) break;
- args.Text = parts[i];
-
- drawer.Clear( backColour, 0, realHeight, sizes[i].Width, sizes[i].Height );
- drawer.DrawChatText( ref args, 0, realHeight );
- realHeight += sizes[i].Height;
- }
- chatInputTexture = drawer.Make2DTexture( bmp, size, 10, 0 );
+ drawer.DrawChatText( ref args, 0, realHeight );
+ realHeight += sizes[i].Height;
}
+ inputTex = drawer.Make2DTexture( bmp, size, 10, 0 );
}
Height = realHeight == 0 ? defaultHeight : realHeight;
Y = game.Height - Height - YOffset;
- chatInputTexture.Y1 = Y;
- caretTexture.Y1 += Y;
+ inputTex.Y1 = Y;
+ caretTex.Y1 += Y;
Width = size.Width;
}
public override void Dispose() {
- graphicsApi.DeleteTexture( ref caretTexture );
- graphicsApi.DeleteTexture( ref chatInputTexture );
+ graphicsApi.DeleteTexture( ref caretTex );
+ graphicsApi.DeleteTexture( ref inputTex );
}
public override void MoveTo( int newX, int newY ) {
int diffX = newX - X, diffY = newY - Y;
X = newX; Y = newY;
- caretTexture.Y1 += diffY;
- chatInputTexture.Y1 += diffY;
+ caretTex.Y1 += diffY;
+ inputTex.Y1 += diffY;
altText.texture.Y1 = game.Height - (YOffset + Height + altText.texture.Height);
altText.Y = altText.texture.Y1;
diff --git a/ClassicalSharp/2D/Widgets/Menu/MenuInputWidget.cs b/ClassicalSharp/2D/Widgets/Menu/MenuInputWidget.cs
index 0b26c6d33..902dc401a 100644
--- a/ClassicalSharp/2D/Widgets/Menu/MenuInputWidget.cs
+++ b/ClassicalSharp/2D/Widgets/Menu/MenuInputWidget.cs
@@ -60,23 +60,23 @@ namespace ClassicalSharp {
Size size = new Size( Math.Max( textSize.Width, DesiredMaxWidth ),
Math.Max( textSize.Height, DesiredMaxHeight ) );
- using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) {
- using( IDrawer2D drawer = game.Drawer2D ) {
- drawer.SetBitmap( bmp );
- drawer.DrawRect( backColour, 0, 0, size.Width, size.Height );
- args.SkipPartsCheck = true;
- drawer.DrawText( ref args, 0, 0 );
-
- args.Text = Validator.Range;
- args.SkipPartsCheck = false;
- Size hintSize = drawer.MeasureSize( ref args );
-
- args.SkipPartsCheck = true;
- int hintX = size.Width - hintSize.Width;
- if( textSize.Width < hintX )
- drawer.DrawText( ref args, hintX, 0 );
- chatInputTexture = drawer.Make2DTexture( bmp, size, 0, 0 );
- }
+ using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) )
+ using( IDrawer2D drawer = game.Drawer2D )
+ {
+ drawer.SetBitmap( bmp );
+ drawer.DrawRect( backColour, 0, 0, size.Width, size.Height );
+ args.SkipPartsCheck = true;
+ drawer.DrawText( ref args, 0, 0 );
+
+ args.Text = Validator.Range;
+ args.SkipPartsCheck = false;
+ Size hintSize = drawer.MeasureSize( ref args );
+
+ args.SkipPartsCheck = true;
+ int hintX = size.Width - hintSize.Width;
+ if( textSize.Width < hintX )
+ drawer.DrawText( ref args, hintX, 0 );
+ chatInputTexture = drawer.Make2DTexture( bmp, size, 0, 0 );
}
X = CalcOffset( game.Width, size.Width, XOffset, HorizontalAnchor );
diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj
index c3055eb77..f795bf055 100644
--- a/ClassicalSharp/ClassicalSharp.csproj
+++ b/ClassicalSharp/ClassicalSharp.csproj
@@ -109,6 +109,7 @@
+
diff --git a/ClassicalSharp/Game/ChatLog.cs b/ClassicalSharp/Game/ChatLog.cs
index 00f2d8502..753103b7a 100644
--- a/ClassicalSharp/Game/ChatLog.cs
+++ b/ClassicalSharp/Game/ChatLog.cs
@@ -7,8 +7,8 @@ namespace ClassicalSharp {
public sealed class ChatLog : IDisposable {
- public ChatLine Status1, Status2, Status3, BottomRight1,
- BottomRight2, BottomRight3, Announcement;
+ public ChatLine Status1, Status2, Status3, BottomRight1 = "F",
+ BottomRight2 = "G", BottomRight3 = "H", Announcement;
Game game;
public ChatLog( Game game ) {