This is plumbing for section handling.
The vfuncs don't do anything, this is just the infrastructure.
}
static GtkListItemBase *
-gtk_list_base_create_widget_func (GtkWidget *widget)
+gtk_list_base_create_list_widget_func (GtkWidget *widget)
{
return GTK_LIST_BASE_GET_CLASS (widget)->create_list_widget (GTK_LIST_BASE (widget));
}
+static void
+gtk_list_base_prepare_section_func (GtkWidget *widget,
+ GtkListTile *tile,
+ guint pos)
+{
+ GTK_LIST_BASE_GET_CLASS (widget)->prepare_section (GTK_LIST_BASE (widget), tile, pos);
+}
+
+static GtkListHeaderBase *
+gtk_list_base_create_header_widget_func (GtkWidget *widget)
+{
+ return GTK_LIST_BASE_GET_CLASS (widget)->create_header_widget (GTK_LIST_BASE (widget));
+}
+
static void
gtk_list_base_init_real (GtkListBase *self,
GtkListBaseClass *g_class)
priv->item_manager = gtk_list_item_manager_new (GTK_WIDGET (self),
gtk_list_base_split_func,
- gtk_list_base_create_widget_func);
+ gtk_list_base_create_list_widget_func,
+ gtk_list_base_prepare_section_func,
+ gtk_list_base_create_header_widget_func);
priv->anchor = gtk_list_item_tracker_new (priv->item_manager);
priv->anchor_side_along = GTK_PACK_START;
priv->anchor_side_across = GTK_PACK_START;
GtkListTile *tile,
guint n_items);
GtkListItemBase * (* create_list_widget) (GtkListBase *self);
+ void (* prepare_section) (GtkListBase *self,
+ GtkListTile *tile,
+ guint position);
+ GtkListHeaderBase * (* create_header_widget) (GtkListBase *self);
gboolean (* get_allocation) (GtkListBase *self,
guint pos,
--- /dev/null
+/*
+ * Copyright © 2023 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 "gtklistheaderbaseprivate.h"
+
+typedef struct _GtkListHeaderBasePrivate GtkListHeaderBasePrivate;
+struct _GtkListHeaderBasePrivate
+{
+ GObject *item;
+ guint start;
+ guint end;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkListHeaderBase, gtk_list_header_base, GTK_TYPE_WIDGET)
+
+static void
+gtk_list_header_base_default_update (GtkListHeaderBase *self,
+ gpointer item,
+ guint start,
+ guint end)
+{
+ GtkListHeaderBasePrivate *priv = gtk_list_header_base_get_instance_private (self);
+
+ g_set_object (&priv->item, item);
+ priv->start = start;
+ priv->end = end;
+}
+
+static void
+gtk_list_header_base_dispose (GObject *object)
+{
+ GtkListHeaderBase *self = GTK_LIST_HEADER_BASE (object);
+ GtkListHeaderBasePrivate *priv = gtk_list_header_base_get_instance_private (self);
+
+ g_clear_object (&priv->item);
+
+ G_OBJECT_CLASS (gtk_list_header_base_parent_class)->dispose (object);
+}
+
+static void
+gtk_list_header_base_class_init (GtkListHeaderBaseClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ klass->update = gtk_list_header_base_default_update;
+
+ gobject_class->dispose = gtk_list_header_base_dispose;
+}
+
+static void
+gtk_list_header_base_init (GtkListHeaderBase *self)
+{
+}
+
+void
+gtk_list_header_base_update (GtkListHeaderBase *self,
+ gpointer item,
+ guint start,
+ guint end)
+{
+ GTK_LIST_HEADER_BASE_GET_CLASS (self)->update (self, item, start, end);
+}
+
+guint
+gtk_list_header_base_get_start (GtkListHeaderBase *self)
+{
+ GtkListHeaderBasePrivate *priv = gtk_list_header_base_get_instance_private (self);
+
+ return priv->start;
+}
+
+guint
+gtk_list_header_base_get_end (GtkListHeaderBase *self)
+{
+ GtkListHeaderBasePrivate *priv = gtk_list_header_base_get_instance_private (self);
+
+ return priv->end;
+}
+
+gpointer
+gtk_list_header_base_get_item (GtkListHeaderBase *self)
+{
+ GtkListHeaderBasePrivate *priv = gtk_list_header_base_get_instance_private (self);
+
+ return priv->item;
+}
+
--- /dev/null
+/*
+ * Copyright © 2023 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>
+ */
+
+#pragma once
+
+#include "gtkwidget.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_LIST_HEADER_BASE (gtk_list_header_base_get_type ())
+#define GTK_LIST_HEADER_BASE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_LIST_HEADER_BASE, GtkListHeaderBase))
+#define GTK_LIST_HEADER_BASE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_LIST_HEADER_BASE, GtkListHeaderBaseClass))
+#define GTK_IS_LIST_HEADER_BASE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_LIST_HEADER_BASE))
+#define GTK_IS_LIST_HEADER_BASE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_LIST_HEADER_BASE))
+#define GTK_LIST_HEADER_BASE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_LIST_HEADER_BASE, GtkListHeaderBaseClass))
+
+typedef struct _GtkListHeaderBase GtkListHeaderBase;
+typedef struct _GtkListHeaderBaseClass GtkListHeaderBaseClass;
+
+struct _GtkListHeaderBase
+{
+ GtkWidget parent_instance;
+};
+
+struct _GtkListHeaderBaseClass
+{
+ GtkWidgetClass parent_class;
+
+ void (* update) (GtkListHeaderBase *self,
+ gpointer item,
+ guint start,
+ guint end);
+};
+
+GType gtk_list_header_base_get_type (void) G_GNUC_CONST;
+
+void gtk_list_header_base_update (GtkListHeaderBase *self,
+ gpointer item,
+ guint start,
+ guint end);
+
+guint gtk_list_header_base_get_start (GtkListHeaderBase *self);
+guint gtk_list_header_base_get_end (GtkListHeaderBase *self);
+gpointer gtk_list_header_base_get_item (GtkListHeaderBase *self);
+
+G_END_DECLS
+
GtkListTile * (* split_func) (GtkWidget *, GtkListTile *, guint);
GtkListItemBase * (* create_widget) (GtkWidget *);
+ void (* prepare_section) (GtkWidget *, GtkListTile *, guint);
+ GtkListHeaderBase * (* create_header_widget) (GtkWidget *);
};
struct _GtkListItemManagerClass
}
GtkListItemManager *
-gtk_list_item_manager_new (GtkWidget *widget,
- GtkListTile * (* split_func) (GtkWidget *, GtkListTile *, guint),
- GtkListItemBase * (* create_widget) (GtkWidget *))
+gtk_list_item_manager_new (GtkWidget *widget,
+ GtkListTile * (* split_func) (GtkWidget *, GtkListTile *, guint),
+ GtkListItemBase * (* create_widget) (GtkWidget *),
+ void (* prepare_section) (GtkWidget *, GtkListTile *, guint),
+ GtkListHeaderBase * (* create_header_widget) (GtkWidget *))
{
GtkListItemManager *self;
self->widget = widget;
self->split_func = split_func;
self->create_widget = create_widget;
+ self->prepare_section = prepare_section;
+ self->create_header_widget = create_header_widget;
self->items = gtk_rb_tree_new_for_size (sizeof (GtkListTile),
sizeof (GtkListTileAugment),
}
else
{
+ self->prepare_section (self->widget, tile, pos);
+
other = gtk_rb_tree_insert_before (self->items, tile);
gtk_list_tile_set_type (other, header_type);
other = gtk_rb_tree_insert_before (self->items, other);
#include "gtk/gtkenums.h"
#include "gtk/gtklistitembaseprivate.h"
+#include "gtk/gtklistheaderbaseprivate.h"
#include "gtk/gtklistitemfactory.h"
#include "gtk/gtkrbtreeprivate.h"
#include "gtk/gtkselectionmodel.h"
GtkListItemManager * gtk_list_item_manager_new (GtkWidget *widget,
GtkListTile * (* split_func) (GtkWidget *, GtkListTile *, guint),
- GtkListItemBase * (* create_widget) (GtkWidget *));
+ GtkListItemBase * (* create_widget) (GtkWidget *),
+ void (* prepare_section) (GtkWidget *, GtkListTile *, guint),
+ GtkListHeaderBase * (* create_header_widget) (GtkWidget *));
void gtk_list_item_manager_get_tile_bounds (GtkListItemManager *self,
GdkRectangle *out_bounds);
'gtklinkbutton.c',
'gtklistbox.c',
'gtklistfactorywidget.c',
+ 'gtklistheaderbase.c',
'gtklistitem.c',
'gtklistitembase.c',
'gtklistitemfactory.c',
return gtk_list_tile_split (items, tile, n_items);
}
+static void
+prepare_simple (GtkWidget *widget,
+ GtkListTile *tile,
+ guint n_items)
+{
+}
+
static GtkListItemBase *
-create_simple (GtkWidget *widget)
+create_simple_item (GtkWidget *widget)
{
return g_object_new (GTK_TYPE_LIST_ITEM_BASE, NULL);
}
+static GtkListHeaderBase *
+create_simple_header (GtkWidget *widget)
+{
+ return g_object_new (GTK_TYPE_LIST_HEADER_BASE, NULL);
+}
+
static void
test_create (void)
{
widget = gtk_window_new ();
items = gtk_list_item_manager_new (widget,
split_simple,
- create_simple);
+ create_simple_item,
+ prepare_simple,
+ create_simple_header);
g_object_set_data_full (G_OBJECT (widget), "the-items", items, g_object_unref);
gtk_window_destroy (GTK_WINDOW (widget));
widget = gtk_window_new ();
items = gtk_list_item_manager_new (widget,
split_simple,
- create_simple);
+ create_simple_item,
+ prepare_simple,
+ create_simple_header);
g_object_set_data_full (G_OBJECT (widget), "the-items", items, g_object_unref);
source = create_source_model (1, 50);
widget = gtk_window_new ();
items = gtk_list_item_manager_new (widget,
split_simple,
- create_simple);
+ create_simple_item,
+ prepare_simple,
+ create_simple_header);
for (i = 0; i < N_TRACKERS; i++)
trackers[i] = gtk_list_item_tracker_new (items);