From d5adf274c137bef22d5695d4a280e10068edcb0e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 23 Jun 2010 20:37:31 +0200 Subject: Show avatars in roster --- src/gui/CMakeLists.txt | 1 + src/gui/CellRendererAvatar.vala | 19 +++++++++++++++++++ src/gui/CellRendererContact.vala | 17 ++++++++++++++++- src/gui/Contact.vala | 2 ++ src/gui/CoreConnector.vala | 17 ++++++++++++++++- src/gui/Ephraim.vala | 24 +++++++++++++++++++----- src/gui/Roster.vala | 4 +++- 7 files changed, 76 insertions(+), 8 deletions(-) create mode 100644 src/gui/CellRendererAvatar.vala (limited to 'src/gui') diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index def009b..6208e62 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -2,6 +2,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ephraim_BINARY_DIR}) vala_precompile(VALA_C "Ephraim.vala" + "CellRendererAvatar.vala" "CellRendererContact.vala" "CellRendererPresence.vala" "Contact.vala" diff --git a/src/gui/CellRendererAvatar.vala b/src/gui/CellRendererAvatar.vala new file mode 100644 index 0000000..e4b53f4 --- /dev/null +++ b/src/gui/CellRendererAvatar.vala @@ -0,0 +1,19 @@ +public class CellRendererAvatar : Gtk.CellRendererPixbuf { + private Contact _contact; + + public Contact contact { + get { + return _contact; + } + set { + _contact = value; + + if(value == null) { + pixbuf = null; + return; + } + + pixbuf = value.avatar; + } + } +} diff --git a/src/gui/CellRendererContact.vala b/src/gui/CellRendererContact.vala index 7efe8cc..290ea09 100644 --- a/src/gui/CellRendererContact.vala +++ b/src/gui/CellRendererContact.vala @@ -8,7 +8,22 @@ public class CellRendererContact : Gtk.CellRendererText { set { _contact = value; - text = contact.display_string; + string str = escape_markup(contact.display_string); + + Gee.Map.Entry res = contact.get_resource_with_highest_priority(); + if(res != null && res.value.status != null) { + str += "\n" + escape_markup(res.value.status) + ""; + } + + markup = str; } } + + public CellRendererContact() { + ellipsize = Pango.EllipsizeMode.END; + } + + private static string escape_markup(string str) { + return str.replace("&", "&").replace("\"", """).replace("<", "<").replace(">", ">"); + } } diff --git a/src/gui/Contact.vala b/src/gui/Contact.vala index d79cfff..0e27b07 100644 --- a/src/gui/Contact.vala +++ b/src/gui/Contact.vala @@ -26,7 +26,9 @@ public class Contact : Object { public string jid {get; construct;} public string? name {get; construct;} public Subscription subscription {get; set;} + public Gdk.Pixbuf? avatar {get; set; default = null;} public Gee.TreeSet groups = new Gee.TreeSet(); + public string display_string {get; private set;} private Gee.HashMap resources = new Gee.HashMap(); diff --git a/src/gui/CoreConnector.vala b/src/gui/CoreConnector.vala index 1030428..9c492b7 100644 --- a/src/gui/CoreConnector.vala +++ b/src/gui/CoreConnector.vala @@ -90,7 +90,7 @@ public class CoreConnector { unowned Erl.Term term = store.term; Erl.Term match_term; - if((match_term = match("{roster_update,JID,Name,Subscription,Groups,Resources}", term)) != null) { + if((match_term = match("{roster_update,JID,Name,Subscription,Groups,Resources,Avatar}", term)) != null) { Erl.Term jid_term = match_term.var_content("JID"); if(!jid_term.is_binary()) // TODO Debug output @@ -151,6 +151,21 @@ public class CoreConnector { resources = resources.tl(); } + Erl.Term avatar = match("{avatar,Data}", match_term.var_content("Avatar")); + if(avatar != null) { + Erl.Term avatarData = avatar.var_content("Data"); + + if(avatarData.is_binary()) { + InputStream avatarStream = new MemoryInputStream.from_data(avatarData.bin_ptr(), avatarData.bin_size(), null); + try { + contact.avatar = new Gdk.Pixbuf.from_stream_at_scale(avatarStream, 32, 32, true, null); + avatarStream.close(null); + } catch(Error e) { + // TODO Debug output + } + } + } + roster.update_contact(contact); } else { diff --git a/src/gui/Ephraim.vala b/src/gui/Ephraim.vala index 6474482..5130247 100644 --- a/src/gui/Ephraim.vala +++ b/src/gui/Ephraim.vala @@ -25,13 +25,14 @@ public class Ephraim { rosterView.set_model(roster); rosterView.query_tooltip.connect((x, y, keyboard_tip, tooltip) => { + Gtk.TreeModel model; Gtk.TreeIter iter; - if(!rosterView.get_tooltip_context(out x, out y, keyboard_tip, null, null, out iter)) + if(!rosterView.get_tooltip_context(out x, out y, keyboard_tip, out model, null, out iter)) return false; Value value; - roster.get_value(iter, 0, out value); + model.get_value(iter, 0, out value); Contact? c = value.get_object() as Contact; if(c == null) @@ -42,14 +43,27 @@ public class Ephraim { if(r == null) return false; - tooltip.set_text("Resource: " + r.key); + tooltip.set_text("Resource: " + r.key + " (" + r.value.priority.to_string() + ")"); return true; }); rosterView.has_tooltip = true; - rosterView.append_column(new Gtk.TreeViewColumn.with_attributes("Presence", new CellRendererPresence(), "contact", 0, null)); - rosterView.append_column(new Gtk.TreeViewColumn.with_attributes("Contact", new CellRendererContact(), "contact", 0, null)); + Gtk.TreeViewColumn presenceColumn = new Gtk.TreeViewColumn.with_attributes(null, new CellRendererPresence(), "contact", 0, null); + presenceColumn.min_width = 32; + rosterView.append_column(presenceColumn); + + Gtk.TreeViewColumn contactColumn = new Gtk.TreeViewColumn(); + + Gtk.CellRenderer cellRendererContact = new CellRendererContact(); + contactColumn.pack_start(cellRendererContact, true); + contactColumn.set_attributes(cellRendererContact, "contact", 0, null); + + Gtk.CellRenderer cellRendererAvatar = new CellRendererAvatar(); + contactColumn.pack_end(cellRendererAvatar, false); + contactColumn.set_attributes(cellRendererAvatar, "contact", 0, null); + + rosterView.append_column(contactColumn); window.visible = true; diff --git a/src/gui/Roster.vala b/src/gui/Roster.vala index bd6b663..f25584c 100644 --- a/src/gui/Roster.vala +++ b/src/gui/Roster.vala @@ -80,8 +80,10 @@ public class Roster : Object, Gtk.TreeModel { } public void get_value (Gtk.TreeIter iter, int column, out Value value) { - if (column != 0 || iter.stamp != stamp || iter.user_data != this) + if (column != 0 || iter.stamp != stamp || iter.user_data != this) { + value = Value(Type.INVALID); return; + } Contact c = iter.user_data2 as Contact; value = Value(typeof(Contact)); -- cgit v1.2.3