[gtk/wip/otte/listview: 63/150] listitemfactory: Add a factory for ui files



commit 1b0d8b68d9d6fced816e8643e4f83584b1f5914b
Author: Benjamin Otte <otte redhat com>
Date:   Mon Jun 10 04:58:45 2019 +0200

    listitemfactory: Add a factory for ui files
    
    Reuse <template> magic to initialize GtkListItems. This feels
    amazingly hacky, but it also amazingly worked on the first try.

 gtk/gtkbuilderlistitemfactory.c        | 136 +++++++++++++++++++++++++++++++++
 gtk/gtkbuilderlistitemfactoryprivate.h |  46 +++++++++++
 gtk/gtklistview.c                      |  31 +++++++-
 gtk/gtklistview.h                      |   6 ++
 gtk/meson.build                        |   1 +
 5 files changed, 219 insertions(+), 1 deletion(-)
---
diff --git a/gtk/gtkbuilderlistitemfactory.c b/gtk/gtkbuilderlistitemfactory.c
new file mode 100644
index 0000000000..eb8bf668da
--- /dev/null
+++ b/gtk/gtkbuilderlistitemfactory.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright © 2019 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#include "config.h"
+
+#include "gtkbuilderlistitemfactoryprivate.h"
+
+#include "gtkbuilder.h"
+#include "gtklistitemprivate.h"
+
+struct _GtkBuilderListItemFactory
+{
+  GtkListItemFactory parent_instance;
+
+  GBytes *bytes;
+};
+
+struct _GtkBuilderListItemFactoryClass
+{
+  GtkListItemFactoryClass parent_class;
+};
+
+G_DEFINE_TYPE (GtkBuilderListItemFactory, gtk_builder_list_item_factory, GTK_TYPE_LIST_ITEM_FACTORY)
+
+static void
+gtk_builder_list_item_factory_setup (GtkListItemFactory *factory,
+                                     GtkListItem        *list_item)
+{
+  GtkBuilderListItemFactory *self = GTK_BUILDER_LIST_ITEM_FACTORY (factory);
+  GtkBuilder *builder;
+  GError *error = NULL;
+
+  GTK_LIST_ITEM_FACTORY_CLASS (gtk_builder_list_item_factory_parent_class)->setup (factory, list_item);
+
+  builder = gtk_builder_new ();
+
+  gtk_builder_set_current_object (builder, G_OBJECT (list_item));
+
+  if (!gtk_builder_extend_with_template  (builder, GTK_WIDGET (list_item), G_OBJECT_TYPE (list_item),
+                                         (const gchar *)g_bytes_get_data (self->bytes, NULL),
+                                         g_bytes_get_size (self->bytes),
+                                         &error))
+    {
+      g_critical ("Error building template for list item: %s", error->message);
+      g_error_free (error);
+
+      /* This should never happen, if the template XML cannot be built
+       * then it is a critical programming error.
+       */
+      g_object_unref (builder);
+      return;
+    }
+
+  g_object_unref (builder);
+}
+
+static void
+gtk_builder_list_item_factory_finalize (GObject *object)
+{
+  GtkBuilderListItemFactory *self = GTK_BUILDER_LIST_ITEM_FACTORY (object);
+
+  g_bytes_unref (self->bytes);
+
+  G_OBJECT_CLASS (gtk_builder_list_item_factory_parent_class)->finalize (object);
+}
+
+static void
+gtk_builder_list_item_factory_class_init (GtkBuilderListItemFactoryClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkListItemFactoryClass *factory_class = GTK_LIST_ITEM_FACTORY_CLASS (klass);
+
+  object_class->finalize = gtk_builder_list_item_factory_finalize;
+
+  factory_class->setup = gtk_builder_list_item_factory_setup;
+}
+
+static void
+gtk_builder_list_item_factory_init (GtkBuilderListItemFactory *self)
+{
+}
+
+GtkListItemFactory *
+gtk_builder_list_item_factory_new_from_bytes (GBytes *bytes)
+{
+  GtkBuilderListItemFactory *self;
+
+  g_return_val_if_fail (bytes != NULL, NULL);
+
+  self = g_object_new (GTK_TYPE_BUILDER_LIST_ITEM_FACTORY, NULL);
+
+  self->bytes = g_bytes_ref (bytes);
+
+  return GTK_LIST_ITEM_FACTORY (self);
+}
+
+GtkListItemFactory *
+gtk_builder_list_item_factory_new_from_resource (const char *resource_path)
+{
+  GtkListItemFactory *result;
+  GError *error = NULL;
+  GBytes *bytes;
+
+  g_return_val_if_fail (resource_path != NULL, NULL);
+
+  bytes = g_resources_lookup_data (resource_path, 0, &error);
+  if (!bytes)
+    {
+      g_critical ("Unable to load resource for list item template: %s", error->message);
+      g_error_free (error);
+      return NULL;
+    }
+
+  result = gtk_builder_list_item_factory_new_from_bytes (bytes);
+
+  g_bytes_unref (bytes);
+
+  return result;
+}
+
diff --git a/gtk/gtkbuilderlistitemfactoryprivate.h b/gtk/gtkbuilderlistitemfactoryprivate.h
new file mode 100644
index 0000000000..b2cbf1b918
--- /dev/null
+++ b/gtk/gtkbuilderlistitemfactoryprivate.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2019 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+
+#ifndef __GTK_BUILDER_LIST_ITEM_FACTORY_H__
+#define __GTK_BUILDER_LIST_ITEM_FACTORY_H__
+
+#include "gtklistitemfactoryprivate.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_BUILDER_LIST_ITEM_FACTORY         (gtk_builder_list_item_factory_get_type ())
+#define GTK_BUILDER_LIST_ITEM_FACTORY(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), 
GTK_TYPE_BUILDER_LIST_ITEM_FACTORY, GtkBuilderListItemFactory))
+#define GTK_BUILDER_LIST_ITEM_FACTORY_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), 
GTK_TYPE_BUILDER_LIST_ITEM_FACTORY, GtkBuilderListItemFactoryClass))
+#define GTK_IS_BUILDER_LIST_ITEM_FACTORY(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), 
GTK_TYPE_BUILDER_LIST_ITEM_FACTORY))
+#define GTK_IS_BUILDER_LIST_ITEM_FACTORY_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), 
GTK_TYPE_BUILDER_LIST_ITEM_FACTORY))
+#define GTK_BUILDER_LIST_ITEM_FACTORY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), 
GTK_TYPE_BUILDER_LIST_ITEM_FACTORY, GtkBuilderListItemFactoryClass))
+
+typedef struct _GtkBuilderListItemFactory GtkBuilderListItemFactory;
+typedef struct _GtkBuilderListItemFactoryClass GtkBuilderListItemFactoryClass;
+
+GType                   gtk_builder_list_item_factory_get_type          (void) G_GNUC_CONST;
+
+GtkListItemFactory *    gtk_builder_list_item_factory_new_from_bytes    (GBytes         *bytes);
+GtkListItemFactory *    gtk_builder_list_item_factory_new_from_resource (const char     *resource_path);
+
+
+G_END_DECLS
+
+#endif /* __GTK_BUILDER_LIST_ITEM_FACTORY_H__ */
diff --git a/gtk/gtklistview.c b/gtk/gtklistview.c
index 589acc8239..63f34f455a 100644
--- a/gtk/gtklistview.c
+++ b/gtk/gtklistview.c
@@ -22,8 +22,9 @@
 #include "gtklistview.h"
 
 #include "gtkadjustment.h"
-#include "gtkintl.h"
+#include "gtkbuilderlistitemfactoryprivate.h"
 #include "gtkfunctionslistitemfactoryprivate.h"
+#include "gtkintl.h"
 #include "gtklistitemmanagerprivate.h"
 #include "gtkrbtreeprivate.h"
 #include "gtkscrollable.h"
@@ -920,6 +921,34 @@ gtk_list_view_set_functions (GtkListView          *self,
   g_object_unref (factory);
 }
 
+void
+gtk_list_view_set_factory_from_bytes (GtkListView *self,
+                                      GBytes      *bytes)
+{
+  GtkListItemFactory *factory;
+
+  g_return_if_fail (GTK_IS_LIST_VIEW (self));
+  g_return_if_fail (bytes != NULL);
+
+  factory = gtk_builder_list_item_factory_new_from_bytes (bytes);
+  gtk_list_item_manager_set_factory (self->item_manager, factory);
+  g_object_unref (factory);
+}
+
+void
+gtk_list_view_set_factory_from_resource (GtkListView *self,
+                                         const char  *resource_path)
+{
+  GtkListItemFactory *factory;
+
+  g_return_if_fail (GTK_IS_LIST_VIEW (self));
+  g_return_if_fail (resource_path != NULL);
+
+  factory = gtk_builder_list_item_factory_new_from_resource (resource_path);
+  gtk_list_item_manager_set_factory (self->item_manager, factory);
+  g_object_unref (factory);
+}
+
 /**
  * gtk_list_view_set_show_separators:
  * @self: a #GtkListView
diff --git a/gtk/gtklistview.h b/gtk/gtklistview.h
index 77d8d502ab..f953c360ab 100644
--- a/gtk/gtklistview.h
+++ b/gtk/gtklistview.h
@@ -48,6 +48,12 @@ void            gtk_list_view_set_functions                     (GtkListView
                                                                  GtkListItemBindFunc     bind_func,
                                                                  gpointer                user_data,
                                                                  GDestroyNotify          user_destroy);
+GDK_AVAILABLE_IN_ALL
+void            gtk_list_view_set_factory_from_bytes            (GtkListView            *self,
+                                                                 GBytes                 *bytes);
+GDK_AVAILABLE_IN_ALL
+void            gtk_list_view_set_factory_from_resource         (GtkListView            *self,
+                                                                 const char             *resource_path);
 
 GDK_AVAILABLE_IN_ALL
 void            gtk_list_view_set_show_separators               (GtkListView            *self,
diff --git a/gtk/meson.build b/gtk/meson.build
index 1cde5bc1db..6e10595901 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -177,6 +177,7 @@ gtk_public_sources = files([
   'gtkbox.c',
   'gtkbuildable.c',
   'gtkbuilder.c',
+  'gtkbuilderlistitemfactory.c',
   'gtkbuilderparser.c',
   'gtkbuilderscope.c',
   'gtkbutton.c',


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