2 // Radegast Metaverse Client
3 // Copyright (c) 2009, Radegast Development Team
4 // All rights reserved.
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
9 // * Redistributions of source code must retain the above copyright notice,
10 // this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 // * Neither the name of the application "Radegast", nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 using System.Collections.Generic;
33 using System.ComponentModel;
35 using System.Windows.Forms;
36 using Radegast.Netcom;
41 public partial class TabsConsole : UserControl
45 /// List of nearby avatars (radar data)
47 public List<NearbyAvatar> NearbyAvatars
51 List<NearbyAvatar> res = new List<NearbyAvatar>();
53 if (TabExists("chat"))
55 ChatConsole c = (ChatConsole)Tabs["chat"].Control;
56 lock (c.agentSimHandle)
58 foreach (ListViewItem item in c.lvwObjects.Items)
60 if (item.Name != client.Self.AgentID.ToString())
62 res.Add(new NearbyAvatar() { ID = new UUID(item.Name), Name = item.Text });
73 /// Delegate invoked on tab operations
75 /// <param name="sender">Event sender</param>
76 /// <param name="e">Event arguments</param>
77 public delegate void TabCallback(object sender, TabEventArgs e);
80 /// Fired when a tab is selected
82 public event TabCallback OnTabSelected;
86 /// Delegate invoked when chat notification is printed
88 /// <param name="sender">Event sender</param>
89 /// <param name="e">Event arguments</param>
90 public delegate void ChatNotificationCallback(object sender, ChatNotificationEventArgs e);
93 /// Fired when a tab is selected
95 public event ChatNotificationCallback OnChatNotification;
98 /// Fired when a new tab is added
100 public event TabCallback OnTabAdded;
103 /// Fired when a tab is removed
105 public event TabCallback OnTabRemoved;
107 private RadegastInstance instance;
108 private GridClient client { get { return instance.Client; } }
109 private RadegastNetcom netcom { get { return instance.Netcom; } }
110 private ChatTextManager mainChatManger;
112 private Dictionary<string, RadegastTab> tabs = new Dictionary<string, RadegastTab>();
113 public Dictionary<string, RadegastTab> Tabs { get { return tabs; } }
115 private ChatConsole chatConsole;
117 private RadegastTab selectedTab;
120 /// Currently selected tab
122 public RadegastTab SelectedTab
132 public TabsConsole(RadegastInstance instance)
134 InitializeComponent();
135 Disposed += new EventHandler(TabsConsole_Disposed);
137 this.instance = instance;
138 this.instance.ClientChanged += new EventHandler<ClientChangedEventArgs>(instance_ClientChanged);
146 RegisterClientEvents(client);
149 private void RegisterClientEvents(GridClient client)
151 client.Self.ScriptQuestion += new EventHandler<ScriptQuestionEventArgs>(Self_ScriptQuestion);
152 client.Self.ScriptDialog += new EventHandler<ScriptDialogEventArgs>(Self_ScriptDialog);
155 private void UnregisterClientEvents(GridClient client)
157 client.Self.ScriptQuestion -= new EventHandler<ScriptQuestionEventArgs>(Self_ScriptQuestion);
158 client.Self.ScriptDialog -= new EventHandler<ScriptDialogEventArgs>(Self_ScriptDialog);
161 void instance_ClientChanged(object sender, ClientChangedEventArgs e)
163 UnregisterClientEvents(e.OldClient);
164 RegisterClientEvents(client);
167 void TabsConsole_Disposed(object sender, EventArgs e)
169 RemoveNetcomEvents();
170 UnregisterClientEvents(client);
173 private void AddNetcomEvents()
175 netcom.ClientLoginStatus += new EventHandler<LoginProgressEventArgs>(netcom_ClientLoginStatus);
176 netcom.ClientLoggedOut += new EventHandler(netcom_ClientLoggedOut);
177 netcom.ClientDisconnected += new EventHandler<DisconnectedEventArgs>(netcom_ClientDisconnected);
178 netcom.ChatReceived += new EventHandler<ChatEventArgs>(netcom_ChatReceived);
179 netcom.ChatSent += new EventHandler<ChatSentEventArgs>(netcom_ChatSent);
180 netcom.AlertMessageReceived += new EventHandler<AlertMessageEventArgs>(netcom_AlertMessageReceived);
181 netcom.InstantMessageReceived += new EventHandler<InstantMessageEventArgs>(netcom_InstantMessageReceived);
184 private void RemoveNetcomEvents()
186 netcom.ClientLoginStatus -= new EventHandler<LoginProgressEventArgs>(netcom_ClientLoginStatus);
187 netcom.ClientLoggedOut -= new EventHandler(netcom_ClientLoggedOut);
188 netcom.ClientDisconnected -= new EventHandler<DisconnectedEventArgs>(netcom_ClientDisconnected);
189 netcom.ChatReceived -= new EventHandler<ChatEventArgs>(netcom_ChatReceived);
190 netcom.ChatSent -= new EventHandler<ChatSentEventArgs>(netcom_ChatSent);
191 netcom.AlertMessageReceived -= new EventHandler<AlertMessageEventArgs>(netcom_AlertMessageReceived);
192 netcom.InstantMessageReceived -= new EventHandler<InstantMessageEventArgs>(netcom_InstantMessageReceived);
195 void Self_ScriptDialog(object sender, ScriptDialogEventArgs e)
197 instance.MainForm.AddNotification(new ntfScriptDialog(instance, e.Message, e.ObjectName, e.ImageID, e.ObjectID, e.FirstName, e.LastName, e.Channel, e.ButtonLabels));
200 void Self_ScriptQuestion(object sender, ScriptQuestionEventArgs e)
202 instance.MainForm.AddNotification(new ntfPermissions(instance, e.Simulator, e.TaskID, e.ItemID, e.ObjectName, e.ObjectOwnerName, e.Questions));
205 private void netcom_ClientLoginStatus(object sender, LoginProgressEventArgs e)
207 if (e.Status == LoginStatus.Failed)
209 DisplayNotificationInChat("Login error: " + e.Message, ChatBufferTextStyle.Error);
211 else if (e.Status == LoginStatus.Success)
213 DisplayNotificationInChat("Logged in as " + netcom.LoginOptions.FullName + ".", ChatBufferTextStyle.StatusDarkBlue);
214 DisplayNotificationInChat("Login reply: " + e.Message, ChatBufferTextStyle.StatusDarkBlue);
216 InitializeOnlineTabs();
218 if (tabs.ContainsKey("login"))
220 if (selectedTab.Name == "login")
222 ForceCloseTab("login");
225 client.Self.RetrieveInstantMessages();
229 private void netcom_ClientLoggedOut(object sender, EventArgs e)
234 DisplayNotificationInChat("Logged out.");
238 private void netcom_ClientDisconnected(object sender, DisconnectedEventArgs e)
240 if (e.Reason == NetworkManager.DisconnectType.ClientInitiated) return;
244 DisplayNotificationInChat("Disconnected: " + e.Message, ChatBufferTextStyle.Error);
247 private void netcom_AlertMessageReceived(object sender, AlertMessageEventArgs e)
249 tabs["chat"].Highlight();
252 private void netcom_ChatSent(object sender, ChatSentEventArgs e)
254 tabs["chat"].Highlight();
257 private void netcom_ChatReceived(object sender, ChatEventArgs e)
259 if (string.IsNullOrEmpty(e.Message)) return;
261 tabs["chat"].Highlight();
264 private void netcom_InstantMessageReceived(object sender, InstantMessageEventArgs e)
268 case InstantMessageDialog.SessionSend:
269 if (instance.Groups.ContainsKey(e.IM.IMSessionID))
275 HandleConferenceIM(e);
279 case InstantMessageDialog.MessageFromAgent:
280 if (e.IM.FromAgentName == "Second Life")
282 HandleIMFromObject(e);
284 else if (e.IM.GroupIM || instance.Groups.ContainsKey(e.IM.IMSessionID))
288 else if (e.IM.BinaryBucket.Length > 1)
290 HandleConferenceIM(e);
298 case InstantMessageDialog.MessageFromObject:
299 HandleIMFromObject(e);
302 case InstantMessageDialog.StartTyping:
303 if (TabExists(e.IM.FromAgentName))
305 RadegastTab tab = tabs[e.IM.FromAgentName.ToLower()];
306 if (!tab.Highlighted) tab.PartialHighlight();
311 case InstantMessageDialog.StopTyping:
312 if (TabExists(e.IM.FromAgentName))
314 RadegastTab tab = tabs[e.IM.FromAgentName.ToLower()];
315 if (!tab.Highlighted) tab.Unhighlight();
320 case InstantMessageDialog.MessageBox:
321 instance.MainForm.AddNotification(new ntfGeneric(instance, e.IM.Message));
324 case InstantMessageDialog.RequestTeleport:
325 if (instance.RLV.AutoAcceptTP(e.IM.FromAgentID))
327 DisplayNotificationInChat("Auto accepting teleprot from " + e.IM.FromAgentName);
328 instance.Client.Self.TeleportLureRespond(e.IM.FromAgentID, true);
332 instance.MainForm.AddNotification(new ntfTeleport(instance, e.IM));
336 case InstantMessageDialog.GroupInvitation:
337 instance.MainForm.AddNotification(new ntfGroupInvitation(instance, e.IM));
340 case InstantMessageDialog.FriendshipOffered:
341 instance.MainForm.AddNotification(new ntfFriendshipOffer(instance, e.IM));
344 case InstantMessageDialog.InventoryAccepted:
345 DisplayNotificationInChat(e.IM.FromAgentName + " accepted your inventory offer.");
348 case InstantMessageDialog.InventoryDeclined:
349 DisplayNotificationInChat(e.IM.FromAgentName + " declined your inventory offer.");
352 case InstantMessageDialog.GroupNotice:
353 instance.MainForm.AddNotification(new ntfGroupNotice(instance, e.IM));
356 case InstantMessageDialog.InventoryOffered:
357 case InstantMessageDialog.TaskInventoryOffered:
358 instance.MainForm.AddNotification(new ntfInventoryOffer(instance, e.IM));
364 /// Make default tab (chat) active
366 public void SelectDefaultTab()
368 if (TabExists("chat"))
369 tabs["chat"].Select();
373 /// Displays notification in the main chat tab
375 /// <param name="msg">Message to be printed in the chat tab</param>
376 public void DisplayNotificationInChat(string msg)
378 DisplayNotificationInChat(msg, ChatBufferTextStyle.ObjectChat);
382 /// Displays notification in the main chat tab
384 /// <param name="msg">Message to be printed in the chat tab</param>
385 /// <param name="style">Style of the message to be printed, normal, object, etc.</param>
386 public void DisplayNotificationInChat(string msg, ChatBufferTextStyle style)
388 DisplayNotificationInChat(msg, style, true);
392 /// Displays notification in the main chat tab
394 /// <param name="msg">Message to be printed in the chat tab</param>
395 /// <param name="style">Style of the message to be printed, normal, object, etc.</param>
396 /// <param name="highlightChatTab">Highligt (and flash in taskbar) chat tab if not selected</param>
397 public void DisplayNotificationInChat(string msg, ChatBufferTextStyle style, bool highlightChatTab)
401 BeginInvoke(new MethodInvoker(() => DisplayNotificationInChat(msg, style, highlightChatTab)));
405 if (style != ChatBufferTextStyle.Invisible)
407 ChatBufferItem line = new ChatBufferItem(
415 mainChatManger.ProcessBufferItem(line, true);
416 if (highlightChatTab)
418 tabs["chat"].Highlight();
421 catch (Exception) { }
424 if (OnChatNotification != null)
426 try { OnChatNotification(this, new ChatNotificationEventArgs(msg, style)); }
431 private void HandleIMFromObject(InstantMessageEventArgs e)
433 DisplayNotificationInChat(e.IM.FromAgentName + ": " + e.IM.Message);
436 private void HandleIM(InstantMessageEventArgs e)
438 if (TabExists(e.IM.IMSessionID.ToString()))
440 RadegastTab tab = tabs[e.IM.IMSessionID.ToString()];
441 if (!tab.Selected) tab.Highlight();
445 IMTabWindow imTab = AddIMTab(e);
446 tabs[e.IM.IMSessionID.ToString()].Highlight();
449 private void HandleConferenceIM(InstantMessageEventArgs e)
451 if (TabExists(e.IM.IMSessionID.ToString()))
453 RadegastTab tab = tabs[e.IM.IMSessionID.ToString()];
454 if (!tab.Selected) tab.Highlight();
458 ConferenceIMTabWindow imTab = AddConferenceIMTab(e);
459 tabs[e.IM.IMSessionID.ToString()].Highlight();
462 private void HandleGroupIM(InstantMessageEventArgs e)
464 if (TabExists(e.IM.IMSessionID.ToString()))
466 RadegastTab tab = tabs[e.IM.IMSessionID.ToString()];
467 if (!tab.Selected) tab.Highlight();
471 GroupIMTabWindow imTab = AddGroupIMTab(e);
472 tabs[e.IM.IMSessionID.ToString()].Highlight();
475 private void InitializeMainTab()
477 LoginConsole loginConsole = new LoginConsole(instance);
479 RadegastTab tab = AddTab("login", "Login", loginConsole);
480 tab.AllowClose = false;
481 tab.AllowDetach = false;
482 tab.AllowMerge = false;
483 tab.AllowHide = false;
485 loginConsole.RegisterTab(tab);
488 private void InitializeChatTab()
490 chatConsole = new ChatConsole(instance);
491 mainChatManger = chatConsole.ChatManager;
493 RadegastTab tab = AddTab("chat", "Chat", chatConsole);
494 tab.AllowClose = false;
495 tab.AllowDetach = false;
496 tab.AllowHide = false;
501 /// Create Tabs that only make sense when connected
503 private void InitializeOnlineTabs()
505 RadegastTab tab = AddTab("friends", "Friends", new FriendsConsole(instance));
506 tab.AllowClose = false;
507 tab.AllowDetach = true;
510 tab = AddTab("groups", "Groups", new GroupsConsole(instance));
511 tab.AllowClose = false;
512 tab.AllowDetach = true;
515 tab = AddTab("inventory", "Inventory", new InventoryConsole(instance));
516 tab.AllowClose = false;
517 tab.AllowDetach = true;
520 tab = AddTab("search", "Search", new SearchConsole(instance));
521 tab.AllowClose = false;
522 tab.AllowDetach = true;
525 if (!TabExists("map"))
527 tab = AddTab("map", "Map", new MapConsole(instance));
528 tab.AllowClose = false;
529 tab.AllowDetach = true;
533 tab = AddTab("voice", "Voice", new VoiceConsole(instance));
534 tab.AllowClose = false;
535 tab.AllowDetach = true;
540 /// Close tabs that make no sense when not connected
542 private void DisposeOnlineTabs()
546 ForceCloseTab("voice");
548 // Mono crashes if we try to open map for the second time
549 if (!instance.MonoRuntime)
550 ForceCloseTab("map");
551 else if (TabExists("map"))
554 ForceCloseTab("search");
555 ForceCloseTab("inventory");
556 ForceCloseTab("groups");
557 ForceCloseTab("friends");
561 private void ForceCloseTab(string name)
563 if (!TabExists(name)) return;
565 RadegastTab tab = tabs[name];
566 if (tab.Merged) SplitTab(tab);
568 tab.AllowClose = true;
574 public void RegisterContextAction(Type libomvType, String label, EventHandler handler)
576 instance.ContextActionManager.RegisterContextAction(libomvType, label, handler);
579 public void RegisterContextAction(ContextAction handler)
581 instance.ContextActionManager.RegisterContextAction(handler);
584 public void AddTab(RadegastTab tab)
586 ToolStripButton button = (ToolStripButton)tstTabs.Items.Add(tab.Label);
587 button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
589 button.AutoToolTip = false;
590 button.Tag = tab.Name;
591 button.Click += new EventHandler(TabButtonClick);
593 tabs.Add(tab.Name, tab);
595 if (OnTabAdded != null)
597 try { OnTabAdded(this, new TabEventArgs(tab)); }
598 catch (Exception) { }
602 public RadegastTab AddTab(string name, string label, Control control)
604 // WORKAROUND: one should never add tab that alrady exists
605 // but under some weird conditions disconnect/connect
606 // fire in the wrong order
609 Logger.Log("Force closing tab '" + name + "'", Helpers.LogLevel.Warning, client);
613 control.Visible = false;
614 control.Dock = DockStyle.Fill;
615 toolStripContainer1.ContentPanel.Controls.Add(control);
617 ToolStripButton button = (ToolStripButton)tstTabs.Items.Add(label);
618 button.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText;
620 button.AutoToolTip = false;
621 button.Tag = name.ToLower();
622 button.Click += new EventHandler(TabButtonClick);
624 RadegastTab tab = new RadegastTab(instance, button, control, name.ToLower(), label);
625 if (control is RadegastTabControl)
626 ((RadegastTabControl)control).RadegastTab = tab;
627 tab.TabAttached += new EventHandler(tab_TabAttached);
628 tab.TabDetached += new EventHandler(tab_TabDetached);
629 tab.TabSelected += new EventHandler(tab_TabSelected);
630 tab.TabClosed += new EventHandler(tab_TabClosed);
631 tab.TabHidden += new EventHandler(tab_TabHidden);
632 tabs.Add(name.ToLower(), tab);
634 if (OnTabAdded != null)
636 try { OnTabAdded(this, new TabEventArgs(tab)); }
637 catch (Exception) { }
643 private void tab_TabAttached(object sender, EventArgs e)
645 RadegastTab tab = (RadegastTab)sender;
649 private void tab_TabDetached(object sender, EventArgs e)
651 RadegastTab tab = (RadegastTab)sender;
652 frmDetachedTab form = (frmDetachedTab)tab.Owner;
654 form.ReattachStrip = tstTabs;
655 form.ReattachContainer = toolStripContainer1.ContentPanel;
658 private void tab_TabSelected(object sender, EventArgs e)
660 RadegastTab tab = (RadegastTab)sender;
662 if (selectedTab != null &&
664 { selectedTab.Deselect(); }
668 tbtnCloseTab.Enabled = tab.AllowClose || tab.AllowHide;
669 owner.AcceptButton = tab.DefaultControlButton;
671 if (OnTabSelected != null)
673 try { OnTabSelected(this, new TabEventArgs(selectedTab)); }
674 catch (Exception) { }
678 void tab_TabHidden(object sender, EventArgs e)
680 RadegastTab tab = (RadegastTab)sender;
682 if (selectedTab != null && selectedTab == tab)
689 private void tab_TabClosed(object sender, EventArgs e)
691 RadegastTab tab = (RadegastTab)sender;
693 if (selectedTab != null && selectedTab == tab && tab.Name != "chat")
699 tabs.Remove(tab.Name);
701 if (OnTabRemoved != null)
703 try { OnTabRemoved(this, new TabEventArgs(tab)); }
704 catch (Exception) { }
710 private void TabButtonClick(object sender, EventArgs e)
712 ToolStripButton button = (ToolStripButton)sender;
714 RadegastTab tab = tabs[button.Tag.ToString()];
718 public void RemoveTabEntry(RadegastTab tab)
720 if (tstTabs.Items.Contains(tab.Button))
722 tstTabs.Items.Remove(tab.Button);
725 tab.Button.Dispose();
726 tabs.Remove(tab.Name);
729 public void RemoveTab(string name)
731 if (tabs.ContainsKey(name))
737 //Used for outside classes that have a reference to TabsConsole
738 public void SelectTab(string name)
740 if (TabExists(name.ToLower()))
741 tabs[name.ToLower()].Select();
744 public bool TabExists(string name)
746 return tabs.ContainsKey(name.ToLower());
749 public RadegastTab GetTab(string name)
751 if (TabExists(name.ToLower()))
752 return tabs[name.ToLower()];
757 public List<RadegastTab> GetOtherTabs()
759 List<RadegastTab> otherTabs = new List<RadegastTab>();
761 foreach (ToolStripItem item in tstTabs.Items)
763 if (item.Tag == null) continue;
764 if ((ToolStripItem)item == selectedTab.Button) continue;
766 RadegastTab tab = tabs[item.Tag.ToString()];
767 if (!tab.AllowMerge) continue;
768 if (tab.Merged) continue;
777 /// Activates the next tab
779 public void SelectNextTab()
781 List<ToolStripItem> buttons = new List<ToolStripItem>();
783 foreach (ToolStripItem item in tstTabs.Items)
785 if (item.Tag == null || !item.Visible) continue;
792 for (int i = 0; i < buttons.Count; i++)
794 if (buttons[i] == selectedTab.Button)
803 if (current == buttons.Count)
806 SelectTab(tabs[buttons[current].Tag.ToString()].Name);
810 /// Activates the previous tab
812 public void SelectPreviousTab()
814 List<ToolStripItem> buttons = new List<ToolStripItem>();
816 foreach (ToolStripItem item in tstTabs.Items)
818 if (item.Tag == null || !item.Visible) continue;
825 for (int i = 0; i < buttons.Count; i++)
827 if (buttons[i] == selectedTab.Button)
837 current = buttons.Count - 1;
839 SelectTab(tabs[buttons[current].Tag.ToString()].Name);
843 public IMTabWindow AddIMTab(UUID target, UUID session, string targetName)
845 IMTabWindow imTab = new IMTabWindow(instance, target, session, targetName);
847 RadegastTab tab = AddTab(session.ToString(), "IM: " + targetName, imTab);
848 imTab.SelectIMInput();
854 public ConferenceIMTabWindow AddConferenceIMTab(UUID session, string name)
856 ConferenceIMTabWindow imTab = new ConferenceIMTabWindow(instance, session, name);
858 RadegastTab tab = AddTab(session.ToString(), name, imTab);
859 imTab.SelectIMInput();
865 public ConferenceIMTabWindow AddConferenceIMTab(InstantMessageEventArgs e)
867 ConferenceIMTabWindow imTab = AddConferenceIMTab(e.IM.IMSessionID, Utils.BytesToString(e.IM.BinaryBucket));
868 imTab.TextManager.ProcessIM(e);
872 public GroupIMTabWindow AddGroupIMTab(UUID session, string name)
874 GroupIMTabWindow imTab = new GroupIMTabWindow(instance, session, name);
876 RadegastTab tab = AddTab(session.ToString(), name, imTab);
877 imTab.SelectIMInput();
882 public GroupIMTabWindow AddGroupIMTab(InstantMessageEventArgs e)
884 GroupIMTabWindow imTab = AddGroupIMTab(e.IM.IMSessionID, Utils.BytesToString(e.IM.BinaryBucket));
885 imTab.TextManager.ProcessIM(e);
889 public IMTabWindow AddIMTab(InstantMessageEventArgs e)
891 IMTabWindow imTab = AddIMTab(e.IM.FromAgentID, e.IM.IMSessionID, e.IM.FromAgentName);
892 imTab.TextManager.ProcessIM(e);
896 public OutfitTextures AddOTTab(Avatar avatar)
898 OutfitTextures otTab = new OutfitTextures(instance, avatar);
900 RadegastTab tab = AddTab("OT: " + avatar.Name, "OT: " + avatar.Name, otTab);
905 public MasterTab AddMSTab(Avatar avatar)
907 MasterTab msTab = new MasterTab(instance, avatar);
909 RadegastTab tab = AddTab("MS: " + avatar.Name, "MS: " + avatar.Name, msTab);
913 public AttachmentTab AddATTab(Avatar avatar)
915 AttachmentTab atTab = new AttachmentTab(instance, avatar);
917 RadegastTab tab = AddTab("AT: " + avatar.Name, "AT: " + avatar.Name, atTab);
921 public AnimTab AddAnimTab(Avatar avatar)
923 AnimTab animTab = new AnimTab(instance, avatar);
925 RadegastTab tab = AddTab("Anim: " + avatar.Name, "Anim: " + avatar.Name, animTab);
929 private void tbtnTabOptions_Click(object sender, EventArgs e)
931 tmnuMergeWith.Enabled = selectedTab.AllowMerge;
932 tmnuDetachTab.Enabled = selectedTab.AllowDetach;
934 tmnuMergeWith.DropDown.Items.Clear();
936 if (!selectedTab.AllowMerge) return;
937 if (!selectedTab.Merged)
939 tmnuMergeWith.Text = "Merge With";
941 List<RadegastTab> otherTabs = GetOtherTabs();
943 tmnuMergeWith.Enabled = (otherTabs.Count > 0);
944 if (!tmnuMergeWith.Enabled) return;
946 foreach (RadegastTab tab in otherTabs)
948 ToolStripItem item = tmnuMergeWith.DropDown.Items.Add(tab.Label);
950 item.Click += new EventHandler(MergeItemClick);
955 tmnuMergeWith.Text = "Split";
956 tmnuMergeWith.Click += new EventHandler(SplitClick);
960 private void MergeItemClick(object sender, EventArgs e)
962 ToolStripItem item = (ToolStripItem)sender;
963 RadegastTab tab = tabs[item.Tag.ToString()];
965 selectedTab.MergeWith(tab);
967 SplitContainer container = (SplitContainer)selectedTab.Control;
968 toolStripContainer1.ContentPanel.Controls.Add(container);
970 selectedTab.Select();
973 tabs.Add(tab.Name, selectedTab);
976 private void SplitClick(object sender, EventArgs e)
978 SplitTab(selectedTab);
979 selectedTab.Select();
982 public void SplitTab(RadegastTab tab)
984 RadegastTab otherTab = tab.Split();
985 if (otherTab == null) return;
987 toolStripContainer1.ContentPanel.Controls.Add(tab.Control);
988 toolStripContainer1.ContentPanel.Controls.Add(otherTab.Control);
990 tabs.Remove(otherTab.Name);
994 private void tmnuDetachTab_Click(object sender, EventArgs e)
996 if (!selectedTab.AllowDetach) return;
997 RadegastTab tab = selectedTab;
999 tab.Detach(instance);
1002 private void tbtnCloseTab_Click(object sender, EventArgs e)
1004 RadegastTab tab = selectedTab;
1007 else if (tab.AllowHide)
1011 private void TabsConsole_Load(object sender, EventArgs e)
1013 owner = this.FindForm();
1016 private void ctxTabs_Opening(object sender, CancelEventArgs e)
1018 Point pt = this.PointToClient(Cursor.Position);
1019 ToolStripItem stripItem = tstTabs.GetItemAt(pt);
1021 if (stripItem == null)
1027 tabs[stripItem.Tag.ToString()].Select();
1029 ctxBtnClose.Enabled = selectedTab.AllowClose || selectedTab.AllowHide;
1030 ctxBtnDetach.Enabled = selectedTab.AllowDetach;
1031 ctxBtnMerge.Enabled = selectedTab.AllowMerge;
1032 ctxBtnMerge.DropDown.Items.Clear();
1034 if (!ctxBtnClose.Enabled && !ctxBtnDetach.Enabled && !ctxBtnMerge.Enabled)
1040 if (!selectedTab.AllowMerge) return;
1041 if (!selectedTab.Merged)
1043 ctxBtnMerge.Text = "Merge With";
1045 List<RadegastTab> otherTabs = GetOtherTabs();
1047 ctxBtnMerge.Enabled = (otherTabs.Count > 0);
1048 if (!ctxBtnMerge.Enabled) return;
1050 foreach (RadegastTab tab in otherTabs)
1052 ToolStripItem item = ctxBtnMerge.DropDown.Items.Add(tab.Label);
1053 item.Tag = tab.Name;
1054 item.Click += new EventHandler(MergeItemClick);
1059 ctxBtnMerge.Text = "Split";
1060 ctxBtnMerge.Click += new EventHandler(SplitClick);
1069 /// Arguments for tab events
1071 public class TabEventArgs : EventArgs
1074 /// Tab that was manipulated in the event
1076 public RadegastTab Tab;
1078 public TabEventArgs()
1083 public TabEventArgs(RadegastTab tab)
1091 /// Argument for chat notification events
1093 public class ChatNotificationEventArgs : EventArgs
1095 public string Message;
1096 public ChatBufferTextStyle Style;
1098 public ChatNotificationEventArgs(string message, ChatBufferTextStyle style)
1106 /// Element of list of nearby avatars
1108 public class NearbyAvatar
1110 public UUID ID { get; set; }
1111 public string Name { get; set; }