corrade-vassal – Rev 16
?pathlinks?
using OpenMetaverse;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace OpenMetaverse.GUI
{
/// <summary>
/// ToolStrip GUI component for displaying and switching between IM windows
/// </summary>
public class MessageBar : ToolStrip
{
private GridClient _Client;
private Dictionary<UUID, MessageBarButton> _Sessions;
/// <summary>
/// A ToolBarButton representing an IM session, including its associated window
/// </summary>
class MessageBarButton : ToolStripButton
{
public delegate void MessageNeedsSendingCallback(UUID targetID, string message);
public event MessageNeedsSendingCallback OnMessageNeedsSending;
/// <summary>Target avatar name</summary>
public string TargetName;
/// <summary>Target avatar ID</summary>
public UUID TargetID;
/// <summary>IM session ID</summary>
public UUID IMSessionID;
/// <summary>Window for this IM session</summary>
public MessageWindow Window;
/// <summary>
/// A class representing each IM session and its associated button and window objects
/// </summary>
public MessageBarButton(string targetName, UUID targetID, UUID imSessionID)
{
TargetName = targetName;
TargetID = targetID;
IMSessionID = imSessionID;
this.Text = targetName;
Window = new MessageWindow(targetName);
Window.FormClosing += new FormClosingEventHandler(Window_FormClosing);
Window.OnTextInput += new MessageWindow.TextInputCallback(Window_OnTextInput);
}
void Window_FormClosing(object sender, FormClosingEventArgs e)
{
this.Parent.Items.Remove(this);
this.Dispose();
}
void Window_OnTextInput(string text)
{
if (OnMessageNeedsSending != null)
OnMessageNeedsSending(TargetID, text);
}
}
/// <summary>
/// A generic form for displaying text and accepting user input
/// </summary>
class MessageWindow : Form
{
private RichTextBox rtfOutput = new RichTextBox();
private TextBox txtInput = new TextBox();
public delegate void TextInputCallback(string text);
public event TextInputCallback OnTextInput;
/// <summary>
/// A generic form for displaying text and accepting user input
/// </summary>
public MessageWindow(string title)
{
rtfOutput.Anchor = AnchorStyles.Bottom | AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
rtfOutput.BackColor = Color.FromKnownColor(KnownColor.Window);
rtfOutput.Width = this.Width;
rtfOutput.Height = this.Height - txtInput.Height;
rtfOutput.ReadOnly = true;
rtfOutput.Top = 0;
rtfOutput.Left = 0;
txtInput.Dock = DockStyle.Bottom;
txtInput.KeyDown += new KeyEventHandler(txtInput_KeyDown);
this.Text = title;
this.Controls.AddRange(new Control[] { txtInput, rtfOutput });
this.Resize += new EventHandler(MessageWindow_Resize);
}
/// <summary>
/// Thread-safe method for adding text of a specified color to the display output
/// </summary>
/// <param name="text"></param>
/// <param name="color"></param>
public void LogText(string text, Color color)
{
if (this.InvokeRequired)
{
this.BeginInvoke((MethodInvoker)delegate { LogText(text, color); });
}
else
{
rtfOutput.SelectionStart = rtfOutput.Text.Length;
rtfOutput.SelectionColor = color;
DateTime now = DateTime.Now;
rtfOutput.SelectedText = string.Format("{0}[{1}:{2}] {3}", Environment.NewLine, now.Hour.ToString().PadLeft(2, '0'), now.Minute.ToString().PadLeft(2, '0'), text);
rtfOutput.ScrollToCaret();
}
}
/// <summary>
/// Thread-safe method for setting the window title
/// </summary>
/// <param name="title"></param>
public void SetTitle(string title)
{
if (this.InvokeRequired)
{
this.BeginInvoke((MethodInvoker)delegate { SetTitle(title); });
}
else
{
this.Text = title;
}
}
void MessageWindow_Resize(object sender, EventArgs e)
{
if (this.WindowState == FormWindowState.Minimized)
this.Hide();
}
void txtInput_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter && txtInput.Text != string.Empty)
{
e.SuppressKeyPress = true;
if (OnTextInput != null)
OnTextInput(txtInput.Text);
txtInput.Clear();
}
}
}
/// <summary>
/// Gets or sets the GridClient associated with this control
/// </summary>
public GridClient Client
{
get { return _Client; }
set { if (value != null) InitializeClient(value); }
}
/// <summary>
/// ToolStrip control for displaying and switching between an unspecified client's IM windows
/// </summary>
public MessageBar()
{
_Sessions = new Dictionary<UUID, MessageBarButton>();
this.Dock = System.Windows.Forms.DockStyle.Bottom;
this.Location = new System.Drawing.Point(0, 523);
this.Size = new System.Drawing.Size(772, 25);
this.TabIndex = 6;
this.ItemClicked += new ToolStripItemClickedEventHandler(MessageBar_ItemClicked);
}
public void CreateSession(string name, UUID id, UUID imSessionID, bool open)
{
MessageBarButton button = new MessageBarButton(name, id, imSessionID);
button.Disposed += new EventHandler(button_Disposed);
button.OnMessageNeedsSending += new MessageBarButton.MessageNeedsSendingCallback(button_OnMessageNeedsSending);
AddButton(button, open);
}
private void AddButton(MessageBarButton button, bool open)
{
if (this.InvokeRequired) this.BeginInvoke((MethodInvoker)delegate { AddButton(button, open); });
else
{
_Sessions.Add(button.TargetID, button);
this.Items.Add((ToolStripItem)button);
if (open)
button.Window.Show();
}
}
private void AddButton(MessageBarButton button, InstantMessage im)
{
if (this.InvokeRequired) this.BeginInvoke((MethodInvoker)delegate { AddButton(button, im); });
else
{
AddButton(button, false);
_Sessions[im.FromAgentID].Window.LogText(im.FromAgentName + ": " + im.Message, Color.FromKnownColor(KnownColor.ControlText));
}
}
private void InitializeClient(GridClient client)
{
_Client = client;
_Client.Self.IM += Self_IM;
}
void Self_IM(object sender, InstantMessageEventArgs e)
{
if (e.IM.Dialog == InstantMessageDialog.MessageFromAgent)
{
lock (_Sessions)
{
if (_Sessions.ContainsKey(e.IM.FromAgentID))
{
_Sessions[e.IM.FromAgentID].IMSessionID = e.IM.IMSessionID;
_Sessions[e.IM.FromAgentID].Window.LogText(e.IM.FromAgentName + ": " + e.IM.Message, Color.FromKnownColor(KnownColor.ControlText));
}
else
{
CreateSession(e.IM.FromAgentName, e.IM.FromAgentID, e.IM.IMSessionID, false);
}
}
}
}
void button_OnMessageNeedsSending(UUID targetID, string message)
{
lock (_Sessions)
{
MessageBarButton button;
if (_Sessions.TryGetValue(targetID, out button))
{
button.Window.LogText(Client.Self.Name + ": " + message, Color.FromKnownColor(KnownColor.ControlText));
Client.Self.InstantMessage(targetID, message, button.IMSessionID);
}
}
}
void MessageBar_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
MessageBarButton button = (MessageBarButton)e.ClickedItem;
if (this.InvokeRequired) this.BeginInvoke((MethodInvoker)delegate { button.Window.Show(); button.Window.Activate(); button.Window.WindowState = FormWindowState.Normal; });
else { button.Window.Show(); button.Window.Activate(); button.Window.WindowState = FormWindowState.Normal; }
}
void button_Disposed(object sender, EventArgs e)
{
MessageBarButton button = (MessageBarButton)sender;
lock (_Sessions)
{
if (_Sessions.ContainsKey(button.TargetID))
_Sessions.Remove(button.TargetID);
}
}
}
}