summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2023-04-09 14:24:26 +0200
committerBenjamin Otte <otte@redhat.com>2023-05-09 17:00:40 +0200
commit38844fef4d798feb1908e341a7f69b600e4c7706 (patch)
tree96de4c03d65e8c250bc49733600b7760b907891e
parent03ac6611c1ec623aba3cab8cd1e50914d2099351 (diff)
downloadgtk+-38844fef4d798feb1908e341a7f69b600e4c7706.tar.gz
listitemmanager: Add GtkListHeaderBase and vfuncs
This is plumbing for section handling. The vfuncs don't do anything, this is just the infrastructure.
-rw-r--r--gtk/gtklistbase.c20
-rw-r--r--gtk/gtklistbaseprivate.h4
-rw-r--r--gtk/gtklistheaderbase.c105
-rw-r--r--gtk/gtklistheaderbaseprivate.h63
-rw-r--r--gtk/gtklistitemmanager.c14
-rw-r--r--gtk/gtklistitemmanagerprivate.h5
-rw-r--r--gtk/meson.build1
-rw-r--r--testsuite/gtk/listitemmanager.c27
8 files changed, 229 insertions, 10 deletions
diff --git a/gtk/gtklistbase.c b/gtk/gtklistbase.c
index 0a7dbb0b02..00ac9c571d 100644
--- a/gtk/gtklistbase.c
+++ b/gtk/gtklistbase.c
@@ -1959,12 +1959,26 @@ gtk_list_base_split_func (GtkWidget *widget,
}
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)
{
@@ -1973,7 +1987,9 @@ gtk_list_base_init_real (GtkListBase *self,
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;
diff --git a/gtk/gtklistbaseprivate.h b/gtk/gtklistbaseprivate.h
index 7aa596ffde..fad3872cdc 100644
--- a/gtk/gtklistbaseprivate.h
+++ b/gtk/gtklistbaseprivate.h
@@ -37,6 +37,10 @@ struct _GtkListBaseClass
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,
diff --git a/gtk/gtklistheaderbase.c b/gtk/gtklistheaderbase.c
new file mode 100644
index 0000000000..2ba119e665
--- /dev/null
+++ b/gtk/gtklistheaderbase.c
@@ -0,0 +1,105 @@
+/*
+ * 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;
+}
+
diff --git a/gtk/gtklistheaderbaseprivate.h b/gtk/gtklistheaderbaseprivate.h
new file mode 100644
index 0000000000..fa3fa45f22
--- /dev/null
+++ b/gtk/gtklistheaderbaseprivate.h
@@ -0,0 +1,63 @@
+/*
+ * 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
+
diff --git a/gtk/gtklistitemmanager.c b/gtk/gtklistitemmanager.c
index a9c15982b3..66ff55fedd 100644
--- a/gtk/gtklistitemmanager.c
+++ b/gtk/gtklistitemmanager.c
@@ -39,6 +39,8 @@ struct _GtkListItemManager
GtkListTile * (* split_func) (GtkWidget *, GtkListTile *, guint);
GtkListItemBase * (* create_widget) (GtkWidget *);
+ void (* prepare_section) (GtkWidget *, GtkListTile *, guint);
+ GtkListHeaderBase * (* create_header_widget) (GtkWidget *);
};
struct _GtkListItemManagerClass
@@ -156,9 +158,11 @@ gtk_list_item_manager_clear_node (gpointer _tile)
}
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;
@@ -170,6 +174,8 @@ gtk_list_item_manager_new (GtkWidget *widget,
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),
@@ -1141,6 +1147,8 @@ gtk_list_item_manager_insert_section (GtkListItemManager *self,
}
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);
diff --git a/gtk/gtklistitemmanagerprivate.h b/gtk/gtklistitemmanagerprivate.h
index 29d24a4925..cc92ef74a9 100644
--- a/gtk/gtklistitemmanagerprivate.h
+++ b/gtk/gtklistitemmanagerprivate.h
@@ -24,6 +24,7 @@
#include "gtk/gtkenums.h"
#include "gtk/gtklistitembaseprivate.h"
+#include "gtk/gtklistheaderbaseprivate.h"
#include "gtk/gtklistitemfactory.h"
#include "gtk/gtkrbtreeprivate.h"
#include "gtk/gtkselectionmodel.h"
@@ -79,7 +80,9 @@ GType gtk_list_item_manager_get_type (void) G_GNUC_CO
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);
diff --git a/gtk/meson.build b/gtk/meson.build
index 1ea9b37e25..9f6a6dd57c 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -271,6 +271,7 @@ gtk_public_sources = files([
'gtklinkbutton.c',
'gtklistbox.c',
'gtklistfactorywidget.c',
+ 'gtklistheaderbase.c',
'gtklistitem.c',
'gtklistitembase.c',
'gtklistitemfactory.c',
diff --git a/testsuite/gtk/listitemmanager.c b/testsuite/gtk/listitemmanager.c
index 828a281745..d883aca063 100644
--- a/testsuite/gtk/listitemmanager.c
+++ b/testsuite/gtk/listitemmanager.c
@@ -270,12 +270,25 @@ split_simple (GtkWidget *widget,
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)
{
@@ -285,7 +298,9 @@ 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));
@@ -302,7 +317,9 @@ test_create_with_items (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);
source = create_source_model (1, 50);
@@ -352,7 +369,9 @@ test_exhaustive (void)
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);