[libhandy] avatar: Add private HdyAvatarIcon



commit 9efd7a33ef2d7fa4f8c251739117d736f7580d43
Author: Julian Sparber <julian sparber net>
Date:   Mon Jan 11 12:42:24 2021 +0100

    avatar: Add private HdyAvatarIcon
    
    This class wraps the #HdyAvatarImageLoadFunc so that it can be used the
    as a GLoadableIcon, which simplifies the code for hdy_avatar_set_image_load_func ()

 doc/meson.build               |   1 +
 src/hdy-avatar-icon-private.h |  35 ++++++++++
 src/hdy-avatar-icon.c         | 151 ++++++++++++++++++++++++++++++++++++++++++
 src/meson.build               |   1 +
 4 files changed, 188 insertions(+)
---
diff --git a/doc/meson.build b/doc/meson.build
index dbf3766a..e8dcf1a6 100644
--- a/doc/meson.build
+++ b/doc/meson.build
@@ -7,6 +7,7 @@ private_headers = [
     'gtkprogresstrackerprivate.h',
     'gtk-window-private.h',
     'hdy-animation-private.h',
+    'hdy-avatar-icon-private.h',
     'hdy-bidi-private.h',
     'hdy-carousel-box-private.h',
     'hdy-css-private.h',
diff --git a/src/hdy-avatar-icon-private.h b/src/hdy-avatar-icon-private.h
new file mode 100644
index 00000000..44532f93
--- /dev/null
+++ b/src/hdy-avatar-icon-private.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 Purism SPC
+ *
+ * Authors:
+ * Julian Sparber <julian sparber net>
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ *
+ */
+
+#pragma once
+
+#if !defined(_HANDY_INSIDE) && !defined(HANDY_COMPILATION)
+#error "Only <handy.h> can be included directly."
+#endif
+
+#include <gtk/gtk.h>
+
+#include "hdy-avatar.h"
+
+G_BEGIN_DECLS
+
+#define HDY_AVATAR_ICON_ERROR hdy_avatar_icon_error_quark()
+GQuark  hdy_avatar_icon_error_quark (void);
+#define HDY_AVATAR_ICON_ERROR_EMPTY 0
+
+#define HDY_TYPE_AVATAR_ICON (hdy_avatar_icon_get_type())
+
+G_DECLARE_FINAL_TYPE (HdyAvatarIcon, hdy_avatar_icon, HDY, AVATAR_ICON, GObject)
+
+HdyAvatarIcon *hdy_avatar_icon_new (HdyAvatarImageLoadFunc  load_image,
+                                    gpointer                user_data,
+                                    GDestroyNotify          destroy);
+
+G_END_DECLS
diff --git a/src/hdy-avatar-icon.c b/src/hdy-avatar-icon.c
new file mode 100644
index 00000000..8d8c883d
--- /dev/null
+++ b/src/hdy-avatar-icon.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2021 Purism SPC
+ *
+ * Authors:
+ * Julian Sparber <julian sparber net>
+ *
+ * SPDX-License-Identifier: LGPL-2.1+
+ *
+ */
+
+#include "config.h"
+
+#include "hdy-avatar-icon-private.h"
+
+G_DEFINE_QUARK (hdy-avatar-icon-error-quark, hdy_avatar_icon_error)
+
+struct _HdyAvatarIcon
+{
+  GObject parent_instance;
+
+  HdyAvatarImageLoadFunc load_image_func;
+  gpointer load_image_func_target;
+  GDestroyNotify load_image_func_target_destroy_notify;
+};
+
+static void hdy_avatar_icon_loadable_icon_iface_init (GLoadableIconIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (HdyAvatarIcon, hdy_avatar_icon, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_ICON,
+                                                NULL)
+                         G_IMPLEMENT_INTERFACE (G_TYPE_LOADABLE_ICON,
+                                                hdy_avatar_icon_loadable_icon_iface_init));
+
+static void
+hdy_avatar_icon_finalize (GObject *object)
+{
+  HdyAvatarIcon *self = HDY_AVATAR_ICON (object);
+
+  if (self->load_image_func_target_destroy_notify != NULL)
+    self->load_image_func_target_destroy_notify (self->load_image_func_target);
+
+  G_OBJECT_CLASS (hdy_avatar_icon_parent_class)->finalize (object);
+}
+
+static void
+hdy_avatar_icon_class_init (HdyAvatarIconClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = hdy_avatar_icon_finalize;
+}
+
+static void
+hdy_avatar_icon_init (HdyAvatarIcon *file)
+{
+}
+
+HdyAvatarIcon *
+hdy_avatar_icon_new (HdyAvatarImageLoadFunc load_image,
+                     gpointer               user_data,
+                     GDestroyNotify         destroy)
+{
+  HdyAvatarIcon *self;
+
+  g_return_val_if_fail (user_data != NULL || (user_data == NULL && destroy == NULL), NULL);
+
+  self = g_object_new (HDY_TYPE_AVATAR_ICON, NULL);
+
+  self->load_image_func = load_image;
+  self->load_image_func_target = user_data;
+  self->load_image_func_target_destroy_notify = destroy;
+
+  return self;
+}
+
+static void
+load_pixbuf_cb (GObject      *source_object,
+                GAsyncResult *res,
+                gpointer      data)
+{
+  g_autoptr (GTask) task = G_TASK (data);
+  g_autoptr (GError) error = NULL;
+  g_autoptr (GInputStream) stream = NULL;
+
+  if (g_task_return_error_if_cancelled (task))
+    return;
+
+  stream = g_loadable_icon_load_finish (G_LOADABLE_ICON (source_object), res, NULL, &error);
+
+  if (stream == NULL) {
+    g_task_return_error (task, g_steal_pointer (&error));
+
+    return;
+  }
+
+  g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
+}
+
+static void
+hdy_avatar_icon_load_async (GLoadableIcon       *icon,
+                            int                  size,
+                            GCancellable        *cancellable,
+                            GAsyncReadyCallback  callback,
+                            gpointer             user_data)
+{
+  HdyAvatarIcon *self;
+  g_autoptr (GTask) task = NULL;
+  g_autoptr (GdkPixbuf) pixbuf = NULL;
+  g_return_if_fail (HDY_IS_AVATAR_ICON (icon));
+
+  self = HDY_AVATAR_ICON (icon);
+
+  task = g_task_new (self,
+                     cancellable,
+                     callback,
+                     user_data);
+
+  if (self->load_image_func)
+    pixbuf = self->load_image_func (size, self->load_image_func_target);
+
+  if (pixbuf) {
+    g_loadable_icon_load_async (G_LOADABLE_ICON (pixbuf),
+                                size,
+                                cancellable,
+                                load_pixbuf_cb,
+                                g_steal_pointer (&task));
+  } else {
+    g_task_return_new_error (task,
+                             HDY_AVATAR_ICON_ERROR,
+                             HDY_AVATAR_ICON_ERROR_EMPTY,
+                             "No pixbuf set");
+  }
+}
+
+static GInputStream *
+hdy_avatar_icon_load_finish (GLoadableIcon  *icon,
+                             GAsyncResult   *res,
+                             char          **type,
+                             GError        **error)
+{
+  g_return_val_if_fail (g_task_is_valid (res, icon), NULL);
+
+  return g_task_propagate_pointer (G_TASK (res), error);
+}
+
+static void
+hdy_avatar_icon_loadable_icon_iface_init (GLoadableIconIface *iface)
+{
+  iface->load_async = hdy_avatar_icon_load_async;
+  iface->load_finish = hdy_avatar_icon_load_finish;
+}
diff --git a/src/meson.build b/src/meson.build
index 9bf71a26..e2f3241f 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -125,6 +125,7 @@ src_sources = [
   'hdy-animation.c',
   'hdy-application-window.c',
   'hdy-avatar.c',
+  'hdy-avatar-icon.c',
   'hdy-bidi.c',
   'hdy-carousel.c',
   'hdy-carousel-box.c',


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