public class CellRendererContact : Gtk.CellRenderer { private static Gdk.Pixbuf online; private static Gdk.Pixbuf away; private static Gdk.Pixbuf dnd; private static Gdk.Pixbuf xa; private static Gdk.Pixbuf undefined; private static Gdk.Pixbuf offline; static construct { try { online = new Gdk.Pixbuf.from_file("icons/16x16/online.png"); away = new Gdk.Pixbuf.from_file("icons/16x16/away.png"); dnd = new Gdk.Pixbuf.from_file("icons/16x16/dnd.png"); xa = new Gdk.Pixbuf.from_file("icons/16x16/xa.png"); undefined = new Gdk.Pixbuf.from_file("icons/16x16/requested.png"); offline = new Gdk.Pixbuf.from_file("icons/16x16/offline.png"); } catch(Error e) { } } private Object _data; private Gtk.CellRendererText textRenderer = new Gtk.CellRendererText(); private Gtk.CellRendererPixbuf presenceRenderer = new Gtk.CellRendererPixbuf(); private Gtk.CellRendererPixbuf avatarRenderer = new Gtk.CellRendererPixbuf(); public Object data { get { return _data; } set { _data = value; if(_data is Contact) { Contact contact = _data as Contact; string str = Markup.escape_text(contact.display_string); Gee.Map.Entry res = contact.get_resource_with_highest_priority(); if(res != null && res.value.status != null) { string status = res.value.status; if(status.chr(-1, '\n') != null) { status = status.split("\n", 2)[0] + "..."; } str += "\n" + Markup.escape_text(status) + ""; } textRenderer.markup = str; Gee.Map.Entry? r = contact.get_resource_with_highest_priority(); if(r == null) { if(contact.subscription.is_to()) { presenceRenderer.pixbuf = offline; } else { presenceRenderer.pixbuf = undefined; } } else { switch(r.value.show) { case Contact.Show.ONLINE: presenceRenderer.pixbuf = online; break; case Contact.Show.AWAY: presenceRenderer.pixbuf = away; break; case Contact.Show.DND: presenceRenderer.pixbuf = dnd; break; case Contact.Show.XA: presenceRenderer.pixbuf = xa; break; default: presenceRenderer.pixbuf = undefined; break; } } avatarRenderer.pixbuf = contact.avatar; cell_background = "#fff"; } else if(_data is String) { textRenderer.markup = "" + Markup.escape_text((_data as String).data) + ""; cell_background = "#ddd"; } } } public override void get_size(Gtk.Widget widget, Gdk.Rectangle? cell_area, out int x_offset, out int y_offset, out int width, out int height) { if(_data is Contact) { int presenceX, presenceY, presenceWidth, presenceHeight; presenceRenderer.get_size(widget, cell_area, out presenceX, out presenceY, out presenceWidth, out presenceHeight); presenceWidth = 32; int textX, textY, textWidth, textHeight; textRenderer.get_size(widget, cell_area, out textX, out textY, out textWidth, out textHeight); int avatarX, avatarY, avatarWidth, avatarHeight; avatarRenderer.get_size(widget, cell_area, out avatarX, out avatarY, out avatarWidth, out avatarHeight); int calc_width = (presenceWidth + textWidth + avatarWidth); int calc_height = int.max(int.max(presenceHeight, textHeight), avatarHeight); if(&width != null) width = calc_width; if(&height != null) height = calc_height; if(cell_area != null) { if(&x_offset != null) x_offset = 0; if(&y_offset != null) y_offset = int.max((int)(yalign * (cell_area.height - calc_height)), 0); } else { if(&x_offset != null) x_offset = 0; if(&y_offset != null) y_offset = 0; } } else { textRenderer.get_size(widget, cell_area, out x_offset, out y_offset, out width, out height); } } public override void render(Gdk.Window window, Gtk.Widget widget, Gdk.Rectangle background_area, Gdk.Rectangle cell_area, Gdk.Rectangle expose_area, Gtk.CellRendererState flags) { if(_data is Contact) { // A bit hacky... int extra_width = cell_area.x - background_area.x; cell_area.x -= extra_width; cell_area.width += extra_width; expose_area.x -= extra_width; expose_area.width += extra_width; int presenceX, presenceY, presenceWidth, presenceHeight; presenceRenderer.get_size(widget, cell_area, out presenceX, out presenceY, out presenceWidth, out presenceHeight); presenceWidth = 32; int textX, textY, textWidth, textHeight; textRenderer.get_size(widget, cell_area, out textX, out textY, out textWidth, out textHeight); int avatarX, avatarY, avatarWidth, avatarHeight; avatarRenderer.get_size(widget, cell_area, out avatarX, out avatarY, out avatarWidth, out avatarHeight); Gdk.Rectangle presenceArea = cell_area; presenceArea.width = presenceWidth; presenceRenderer.render(window, widget, background_area, presenceArea, expose_area, flags); Gdk.Rectangle textArea = cell_area; textArea.x += presenceWidth; textArea.width -= (presenceWidth + avatarWidth); textRenderer.render(window, widget, background_area, textArea, expose_area, flags); Gdk.Rectangle avatarArea = cell_area; avatarArea.width = avatarWidth; avatarArea.x += (cell_area.width - avatarWidth); avatarRenderer.render(window, widget, background_area, avatarArea, expose_area, flags); } else if(_data is String) { textRenderer.render(window, widget, background_area, cell_area, expose_area, flags); } } public CellRendererContact() { Object(); textRenderer.ellipsize = Pango.EllipsizeMode.END; cell_background_set = true; } }