using System; using System.Collections.Generic; using System.Drawing; using OpenTK.Input; namespace ClassicalSharp { public class ChatScreen : Screen { public ChatScreen( Game game ) : base( game ) { } public int ChatInputYOffset, ChatLogYOffset; public bool HistoryMode; const int chatLines = 12; Texture announcementTex; TextInputWidget textInput; TextGroupWidget status, bottomRight, normalChat; bool suppressNextPress = true; DateTime announcementDisplayTime; int chatIndex; public override void Render( double delta ) { normalChat.Render( delta ); status.Render( delta ); bottomRight.Render( delta ); if( announcementTex.IsValid ) { announcementTex.Render( graphicsApi ); } if( HandlesAllInput ) { textInput.Render( delta ); } if( game.Chat.Announcement != null && (DateTime.UtcNow - announcementDisplayTime).TotalSeconds > 5 ) { game.Chat.Announcement = null; graphicsApi.DeleteTexture( ref announcementTex ); } } static FastColour backColour = new FastColour( 60, 60, 60, 180 ); public void RenderBackground() { int height = normalChat.GetUsedHeight(); int y = normalChat.Y + normalChat.Height - height - 5; int x = normalChat.X - 5; int width = normalChat.Width + 10; if( height > 0 ) graphicsApi.Draw2DQuad( x, y, width, height + 10, backColour ); } Font chatFont, chatInputFont, announcementFont; public override void Init() { chatFont = new Font( "Arial", game.Chat.FontSize ); chatInputFont = new Font( "Arial", game.Chat.FontSize, FontStyle.Bold ); announcementFont = new Font( "Arial", 14 ); textInput = new TextInputWidget( game, chatFont, chatInputFont ); textInput.YOffset = ChatInputYOffset; status = new TextGroupWidget( game, 3, chatFont ); status.VerticalDocking = Docking.LeftOrTop; status.HorizontalDocking = Docking.BottomOrRight; status.Init(); bottomRight = new TextGroupWidget( game, 3, chatFont ); bottomRight.VerticalDocking = Docking.BottomOrRight; bottomRight.HorizontalDocking = Docking.BottomOrRight; bottomRight.YOffset = ChatInputYOffset; bottomRight.Init(); normalChat = new TextGroupWidget( game, chatLines, chatFont ); normalChat.XOffset = 10; normalChat.YOffset = ChatLogYOffset; normalChat.HorizontalDocking = Docking.LeftOrTop; normalChat.VerticalDocking = Docking.BottomOrRight; normalChat.Init(); ChatLog chat = game.Chat; chatIndex = chat.Log.Count - chatLines; ResetChat(); status.SetText( 0, chat.Status1 ); status.SetText( 1, chat.Status2 ); status.SetText( 2, chat.Status3 ); bottomRight.SetText( 2, chat.BottomRight1 ); bottomRight.SetText( 1, chat.BottomRight2 ); bottomRight.SetText( 0,chat.BottomRight3 ); UpdateAnnouncement( chat.Announcement ); if( !String.IsNullOrEmpty( game.chatInInputBuffer ) ) { OpenTextInputBar( game.chatInInputBuffer ); game.chatInInputBuffer = null; } game.Events.ChatReceived += ChatReceived; } void ChatReceived( object sender, ChatEventArgs e ) { CpeMessage type = e.Type; if( type == CpeMessage.Normal ) { chatIndex++; List chat = game.Chat.Log; normalChat.PushUpAndReplaceLast( chat[chatIndex + chatLines - 1] ); } else if( type >= CpeMessage.Status1 && type <= CpeMessage.Status3 ) { status.SetText( (int)( type - CpeMessage.Status1 ), e.Text ); } else if( type >= CpeMessage.BottomRight1 && type <= CpeMessage.BottomRight3 ) { bottomRight.SetText( 2 - (int)( type - CpeMessage.BottomRight1 ), e.Text ); } else if( type == CpeMessage.Announcement ) { UpdateAnnouncement( e.Text ); } } public override void Dispose() { if( !textInput.chatInputText.Empty ) { if( game.CursorVisible ) game.CursorVisible = false; game.chatInInputBuffer = textInput.chatInputText.ToString(); } chatFont.Dispose(); chatInputFont.Dispose(); announcementFont.Dispose(); normalChat.Dispose(); textInput.Dispose(); status.Dispose(); bottomRight.Dispose(); graphicsApi.DeleteTexture( ref announcementTex ); game.Events.ChatReceived -= ChatReceived; } public override void OnResize( int oldWidth, int oldHeight, int width, int height ) { announcementTex.X1 += ( width - oldWidth ) / 2; announcementTex.Y1 += ( height - oldHeight ) / 2; textInput.OnResize( oldWidth, oldHeight, width, height ); status.OnResize( oldWidth, oldHeight, width, height ); bottomRight.OnResize( oldWidth, oldHeight, width, height ); normalChat.OnResize( oldWidth, oldHeight, width, height ); } void UpdateAnnouncement( string text ) { announcementDisplayTime = DateTime.UtcNow; DrawTextArgs args = new DrawTextArgs( text, true ); announcementTex = game.Drawer2D.MakeTextTexture( announcementFont, 0, 0, ref args ); announcementTex.X1 = game.Width / 2 - announcementTex.Width / 2; announcementTex.Y1 = game.Height / 4 - announcementTex.Height / 2; } void ResetChat() { normalChat.Dispose(); List chat = game.Chat.Log; for( int i = chatIndex; i < chatIndex + chatLines; i++ ) { if( i >= 0 && i < chat.Count ) normalChat.PushUpAndReplaceLast( chat[i] ); } } public override bool HandlesKeyPress( char key ) { if( !HandlesAllInput ) return false; if( suppressNextPress ) { suppressNextPress = false; return false; } return textInput.HandlesKeyPress( key ); } void OpenTextInputBar( string initialText ) { if( !game.CursorVisible ) game.CursorVisible = true; suppressNextPress = true; HandlesAllInput = true; game.Keyboard.KeyRepeat = true; textInput.chatInputText.Clear(); textInput.chatInputText.Append( 0, initialText ); textInput.Init(); } public override bool HandlesKeyDown( Key key ) { suppressNextPress = false; if( HandlesAllInput ) { // text input bar if( key == game.Keys[KeyMapping.SendChat] || key == game.Keys[KeyMapping.PauseOrExit] ) { HandlesAllInput = false; if( game.CursorVisible ) game.CursorVisible = false; game.Camera.RegrabMouse(); game.Keyboard.KeyRepeat = false; if( key == game.Keys[KeyMapping.PauseOrExit] ) textInput.chatInputText.Clear(); textInput.SendTextInBufferAndReset(); } else if( key == Key.PageUp ) { chatIndex -= chatLines; int minIndex = Math.Min( 0, game.Chat.Log.Count - chatLines ); if( chatIndex < minIndex ) chatIndex = minIndex; ResetChat(); } else if( key == Key.PageDown ) { chatIndex += chatLines; if( chatIndex > game.Chat.Log.Count - chatLines ) chatIndex = game.Chat.Log.Count - chatLines; ResetChat(); } else if( key == game.Keys[KeyMapping.HideGui] ) { game.HideGui = !game.HideGui; } else { textInput.HandlesKeyDown( key ); } return true; } if( key == game.Keys[KeyMapping.OpenChat] ) { OpenTextInputBar( "" ); } else if( key == Key.Slash ) { OpenTextInputBar( "/" ); } else { return false; } return true; } public override bool HandlesMouseScroll( int delta ) { if( !HandlesAllInput ) return false; chatIndex += -delta; int maxIndex = game.Chat.Log.Count - chatLines; int minIndex = Math.Min( 0, maxIndex ); Utils.Clamp( ref chatIndex, minIndex, maxIndex ); ResetChat(); return true; } } }