[libadwaita/wip/exalm/warning: 1/4] avatar: Make custom images fill the circle




commit c3847b18460170bf21411967fd3d4df7865bfb66
Author: Kévin Commaille <zecakeh tedomum fr>
Date:   Sun Oct 31 20:00:23 2021 +0100

    avatar: Make custom images fill the circle
    
    Non-square images would be shown entirely, with empty spaces on the
    shortest side.
    
    Crop the largest side to make the image square, so it fills the circle.
    
    Same behavior as HdyAvatar.

 src/adw-avatar.c | 44 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 3 deletions(-)
---
diff --git a/src/adw-avatar.c b/src/adw-avatar.c
index 34ece640..ef74e010 100644
--- a/src/adw-avatar.c
+++ b/src/adw-avatar.c
@@ -50,6 +50,7 @@ struct _AdwAvatar
   GtkLabel *label;
   GtkImage *icon;
   GtkImage *custom_image;
+  GdkPaintable *square_image;
 
   char *icon_name;
   char *text;
@@ -286,6 +287,7 @@ adw_avatar_finalize (GObject *object)
 
   g_clear_pointer (&self->icon_name, g_free);
   g_clear_pointer (&self->text, g_free);
+  g_clear_object (&self->square_image);
 
   G_OBJECT_CLASS (adw_avatar_parent_class)->finalize (object);
 }
@@ -614,12 +616,48 @@ adw_avatar_set_custom_image (AdwAvatar    *self,
   if (gtk_image_get_paintable (self->custom_image) == custom_image)
     return;
 
-  gtk_image_set_from_paintable (self->custom_image, custom_image);
+  g_clear_object (&self->square_image);
+
+  if (custom_image) {
+    int height, width;
+
+    height = gdk_paintable_get_intrinsic_height(custom_image);
+    width = gdk_paintable_get_intrinsic_width(custom_image);
+
+    if (height == width) {
+      gtk_image_set_from_paintable (self->custom_image, custom_image);
+    } else {
+      GtkSnapshot *snapshot = gtk_snapshot_new ();
+      graphene_point_t* point;
+      graphene_size_t* s;
+      int size;
+
+      if (height > width) {
+        size = width;
+      } else {
+        size = height;
+      }
+
+      point = graphene_point_init (graphene_point_alloc (), (width - size) / -2.0, (height - size) / -2.0);
+      gtk_snapshot_translate (snapshot, point);
+
+      gdk_paintable_snapshot (custom_image, snapshot, width, height);
+
+      s = graphene_size_init (graphene_size_alloc (), size, size);
+
+      self->square_image = gtk_snapshot_free_to_paintable (snapshot, s);
+
+      graphene_point_free (point);
+      graphene_size_free (s);
+
+      gtk_image_set_from_paintable (self->custom_image, self->square_image);
+    }
 
-  if (custom_image)
     gtk_widget_add_css_class (self->gizmo, "image");
-  else
+  } else {
+    gtk_image_set_from_paintable (self->custom_image, NULL);
     gtk_widget_remove_css_class (self->gizmo, "image");
+  }
 
   update_visibility (self);
 


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