corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 using OpenMetaverse;
2 using System;
3 using System.Collections.Generic;
4 using System.Drawing;
5 using System.Text;
6 using System.Windows.Forms;
7  
8 namespace OpenMetaverse.GUI
9 {
10 /// <summary>
11 /// ToolStrip GUI component for displaying and switching between IM windows
12 /// </summary>
13 public class MessageBar : ToolStrip
14 {
15 private GridClient _Client;
16 private Dictionary<UUID, MessageBarButton> _Sessions;
17  
18 /// <summary>
19 /// A ToolBarButton representing an IM session, including its associated window
20 /// </summary>
21 class MessageBarButton : ToolStripButton
22 {
23 public delegate void MessageNeedsSendingCallback(UUID targetID, string message);
24 public event MessageNeedsSendingCallback OnMessageNeedsSending;
25  
26 /// <summary>Target avatar name</summary>
27 public string TargetName;
28 /// <summary>Target avatar ID</summary>
29 public UUID TargetID;
30 /// <summary>IM session ID</summary>
31 public UUID IMSessionID;
32 /// <summary>Window for this IM session</summary>
33 public MessageWindow Window;
34  
35 /// <summary>
36 /// A class representing each IM session and its associated button and window objects
37 /// </summary>
38 public MessageBarButton(string targetName, UUID targetID, UUID imSessionID)
39 {
40 TargetName = targetName;
41 TargetID = targetID;
42 IMSessionID = imSessionID;
43  
44 this.Text = targetName;
45  
46 Window = new MessageWindow(targetName);
47 Window.FormClosing += new FormClosingEventHandler(Window_FormClosing);
48 Window.OnTextInput += new MessageWindow.TextInputCallback(Window_OnTextInput);
49 }
50  
51 void Window_FormClosing(object sender, FormClosingEventArgs e)
52 {
53 this.Parent.Items.Remove(this);
54 this.Dispose();
55 }
56  
57 void Window_OnTextInput(string text)
58 {
59 if (OnMessageNeedsSending != null)
60 OnMessageNeedsSending(TargetID, text);
61 }
62 }
63  
64 /// <summary>
65 /// A generic form for displaying text and accepting user input
66 /// </summary>
67 class MessageWindow : Form
68 {
69 private RichTextBox rtfOutput = new RichTextBox();
70 private TextBox txtInput = new TextBox();
71  
72 public delegate void TextInputCallback(string text);
73 public event TextInputCallback OnTextInput;
74  
75 /// <summary>
76 /// A generic form for displaying text and accepting user input
77 /// </summary>
78 public MessageWindow(string title)
79 {
80 rtfOutput.Anchor = AnchorStyles.Bottom | AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
81 rtfOutput.BackColor = Color.FromKnownColor(KnownColor.Window);
82 rtfOutput.Width = this.Width;
83 rtfOutput.Height = this.Height - txtInput.Height;
84 rtfOutput.ReadOnly = true;
85 rtfOutput.Top = 0;
86 rtfOutput.Left = 0;
87  
88 txtInput.Dock = DockStyle.Bottom;
89 txtInput.KeyDown += new KeyEventHandler(txtInput_KeyDown);
90  
91 this.Text = title;
92 this.Controls.AddRange(new Control[] { txtInput, rtfOutput });
93  
94 this.Resize += new EventHandler(MessageWindow_Resize);
95 }
96  
97 /// <summary>
98 /// Thread-safe method for adding text of a specified color to the display output
99 /// </summary>
100 /// <param name="text"></param>
101 /// <param name="color"></param>
102 public void LogText(string text, Color color)
103 {
104 if (this.InvokeRequired)
105 {
106 this.BeginInvoke((MethodInvoker)delegate { LogText(text, color); });
107 }
108 else
109 {
110 rtfOutput.SelectionStart = rtfOutput.Text.Length;
111 rtfOutput.SelectionColor = color;
112 DateTime now = DateTime.Now;
113 rtfOutput.SelectedText = string.Format("{0}[{1}:{2}] {3}", Environment.NewLine, now.Hour.ToString().PadLeft(2, '0'), now.Minute.ToString().PadLeft(2, '0'), text);
114 rtfOutput.ScrollToCaret();
115 }
116 }
117  
118 /// <summary>
119 /// Thread-safe method for setting the window title
120 /// </summary>
121 /// <param name="title"></param>
122 public void SetTitle(string title)
123 {
124 if (this.InvokeRequired)
125 {
126 this.BeginInvoke((MethodInvoker)delegate { SetTitle(title); });
127 }
128 else
129 {
130 this.Text = title;
131 }
132 }
133  
134 void MessageWindow_Resize(object sender, EventArgs e)
135 {
136 if (this.WindowState == FormWindowState.Minimized)
137 this.Hide();
138 }
139  
140 void txtInput_KeyDown(object sender, KeyEventArgs e)
141 {
142 if (e.KeyCode == Keys.Enter && txtInput.Text != string.Empty)
143 {
144 e.SuppressKeyPress = true;
145  
146 if (OnTextInput != null)
147 OnTextInput(txtInput.Text);
148  
149 txtInput.Clear();
150 }
151 }
152 }
153  
154 /// <summary>
155 /// Gets or sets the GridClient associated with this control
156 /// </summary>
157 public GridClient Client
158 {
159 get { return _Client; }
160 set { if (value != null) InitializeClient(value); }
161 }
162  
163 /// <summary>
164 /// ToolStrip control for displaying and switching between an unspecified client's IM windows
165 /// </summary>
166 public MessageBar()
167 {
168 _Sessions = new Dictionary<UUID, MessageBarButton>();
169  
170 this.Dock = System.Windows.Forms.DockStyle.Bottom;
171 this.Location = new System.Drawing.Point(0, 523);
172 this.Size = new System.Drawing.Size(772, 25);
173 this.TabIndex = 6;
174  
175 this.ItemClicked += new ToolStripItemClickedEventHandler(MessageBar_ItemClicked);
176 }
177  
178 public void CreateSession(string name, UUID id, UUID imSessionID, bool open)
179 {
180 MessageBarButton button = new MessageBarButton(name, id, imSessionID);
181 button.Disposed += new EventHandler(button_Disposed);
182 button.OnMessageNeedsSending += new MessageBarButton.MessageNeedsSendingCallback(button_OnMessageNeedsSending);
183 AddButton(button, open);
184 }
185  
186 private void AddButton(MessageBarButton button, bool open)
187 {
188 if (this.InvokeRequired) this.BeginInvoke((MethodInvoker)delegate { AddButton(button, open); });
189 else
190 {
191 _Sessions.Add(button.TargetID, button);
192 this.Items.Add((ToolStripItem)button);
193 if (open)
194 button.Window.Show();
195 }
196 }
197  
198 private void AddButton(MessageBarButton button, InstantMessage im)
199 {
200 if (this.InvokeRequired) this.BeginInvoke((MethodInvoker)delegate { AddButton(button, im); });
201 else
202 {
203 AddButton(button, false);
204 _Sessions[im.FromAgentID].Window.LogText(im.FromAgentName + ": " + im.Message, Color.FromKnownColor(KnownColor.ControlText));
205 }
206 }
207  
208 private void InitializeClient(GridClient client)
209 {
210 _Client = client;
211 _Client.Self.IM += Self_IM;
212 }
213  
214 void Self_IM(object sender, InstantMessageEventArgs e)
215 {
216 if (e.IM.Dialog == InstantMessageDialog.MessageFromAgent)
217 {
218 lock (_Sessions)
219 {
220 if (_Sessions.ContainsKey(e.IM.FromAgentID))
221 {
222 _Sessions[e.IM.FromAgentID].IMSessionID = e.IM.IMSessionID;
223 _Sessions[e.IM.FromAgentID].Window.LogText(e.IM.FromAgentName + ": " + e.IM.Message, Color.FromKnownColor(KnownColor.ControlText));
224 }
225 else
226 {
227 CreateSession(e.IM.FromAgentName, e.IM.FromAgentID, e.IM.IMSessionID, false);
228 }
229 }
230 }
231 }
232  
233 void button_OnMessageNeedsSending(UUID targetID, string message)
234 {
235 lock (_Sessions)
236 {
237 MessageBarButton button;
238 if (_Sessions.TryGetValue(targetID, out button))
239 {
240 button.Window.LogText(Client.Self.Name + ": " + message, Color.FromKnownColor(KnownColor.ControlText));
241 Client.Self.InstantMessage(targetID, message, button.IMSessionID);
242 }
243 }
244 }
245  
246 void MessageBar_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
247 {
248 MessageBarButton button = (MessageBarButton)e.ClickedItem;
249  
250 if (this.InvokeRequired) this.BeginInvoke((MethodInvoker)delegate { button.Window.Show(); button.Window.Activate(); button.Window.WindowState = FormWindowState.Normal; });
251 else { button.Window.Show(); button.Window.Activate(); button.Window.WindowState = FormWindowState.Normal; }
252 }
253  
254 void button_Disposed(object sender, EventArgs e)
255 {
256 MessageBarButton button = (MessageBarButton)sender;
257 lock (_Sessions)
258 {
259 if (_Sessions.ContainsKey(button.TargetID))
260 _Sessions.Remove(button.TargetID);
261 }
262 }
263 }
264 }