space-pew/Neoforce/Console.cs
Magnus von Wachenfeldt 4291dc0300 deprecated crap
2016-02-16 19:48:09 +01:00

594 lines
22 KiB
C#

////////////////////////////////////////////////////////////////
// //
// Neoforce Controls //
// //
////////////////////////////////////////////////////////////////
// //
// File: Console.cs //
// //
// Version: 0.7 //
// //
// Date: 11/09/2010 //
// //
// Author: Tom Shane //
// //
////////////////////////////////////////////////////////////////
// //
// Copyright (c) by Tom Shane //
// //
////////////////////////////////////////////////////////////////
#region //// Using /////////////
////////////////////////////////////////////////////////////////////////////
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections;
using System.Collections.Generic;
////////////////////////////////////////////////////////////////////////////
#endregion
namespace TomShane.Neoforce.Controls
{
public struct ConsoleMessage
{
public string Text;
public byte Channel;
public DateTime Time;
public string Sender;
public ConsoleMessage(string sender, string text, byte channel)
{
this.Text = text;
this.Channel = channel;
this.Time = DateTime.Now;
this.Sender = sender;
}
}
public class ChannelList : EventedList<ConsoleChannel>
{
#region //// Indexers //////////
////////////////////////////////////////////////////////////////////////////
public ConsoleChannel this[string name]
{
get
{
for (int i = 0; i < this.Count; i++)
{
ConsoleChannel s = (ConsoleChannel)this[i];
if (s.Name.ToLower() == name.ToLower())
{
return s;
}
}
return default(ConsoleChannel);
}
set
{
for (int i = 0; i < this.Count; i++)
{
ConsoleChannel s = (ConsoleChannel)this[i];
if (s.Name.ToLower() == name.ToLower())
{
this[i] = value;
}
}
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
public ConsoleChannel this[byte index]
{
get
{
for (int i = 0; i < this.Count; i++)
{
ConsoleChannel s = (ConsoleChannel)this[i];
if (s.Index == index)
{
return s;
}
}
return default(ConsoleChannel);
}
set
{
for (int i = 0; i < this.Count; i++)
{
ConsoleChannel s = (ConsoleChannel)this[i];
if (s.Index == index)
{
this[i] = value;
}
}
}
}
////////////////////////////////////////////////////////////////////////////
#endregion
}
public class ConsoleChannel
{
private string name;
private byte index;
private Color color;
public ConsoleChannel(byte index, string name, Color color)
{
this.name = name;
this.index = index;
this.color = color;
}
public virtual byte Index
{
get { return index; }
set { index = value; }
}
public virtual Color Color
{
get { return color; }
set { color = value; }
}
public virtual string Name
{
get { return name; }
set { name = value; }
}
}
[Flags]
public enum ConsoleMessageFormats
{
None = 0x00,
ChannelName = 0x01,
TimeStamp = 0x02,
Sender = 0x03,
All = Sender | ChannelName | TimeStamp
}
public class Console : Container
{
#region //// Fields ////////////
////////////////////////////////////////////////////////////////////////////
private TextBox txtMain = null;
private ComboBox cmbMain;
private EventedList<ConsoleMessage> buffer = new EventedList<ConsoleMessage>();
private ChannelList channels = new ChannelList();
private List<byte> filter = new List<byte>();
private ConsoleMessageFormats messageFormat = ConsoleMessageFormats.None;
private bool channelsVisible = true;
private bool textBoxVisible = true;
private string sender;
////////////////////////////////////////////////////////////////////////////
#endregion
#region //// Properties ////////
public string Sender
{
get { return sender; }
set { sender = value; }
}
////////////////////////////////////////////////////////////////////////////
public virtual EventedList<ConsoleMessage> MessageBuffer
{
get { return buffer; }
set
{
buffer.ItemAdded -= new EventHandler(buffer_ItemAdded);
buffer = value;
buffer.ItemAdded += new EventHandler(buffer_ItemAdded);
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
public virtual ChannelList Channels
{
get { return channels; }
set
{
channels.ItemAdded -= new EventHandler(channels_ItemAdded);
channels = value;
channels.ItemAdded += new EventHandler(channels_ItemAdded);
channels_ItemAdded(null, null);
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
public virtual List<byte> ChannelFilter
{
get { return filter; }
set { filter = value; }
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
public virtual byte SelectedChannel
{
set { cmbMain.Text = channels[value].Name; }
get { return channels[cmbMain.Text].Index; }
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
public virtual ConsoleMessageFormats MessageFormat
{
get { return messageFormat; }
set { messageFormat = value; }
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
public virtual bool ChannelsVisible
{
get { return channelsVisible; }
set
{
cmbMain.Visible = channelsVisible = value;
if (value && !textBoxVisible) TextBoxVisible = false;
PositionControls();
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
public virtual bool TextBoxVisible
{
get { return textBoxVisible; }
set
{
txtMain.Visible = textBoxVisible = value;
txtMain.Focused = true;
if (!value && channelsVisible) ChannelsVisible = false;
PositionControls();
}
}
////////////////////////////////////////////////////////////////////////////
#endregion
#region //// Events ////////////
////////////////////////////////////////////////////////////////////////////
public event ConsoleMessageEventHandler MessageSent;
////////////////////////////////////////////////////////////////////////////
#endregion
#region //// Construstors //////
////////////////////////////////////////////////////////////////////////////
public Console(Manager manager)
: base(manager)
{
Width = 320;
Height = 160;
MinimumHeight = 64;
MinimumWidth = 64;
CanFocus = false;
Resizable = false;
Movable = false;
cmbMain = new ComboBox(manager);
cmbMain.Init();
cmbMain.Top = Height - cmbMain.Height;
cmbMain.Left = 0;
cmbMain.Width = 128;
cmbMain.Anchor = Anchors.Left | Anchors.Bottom;
cmbMain.Detached = false;
cmbMain.DrawSelection = false;
cmbMain.Visible = channelsVisible;
Add(cmbMain, false);
txtMain = new TextBox(manager);
txtMain.Init();
txtMain.Top = Height - txtMain.Height;
txtMain.Left = cmbMain.Width + 1;
txtMain.Anchor = Anchors.Left | Anchors.Bottom | Anchors.Right;
txtMain.Detached = false;
txtMain.Visible = textBoxVisible;
txtMain.KeyDown += new KeyEventHandler(txtMain_KeyDown);
txtMain.GamePadDown += new GamePadEventHandler(txtMain_GamePadDown);
txtMain.FocusGained += new EventHandler(txtMain_FocusGained);
Add(txtMain, false);
VerticalScrollBar.Top = 2;
VerticalScrollBar.Left = Width - 18;
VerticalScrollBar.Range = 1;
VerticalScrollBar.PageSize = 1;
VerticalScrollBar.ValueChanged += new EventHandler(VerticalScrollBar_ValueChanged);
VerticalScrollBar.Visible = true;
ClientArea.Draw += new DrawEventHandler(ClientArea_Draw);
buffer.ItemAdded += new EventHandler(buffer_ItemAdded);
channels.ItemAdded += new EventHandler(channels_ItemAdded);
channels.ItemRemoved += new EventHandler(channels_ItemRemoved);
PositionControls();
}
////////////////////////////////////////////////////////////////////////////
#endregion
#region //// Methods ///////////
////////////////////////////////////////////////////////////////////////////
private void PositionControls()
{
if (txtMain != null)
{
txtMain.Left = channelsVisible ? cmbMain.Width + 1 : 0;
txtMain.Width = channelsVisible ? Width - cmbMain.Width - 1 : Width;
if (textBoxVisible)
{
ClientMargins = new Margins(Skin.ClientMargins.Left, Skin.ClientMargins.Top + 4, VerticalScrollBar.Width + 6, txtMain.Height + 4);
VerticalScrollBar.Height = Height - txtMain.Height - 5;
}
else
{
ClientMargins = new Margins(Skin.ClientMargins.Left, Skin.ClientMargins.Top + 4, VerticalScrollBar.Width + 6, 2);
VerticalScrollBar.Height = Height - 4;
}
Invalidate();
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
public override void Init()
{
base.Init();
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
protected internal override void InitSkin()
{
base.InitSkin();
Skin = new SkinControl(Manager.Skin.Controls["Console"]);
PositionControls();
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
protected internal override void Update(GameTime gameTime)
{
base.Update(gameTime);
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void ClientArea_Draw(object sender, DrawEventArgs e)
{
SpriteFont font = Skin.Layers[0].Text.Font.Resource;
Rectangle r = new Rectangle(e.Rectangle.Left, e.Rectangle.Top, e.Rectangle.Width, e.Rectangle.Height);
int pos = 0;
if (buffer.Count > 0)
{
EventedList<ConsoleMessage> b = GetFilteredBuffer(filter);
int c = b.Count;
int s = (VerticalScrollBar.Value + VerticalScrollBar.PageSize);
int f = s - VerticalScrollBar.PageSize;
if (b.Count > 0)
{
for (int i = s - 1; i >= f; i--)
{
{
int x = 4;
int y = r.Bottom - (pos + 1) * ((int)font.LineSpacing + 0);
string msg = ((ConsoleMessage)b[i]).Text;
string pre = "";
ConsoleChannel ch = (channels[((ConsoleMessage)b[i]).Channel] as ConsoleChannel);
if ((messageFormat & ConsoleMessageFormats.ChannelName) == ConsoleMessageFormats.ChannelName)
{
pre += string.Format("[{0}]", channels[((ConsoleMessage)b[i]).Channel].Name);
}
if ((messageFormat & ConsoleMessageFormats.Sender) == ConsoleMessageFormats.Sender)
{
pre += string.Format("[{0}]", ((ConsoleMessage)b[i]).Sender);
}
if ((messageFormat & ConsoleMessageFormats.TimeStamp) == ConsoleMessageFormats.TimeStamp)
{
pre = string.Format("[{0}]", ((ConsoleMessage)b[i]).Time.ToLongTimeString()) + pre;
}
if (pre != "") msg = pre + ": " + msg;
e.Renderer.DrawString(font,
msg,
x, y,
ch.Color);
pos += 1;
}
}
}
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
protected override void DrawControl(Renderer renderer, Rectangle rect, GameTime gameTime)
{
int h = txtMain.Visible ? (txtMain.Height + 1) : 0;
Rectangle r = new Rectangle(rect.Left, rect.Top, rect.Width, rect.Height - h);
base.DrawControl(renderer, r, gameTime);
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void txtMain_FocusGained(object sender, EventArgs e)
{
ConsoleChannel ch = channels[cmbMain.Text];
if (ch != null) txtMain.TextColor = ch.Color;
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void txtMain_KeyDown(object sender, KeyEventArgs e)
{
SendMessage(e);
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void txtMain_GamePadDown(object sender, GamePadEventArgs e)
{
SendMessage(e);
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
private void SendMessage(EventArgs x)
{
KeyEventArgs k = new KeyEventArgs();
GamePadEventArgs g = new GamePadEventArgs(PlayerIndex.One);
if (x is KeyEventArgs) k = x as KeyEventArgs;
else if (x is GamePadEventArgs) g = x as GamePadEventArgs;
ConsoleChannel ch = channels[cmbMain.Text];
if (ch != null)
{
txtMain.TextColor = ch.Color;
string message = txtMain.Text;
if ((k.Key == Microsoft.Xna.Framework.Input.Keys.Enter || g.Button == GamePadActions.Press) && message != null && message != "")
{
x.Handled = true;
ConsoleMessageEventArgs me = new ConsoleMessageEventArgs(new ConsoleMessage(sender, message, ch.Index));
OnMessageSent(me);
buffer.Add(new ConsoleMessage(sender, me.Message.Text, me.Message.Channel));
txtMain.Text = "";
ClientArea.Invalidate();
CalcScrolling();
}
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
protected virtual void OnMessageSent(ConsoleMessageEventArgs e)
{
if (MessageSent != null) MessageSent.Invoke(this, e);
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void channels_ItemAdded(object sender, EventArgs e)
{
cmbMain.Items.Clear();
for (int i = 0; i < channels.Count; i++)
{
cmbMain.Items.Add((channels[i] as ConsoleChannel).Name);
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void channels_ItemRemoved(object sender, EventArgs e)
{
cmbMain.Items.Clear();
for (int i = 0; i < channels.Count; i++)
{
cmbMain.Items.Add((channels[i] as ConsoleChannel).Name);
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void buffer_ItemAdded(object sender, EventArgs e)
{
CalcScrolling();
ClientArea.Invalidate();
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
private void CalcScrolling()
{
if (VerticalScrollBar != null)
{
int line = Skin.Layers[0].Text.Font.Resource.LineSpacing;
int c = GetFilteredBuffer(filter).Count;
int p = (int)Math.Ceiling(ClientArea.ClientHeight / (float)line);
VerticalScrollBar.Range = c == 0 ? 1 : c;
VerticalScrollBar.PageSize = c == 0 ? 1 : p;
VerticalScrollBar.Value = VerticalScrollBar.Range;
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
void VerticalScrollBar_ValueChanged(object sender, EventArgs e)
{
ClientArea.Invalidate();
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
protected override void OnResize(ResizeEventArgs e)
{
CalcScrolling();
base.OnResize(e);
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
private EventedList<ConsoleMessage> GetFilteredBuffer(List<byte> filter)
{
EventedList<ConsoleMessage> ret = new EventedList<ConsoleMessage>();
if (filter.Count > 0)
{
for (int i = 0; i < buffer.Count; i++)
{
if (filter.Contains(((ConsoleMessage)buffer[i]).Channel))
{
ret.Add(buffer[i]);
}
}
return ret;
}
else return buffer;
}
////////////////////////////////////////////////////////////////////////////
#endregion
}
}