diff --git a/OpenMetaverse.GUI/AvatarList.cs b/OpenMetaverse.GUI/AvatarList.cs index 4ddce9b1..1001649a 100644 --- a/OpenMetaverse.GUI/AvatarList.cs +++ b/OpenMetaverse.GUI/AvatarList.cs @@ -26,15 +26,10 @@ using OpenMetaverse; using System; +using System.Collections; using System.Collections.Generic; using System.Windows.Forms; -using System.Drawing; -using System.Collections; -using System.ComponentModel; -using System.Data; -using System.IO; - namespace OpenMetaverse.GUI { /// @@ -162,17 +157,14 @@ namespace OpenMetaverse.GUI private void AvatarList_DoubleClick(object sender, EventArgs e) { - ListView list = (ListView)sender; - if (list.SelectedItems.Count > 0) + if (OnAvatarDoubleClick != null) { - if (list.SelectedItems[0].Tag is Avatar) + ListView list = (ListView)sender; + if (list.SelectedItems.Count > 0 && list.SelectedItems[0].Tag is Avatar) { Avatar av = (Avatar)list.SelectedItems[0].Tag; - if (OnAvatarDoubleClick != null) - { - try { OnAvatarDoubleClick(av); } - catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex); } - } + try { OnAvatarDoubleClick(av); } + catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex); } } } } diff --git a/OpenMetaverse.GUI/FriendsList.cs b/OpenMetaverse.GUI/FriendsList.cs new file mode 100644 index 00000000..a6defc2f --- /dev/null +++ b/OpenMetaverse.GUI/FriendsList.cs @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2007-2008, openmetaverse.org + * All rights reserved. + * + * - Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * - Neither the name of the openmetaverse.org nor the names + * of its contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; + +namespace OpenMetaverse.GUI +{ + + /// + /// ListView GUI component for viewing a client's friends list + /// + public class FriendsList : ListView + { + private GridClient _Client; + private ColumnSorter _ColumnSorter = new ColumnSorter(); + + public delegate void FriendDoubleClickCallback(FriendInfo friend); + + /// + /// Triggered when the user double clicks on a friend in the list + /// + public event FriendDoubleClickCallback OnFriendDoubleClick; + + /// + /// Gets or sets the GridClient associated with this control + /// + public GridClient Client + { + get { return _Client; } + set { if (value != null) InitializeClient(value); } + } + + /// + /// TreeView control for an unspecified client's friends list + /// + public FriendsList() + { + ColumnHeader header1 = this.Columns.Add("Name"); + header1.Width = this.Width - 20; + + ColumnHeader header2 = this.Columns.Add(" "); + header2.Width = 40; + + _ColumnSorter.SortColumn = 0; + + this.DoubleBuffered = true; + this.ListViewItemSorter = _ColumnSorter; + this.View = View.Details; + + this.ColumnClick += new ColumnClickEventHandler(FriendsList_ColumnClick); + this.DoubleClick += new System.EventHandler(FriendsList_DoubleClick); + } + + /// + /// TreeView control for the specified client's friends list + /// + public FriendsList(GridClient client) : this () + { + InitializeClient(client); + } + + private void InitializeClient(GridClient client) + { + _Client = client; + _Client.Friends.OnFriendNamesReceived += new FriendsManager.FriendNamesReceived(Friends_OnFriendNamesReceived); + _Client.Friends.OnFriendOffline += new FriendsManager.FriendOfflineEvent(Friends_OnFriendOffline); + _Client.Friends.OnFriendOnline += new FriendsManager.FriendOnlineEvent(Friends_OnFriendOnline); + _Client.Network.OnLogin += new NetworkManager.LoginCallback(Network_OnLogin); + } + + private void RefreshFriends() + { + if (this.InvokeRequired) this.BeginInvoke((MethodInvoker)delegate { RefreshFriends(); }); + else + { + Client.Friends.FriendList.ForEach(delegate(FriendInfo friend) + { + string key = friend.UUID.ToString(); + string onlineText; + string name = friend.Name == null ? "(loading...)" : friend.Name; + int image; + Color color; + + if (friend.IsOnline) + { + image = 1; + onlineText = "*"; + color = Color.FromKnownColor(KnownColor.ControlText); + } + else + { + image = 0; + onlineText = string.Empty; + color = Color.FromKnownColor(KnownColor.GrayText); + } + + if (!this.Items.ContainsKey(key)) + { + this.Items.Add(key, name, image); + this.Items[key].SubItems.Add(onlineText); + } + else + { + if (this.Items[key].Text == string.Empty || friend.Name != null) + this.Items[key].Text = name; + + this.Items[key].SubItems[1].Text = onlineText; + } + + this.Items[key].ForeColor = color; + this.Items[key].ImageIndex = image; + this.Items[key].Tag = friend; + }); + } + } + + private void Friends_OnFriendOffline(FriendInfo friend) + { + RefreshFriends(); + } + + private void Friends_OnFriendOnline(FriendInfo friend) + { + RefreshFriends(); + } + + private void Friends_OnFriendNamesReceived(Dictionary names) + { + RefreshFriends(); + } + + private void FriendsList_ColumnClick(object sender, ColumnClickEventArgs e) + { + _ColumnSorter.SortColumn = e.Column; + if ((_ColumnSorter.Ascending = (this.Sorting == SortOrder.Ascending))) this.Sorting = SortOrder.Descending; + else this.Sorting = SortOrder.Ascending; + this.ListViewItemSorter = _ColumnSorter; + } + + private void FriendsList_DoubleClick(object sender, System.EventArgs e) + { + if (OnFriendDoubleClick != null) + { + ListView list = (ListView)sender; + if (list.SelectedItems.Count > 0 && list.SelectedItems[0].Tag is FriendInfo) + { + FriendInfo friend = (FriendInfo)list.SelectedItems[0].Tag; + try { OnFriendDoubleClick(friend); } + catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client, ex); } + } + } + } + + private void Network_OnLogin(LoginStatus login, string message) + { + if (login == LoginStatus.Success) RefreshFriends(); + } + + private class ColumnSorter : IComparer + { + public bool Ascending = true; + public int SortColumn = 0; + + public int Compare(object a, object b) + { + ListViewItem itemA = (ListViewItem)a; + ListViewItem itemB = (ListViewItem)b; + + if (SortColumn == 1) + { + if (Ascending) return string.Compare(itemA.SubItems[1].Text + itemA.Text, itemB.SubItems[1].Text + itemB.Text); + else return -string.Compare(itemA.SubItems[1].Text + itemA.Text, itemB.SubItems[1].Text + itemB.Text); + } + else + { + if (Ascending) return string.Compare(itemA.Text, itemB.Text); + else return -string.Compare(itemA.Text, itemB.Text); + } + } + } + + } +} diff --git a/OpenMetaverse.GUI/InventoryTree.cs b/OpenMetaverse.GUI/InventoryTree.cs index 840db17d..3be43159 100644 --- a/OpenMetaverse.GUI/InventoryTree.cs +++ b/OpenMetaverse.GUI/InventoryTree.cs @@ -138,7 +138,7 @@ namespace OpenMetaverse.GUI children[key].Tag = inv; if (inv is InventoryFolder) { - children[key].Nodes.Add(null, "Loading...").ForeColor = Color.FromKnownColor(KnownColor.GrayText); + children[key].Nodes.Add(null, "(loading...)").ForeColor = Color.FromKnownColor(KnownColor.GrayText); ((InventoryFolder)inv).OnContentsRetrieved += new InventoryFolder.ContentsRetrieved(InventoryFolder_OnContentsRetrieved); } }