[gnome-contacts/wip/christopherdavis/hdy-avatar] avatar: Use HdyAvatar




commit 5ba47f86bbf7c9bbeb12af6802dcef062caa560c
Author: Christopher Davis <brainblasted disroot org>
Date:   Sat Oct 3 15:30:13 2020 -0700

    avatar: Use HdyAvatar
    
    Makes Contacts.Avatar a wrapper around HdyAvatar.
    This allows us to drop our custom fallback and
    circular avatar code in favor of HdyAvatar.
    
    Fixes https://gitlab.gnome.org/GNOME/gnome-contacts/-/issues/183
    
    Related to https://gitlab.gnome.org/GNOME/Initiatives/-/issues/20

 src/contacts-avatar-selector.vala |   3 +-
 src/contacts-avatar-utils.vala    | 183 --------------------------------------
 src/contacts-avatar.vala          | 106 ++++++----------------
 src/meson.build                   |   1 -
 4 files changed, 30 insertions(+), 263 deletions(-)
---
diff --git a/src/contacts-avatar-selector.vala b/src/contacts-avatar-selector.vala
index e2e9c1cf..5e6a1600 100644
--- a/src/contacts-avatar-selector.vala
+++ b/src/contacts-avatar-selector.vala
@@ -119,8 +119,7 @@ public class Contacts.AvatarSelector : Popover {
 
   private FlowBoxChild create_thumbnail (Gdk.Pixbuf source_pixbuf) {
     var avatar = new Avatar (ICONS_SIZE);
-    var pixbuf = source_pixbuf.scale_simple (ICONS_SIZE, ICONS_SIZE, Gdk.InterpType.HYPER);
-    avatar.set_pixbuf (pixbuf);
+    avatar.set_pixbuf (source_pixbuf);
 
     var button = new Button ();
     button.get_style_context ().add_class (AVATAR_BUTTON_CSS_NAME);
diff --git a/src/contacts-avatar.vala b/src/contacts-avatar.vala
index 9f542170..578af8f1 100644
--- a/src/contacts-avatar.vala
+++ b/src/contacts-avatar.vala
@@ -23,85 +23,15 @@ using Gee;
  * The Avatar of a Contact is responsible for showing an {@link Folks.Individual}'s
  * avatar, or a fallback if it's not available.
  */
-public class Contacts.Avatar : DrawingArea {
-  private int size;
-  private Gdk.Pixbuf? pixbuf = null;
-  private Gdk.Pixbuf? cache = null;
+public class Contacts.Avatar : Bin {
+  private Hdy.Avatar widget;
 
   private Individual? individual = 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;
 
   public Avatar (int size, Individual? individual = null) {
     this.individual = individual;
-    if (individual != null) {
-      individual.notify["avatar"].connect ( (s, p) => {
-        load_avatar.begin ();
-      });
-    }
-
-    this.size = size;
-    set_size_request (size, size);
-
-    // If we don't have an avatar, don't try to load it later
-    this.avatar_loaded = (individual == null || 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.cache = null;
-    this.pixbuf = a_pixbuf;
-    queue_draw ();
-  }
-
-  private async void load_avatar () {
-    assert (this.individual != null);
-
-    this.avatar_loaded = true;
-    try {
-      var stream = yield this.individual.avatar.load_async (this.size);
-      this.cache = null;
-      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.individual.display_name, e.message);
-    }
-  }
-
-  public override bool draw (Cairo.Context cr) {
-    // 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.cache != null) {
-    // Don't do anything if we have already a cached avatar
-    } else if (this.pixbuf != null)
-      this.cache = create_contact_avatar ();
-    else // No avatar or cache available, create the fallback
-      this.cache = create_fallback ();
-
-    draw_cached_avatar (cr);
-
-    return true;
-  }
-
-  private void draw_cached_avatar (Cairo.Context cr) {
-    Gdk.cairo_set_source_pixbuf (cr, this.cache, 0, 0);
-    cr.paint ();
-  }
-
-  private Gdk.Pixbuf create_contact_avatar () {
-    return AvatarUtils.round_image(this.pixbuf);
-  }
-
-  private Gdk.Pixbuf create_fallback () {
     string name = "";
-    bool show_label = false;
+    bool show_initials = false;
     if (this.individual != null) {
       name = find_display_name ();
       /* If we don't have a usable name use the display_name
@@ -110,13 +40,35 @@ public class Contacts.Avatar : DrawingArea {
       if (name == "") {
         name = this.individual.display_name;
       } else {
-        show_label = true;
+        show_initials = true;
       }
     }
-    var pixbuf = AvatarUtils.generate_user_picture(name, this.size, show_label);
-    pixbuf = AvatarUtils.round_image(pixbuf);
 
-    return pixbuf;
+    this.widget = new Hdy.Avatar (size, name, show_initials);
+    this.widget.set_image_load_func (size => {
+      if (this.individual != null && this.individual.avatar != null) {
+        try {
+          var stream = this.individual.avatar.load (size, null);
+          return new Gdk.Pixbuf.from_stream_at_scale (stream, size, size, true);
+        } catch (Error e) {
+          debug ("Couldn't load avatar of contact %s. Reason: %s", this.individual.display_name, e.message);
+        }
+      }
+      return null;
+    });
+    this.widget.show ();
+    add(this.widget);
+
+    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.widget.set_image_load_func (size => {
+      return a_pixbuf.scale_simple (size, size, Gdk.InterpType.HYPER);
+    });
   }
 
   /* Find a nice name to generate the label and color for the fallback avatar
diff --git a/src/meson.build b/src/meson.build
index 63b28478..a38b2629 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -13,7 +13,6 @@ libcontacts_sources = files(
   'contacts-typeset.vala',
   'contacts-type-descriptor.vala',
   'contacts-utils.vala',
-  'contacts-avatar-utils.vala',
   'contacts-vcard-type-mapping.vala',
 )
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]