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.
This commit is contained in:
Benjamin Otte 2019-06-10 04:58:45 +02:00 committed by Matthias Clasen
parent 2227fb957f
commit cfb293d396
5 changed files with 219 additions and 1 deletions

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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

View File

@ -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,

View File

@ -165,6 +165,7 @@ gtk_public_sources = files([
'gtkbox.c',
'gtkbuildable.c',
'gtkbuilder.c',
'gtkbuilderlistitemfactory.c',
'gtkbuilderparser.c',
'gtkbuilderscope.c',
'gtkbutton.c',