Make text input bar have a small background when empty, allowing entering colour codes directly into chat, add support for clicking on urls.

This commit is contained in:
UnknownShadow200 2015-11-14 22:02:45 +11:00
parent 97a38f3cf4
commit 7208d2e7dc
13 changed files with 341 additions and 185 deletions

View File

@ -64,7 +64,7 @@ namespace ClassicalSharp {
public abstract void DrawBitmappedText( ref DrawTextArgs args, int x, int y );
/// <summary> 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. </summary>
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 );
/// <summary> 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. </summary>
/// when drawn with the specified font or the current bitmapped font depending on 'UseBitmappedChat'. </summary>
public Size MeasureChatSize( ref DrawTextArgs args ) {
return !UseBitmappedChat ? MeasureSize( ref args ) :
MeasureBitmappedSize( ref args );
@ -94,24 +94,28 @@ namespace ClassicalSharp {
/// <summary> Draws the specified string from the arguments into a new bitmap,
/// then creates a 2D texture with origin at the specified window coordinates. </summary>
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 );
}
/// <summary> 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. </summary>
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 ) {
/// <summary> 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. </summary>
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;

View File

@ -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() {

View File

@ -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 ) {

View File

@ -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 );
}
}
}

View File

@ -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 );
}
}
}

View File

@ -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] );
}

View File

@ -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 );

View File

@ -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;
}
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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 );

View File

@ -109,6 +109,7 @@
<Compile Include="2D\Widgets\Chat\ChatTextWidget.cs" />
<Compile Include="2D\Widgets\Chat\AltTextInputWidget.cs" />
<Compile Include="2D\Widgets\Chat\TextGroupWidget.cs" />
<Compile Include="2D\Widgets\Chat\TextGroupWidget.Formatter.cs" />
<Compile Include="2D\Widgets\Chat\TextInputWidget.cs" />
<Compile Include="2D\Widgets\Chat\TextInputWidget.Handlers.cs" />
<Compile Include="2D\Widgets\ExtPlayerListWidget.cs" />

View File

@ -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 ) {