[gnome-contacts] Avatar: lazily load the Pixbuf of the avatar.
- From: Niels De Graef <nielsdg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-contacts] Avatar: lazily load the Pixbuf of the avatar.
- Date: Mon, 22 Jan 2018 16:39:04 +0000 (UTC)
commit b4822d1040af1ff5858fe22924acbfb75a96ca7d
Author: Niels De Graef <nielsdegraef gmail com>
Date: Mon Jan 22 17:38:00 2018 +0100
Avatar: lazily load the Pixbuf of the avatar.
This should again decrease our memory usage in most cases.
src/contacts-avatar-selector.vala | 9 +-----
src/contacts-avatar.vala | 44 +++++++++++++++++++++--------
src/contacts-contact-editor.vala | 10 +------
src/contacts-contact-list.vala | 3 +-
src/contacts-contact-sheet.vala | 5 +---
src/contacts-link-suggestion-grid.vala | 7 +---
src/contacts-linked-accounts-dialog.vala | 5 +---
7 files changed, 39 insertions(+), 44 deletions(-)
---
diff --git a/src/contacts-avatar-selector.vala b/src/contacts-avatar-selector.vala
index 16c1ba4..83e3631 100644
--- a/src/contacts-avatar-selector.vala
+++ b/src/contacts-avatar-selector.vala
@@ -82,14 +82,7 @@ public class Contacts.AvatarSelector : Dialog {
this.contact = contact;
// Load the current avatar
- this.current_avatar = new Avatar (MAIN_SIZE);
- if (contact != null) {
- contact.keep_widget_uptodate (this.current_avatar, (w) => {
- (w as Avatar).set_image.begin (contact.individual, contact);
- });
- } else {
- this.current_avatar.set_image.begin (null, null);
- }
+ this.current_avatar = new Avatar (MAIN_SIZE, contact);
this.current_avatar.set_hexpand (false);
this.current_avatar.show ();
this.grid.attach (this.current_avatar, 0, 0);
diff --git a/src/contacts-avatar.vala b/src/contacts-avatar.vala
index 3d62747..bfe6c9c 100644
--- a/src/contacts-avatar.vala
+++ b/src/contacts-avatar.vala
@@ -26,45 +26,65 @@ using Gee;
public class Contacts.Avatar : DrawingArea {
private int size;
private Gdk.Pixbuf? pixbuf = null;
+
private Contact? contact = null;
+ // We want to lazily load the Pixbuf to make sure we don't draw all contact avatars at once.
+ // As long as there is no need for it to be drawn, keep this to false.
+ private bool avatar_loaded = false;
// The background color used in case of a fallback avatar
private Gdk.RGBA? bg_color = null;
// The color used for an initial or the fallback icon
private const Gdk.RGBA fg_color = { 0, 0, 0, 0.25 };
- public Avatar (int size) {
+ public Avatar (int size, Contact? contact = null) {
+ this.contact = contact;
+ if (contact != null) {
+ contact.individual.notify["avatar"].connect ( (s, p) => {
+ load_avatar.begin ();
+ });
+ }
+
this.size = size;
set_size_request (size, size);
get_style_context ().add_class ("contacts-avatar");
+ // If we don't have an avatar, don't try to load it later
+ this.avatar_loaded = (contact == null || contact.individual == null
+ || contact.individual.avatar == null);
+
show ();
}
+ /**
+ * Manually set the avatar to the given pixbuf, even if the contact has an avatar.
+ */
public void set_pixbuf (Gdk.Pixbuf? a_pixbuf) {
this.pixbuf = a_pixbuf;
queue_draw ();
}
- public async void set_image (AvatarDetails? details, Contact? contact = null) {
- this.contact = contact;
-
- // FIXME listen for changes in the Individual's avatar
+ private async void load_avatar () {
+ assert (this.contact != null);
- if (details != null && details.avatar != null) {
- try {
- var stream = yield details.avatar.load_async (size, null);
- this.pixbuf = yield new Gdk.Pixbuf.from_stream_at_scale_async (stream, size, size, true);
- queue_draw ();
- } catch {
- }
+ this.avatar_loaded = true;
+ try {
+ var stream = yield this.contact.individual.avatar.load_async (this.size);
+ this.pixbuf = yield new Gdk.Pixbuf.from_stream_at_scale_async (stream, this.size, this.size, true);
+ queue_draw ();
+ } catch (Error e) {
+ debug ("Couldn't load avatar of contact %s. Reason: %s", this.contact.individual.display_name,
e.message);
}
}
public override bool draw (Cairo.Context cr) {
cr.save ();
+ // This exists to implement lazy loading: i.e. only load the avatar on the first draw()
+ if (!this.avatar_loaded)
+ load_avatar.begin ();
+
if (this.pixbuf != null)
draw_contact_avatar (cr);
else // No avatar available, draw a fallback
diff --git a/src/contacts-contact-editor.vala b/src/contacts-contact-editor.vala
index 0c5de6d..3cde0c2 100644
--- a/src/contacts-contact-editor.vala
+++ b/src/contacts-contact-editor.vala
@@ -942,21 +942,13 @@ public class Contacts.ContactEditor : Grid {
// Creates the contact's current avatar in a big button on top of the Editor
private void create_avatar_button () {
- this.avatar = new Avatar (PROFILE_SIZE);
+ this.avatar = new Avatar (PROFILE_SIZE, this.contact);
var button = new Button ();
button.get_accessible ().set_name (_("Change avatar"));
button.image = this.avatar;
button.clicked.connect (on_avatar_button_clicked);
- if (this.contact != null) {
- this.contact.keep_widget_uptodate (this.avatar, (w) => {
- this.avatar.set_image.begin (this.contact.individual, this.contact);
- });
- } else {
- this.avatar.set_image.begin (null, null);
- }
-
this.container_grid.attach (button, 0, 0, 1, 3);
}
diff --git a/src/contacts-contact-list.vala b/src/contacts-contact-list.vala
index 2aa2b85..618ecc8 100644
--- a/src/contacts-contact-list.vala
+++ b/src/contacts-contact-list.vala
@@ -44,7 +44,7 @@ public class Contacts.ContactList : ListBox {
grid.margin = 3;
grid.margin_start = 9;
grid.set_column_spacing (10);
- this.avatar = new Avatar (LIST_AVATAR_SIZE);
+ this.avatar = new Avatar (LIST_AVATAR_SIZE, this.contact);
this.label = new Label (c.individual.display_name);
this.label.ellipsize = Pango.EllipsizeMode.END;
@@ -71,7 +71,6 @@ public class Contacts.ContactList : ListBox {
public void update () {
// Update widgets
this.label.set_text (this.contact.individual.display_name);
- this.avatar.set_image.begin (this.contact.individual, this.contact);
}
// Sets whether the checbox should always be shown (and not only on hover)
diff --git a/src/contacts-contact-sheet.vala b/src/contacts-contact-sheet.vala
index 88c0bb1..8467f46 100644
--- a/src/contacts-contact-sheet.vala
+++ b/src/contacts-contact-sheet.vala
@@ -96,12 +96,9 @@ public class Contacts.ContactSheet : Grid {
}
public void update (Contact c) {
- var image_frame = new Avatar (PROFILE_SIZE);
+ var image_frame = new Avatar (PROFILE_SIZE, c);
image_frame.set_vexpand (false);
image_frame.set_valign (Align.START);
- c.keep_widget_uptodate (image_frame, (w) => {
- (w as Avatar).set_image.begin (c.individual, c);
- });
attach (image_frame, 0, 0, 1, 3);
var name_label = new Label (null);
diff --git a/src/contacts-link-suggestion-grid.vala b/src/contacts-link-suggestion-grid.vala
index 36f4a61..998c5eb 100644
--- a/src/contacts-link-suggestion-grid.vala
+++ b/src/contacts-link-suggestion-grid.vala
@@ -43,16 +43,13 @@ public class Contacts.LinkSuggestionGrid : Grid {
public LinkSuggestionGrid (Contact contact) {
get_style_context ().add_class ("contacts-suggestion");
- var image_frame = new Avatar (AVATAR_SIZE);
+ var image_frame = new Avatar (AVATAR_SIZE, contact);
image_frame.hexpand = false;
image_frame.margin = 12;
- contact.keep_widget_uptodate (image_frame, (w) => {
- (w as Avatar).set_image.begin (contact.individual, contact);
- });
image_frame.show ();
attach (image_frame, 0, 0, 1, 2);
- this.description_label.xalign = 0; // FIXME: hack to make it actually align left.
+ this.description_label.xalign = 0;
this.description_label.label = contact.is_main?
_("Is this the same person as %s from %s?").printf (contact.individual.display_name,
contact.format_persona_stores ())
: _("Is this the same person as %s?").printf (contact.individual.display_name);
diff --git a/src/contacts-linked-accounts-dialog.vala b/src/contacts-linked-accounts-dialog.vala
index 6bb3df6..5913e5e 100644
--- a/src/contacts-linked-accounts-dialog.vala
+++ b/src/contacts-linked-accounts-dialog.vala
@@ -80,13 +80,10 @@ public class Contacts.LinkedAccountsDialog : Dialog {
var row_grid = new Grid ();
- var image_frame = new Avatar (AVATAR_SIZE);
+ var image_frame = new Avatar (AVATAR_SIZE, contact);
image_frame.set_hexpand (false);
image_frame.margin = 6;
image_frame.margin_end = 12;
- contact.keep_widget_uptodate (image_frame, (w) => {
- (w as Avatar).set_image.begin (contact.individual, contact);
- });
row_grid.attach (image_frame, 0, 0, 1, 2);
var display_name = new Label ("");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]