[gtk/wip/otte/listview: 184/215] columnview: Add listitems for the columns
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/listview: 184/215] columnview: Add listitems for the columns
- Date: Tue, 26 Nov 2019 03:14:01 +0000 (UTC)
commit 6550d7aed00ae9215ae730fbd7837826a5fc4689
Author: Benjamin Otte <otte redhat com>
Date: Wed Oct 30 18:03:23 2019 +0100
columnview: Add listitems for the columns
They are not aligned in columns yet, but they do exist.
gtk/gtkcolumnlistitemfactory.c | 178 ++++++++++++++++++++++++++++++++++
gtk/gtkcolumnlistitemfactoryprivate.h | 62 ++++++++++++
gtk/gtkcolumnview.c | 70 +++++++++++--
gtk/gtkcolumnviewprivate.h | 35 +++++++
gtk/gtklistitem.c | 1 +
gtk/meson.build | 1 +
testsuite/gtk/defaultvalue.c | 4 +
7 files changed, 343 insertions(+), 8 deletions(-)
---
diff --git a/gtk/gtkcolumnlistitemfactory.c b/gtk/gtkcolumnlistitemfactory.c
new file mode 100644
index 0000000000..6f14363c06
--- /dev/null
+++ b/gtk/gtkcolumnlistitemfactory.c
@@ -0,0 +1,178 @@
+/*
+ * 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 "gtkcolumnlistitemfactoryprivate.h"
+
+#include "gtkboxlayout.h"
+#include "gtkcolumnviewcolumnprivate.h"
+#include "gtklistitemfactoryprivate.h"
+#include "gtklistitemprivate.h"
+
+struct _GtkColumnListItemFactory
+{
+ GtkListItemFactory parent_instance;
+
+ GtkColumnView *view; /* no reference, the view references us */
+};
+
+struct _GtkColumnListItemFactoryClass
+{
+ GtkListItemFactoryClass parent_class;
+};
+
+G_DEFINE_TYPE (GtkColumnListItemFactory, gtk_column_list_item_factory, GTK_TYPE_LIST_ITEM_FACTORY)
+
+static GtkListItemWidget *
+get_nth_child (GtkListItemWidget *parent,
+ guint pos)
+{
+ GtkWidget *child;
+ guint i;
+
+ child = gtk_widget_get_first_child (GTK_WIDGET (parent));
+ for (i = 1; i < pos && child; i++)
+ child = gtk_widget_get_next_sibling (child);
+
+ return GTK_LIST_ITEM_WIDGET (child);
+}
+
+static void
+gtk_column_list_item_factory_setup (GtkListItemFactory *factory,
+ GtkListItemWidget *widget,
+ GtkListItem *list_item)
+{
+ GtkColumnListItemFactory *self = GTK_COLUMN_LIST_ITEM_FACTORY (factory);
+ GListModel *columns;
+ guint i;
+
+ gtk_widget_set_layout_manager (GTK_WIDGET (list_item->owner),
+ gtk_box_layout_new (GTK_ORIENTATION_HORIZONTAL));
+
+ GTK_LIST_ITEM_FACTORY_CLASS (gtk_column_list_item_factory_parent_class)->setup (factory, widget,
list_item);
+
+ columns = gtk_column_view_get_columns (self->view);
+
+ for (i = 0; i < g_list_model_get_n_items (columns); i++)
+ {
+ GtkColumnViewColumn *column = g_list_model_get_item (columns, i);
+
+ gtk_column_list_item_factory_add_column (self,
+ list_item->owner,
+ column,
+ FALSE);
+ }
+}
+
+static void
+gtk_column_list_item_factory_teardown (GtkListItemFactory *factory,
+ GtkListItemWidget *widget,
+ GtkListItem *list_item)
+{
+ GtkWidget *child;
+
+ GTK_LIST_ITEM_FACTORY_CLASS (gtk_column_list_item_factory_parent_class)->teardown (factory, widget,
list_item);
+
+ for (child = gtk_widget_get_first_child (GTK_WIDGET (list_item->owner));
+ child;
+ child = gtk_widget_get_first_child (GTK_WIDGET (list_item->owner)))
+ {
+ gtk_list_item_widget_remove_child (list_item->owner, child);
+ }
+}
+
+static void
+gtk_column_list_item_factory_update (GtkListItemFactory *factory,
+ GtkListItemWidget *widget,
+ GtkListItem *list_item,
+ guint position,
+ gpointer item,
+ gboolean selected)
+{
+ GtkWidget *child;
+
+ GTK_LIST_ITEM_FACTORY_CLASS (gtk_column_list_item_factory_parent_class)->update (factory, widget,
list_item, position, item, selected);
+
+ for (child = gtk_widget_get_first_child (GTK_WIDGET (widget));
+ child;
+ child = gtk_widget_get_next_sibling (child))
+ {
+ gtk_list_item_widget_update (GTK_LIST_ITEM_WIDGET (child), position, item, selected);
+ }
+}
+
+static void
+gtk_column_list_item_factory_class_init (GtkColumnListItemFactoryClass *klass)
+{
+ GtkListItemFactoryClass *factory_class = GTK_LIST_ITEM_FACTORY_CLASS (klass);
+
+ factory_class->setup = gtk_column_list_item_factory_setup;
+ factory_class->teardown = gtk_column_list_item_factory_teardown;
+ factory_class->update = gtk_column_list_item_factory_update;
+}
+
+static void
+gtk_column_list_item_factory_init (GtkColumnListItemFactory *self)
+{
+}
+
+GtkColumnListItemFactory *
+gtk_column_list_item_factory_new (GtkColumnView *view)
+{
+ GtkColumnListItemFactory *result;
+
+ result = g_object_new (GTK_TYPE_COLUMN_LIST_ITEM_FACTORY, NULL);
+
+ result->view = view;
+
+ return result;
+}
+
+void
+gtk_column_list_item_factory_add_column (GtkColumnListItemFactory *factory,
+ GtkListItemWidget *list_item,
+ GtkColumnViewColumn *column,
+ gboolean check_bind)
+{
+ GtkListItemFactory *column_factory;
+ GtkWidget *cell;
+
+ column_factory = gtk_column_view_column_get_factory (column);
+
+ cell = gtk_list_item_widget_new (column_factory, "cell");
+ gtk_list_item_widget_add_child (GTK_LIST_ITEM_WIDGET (list_item), GTK_WIDGET (cell));
+ gtk_list_item_widget_update (GTK_LIST_ITEM_WIDGET (cell),
+ gtk_list_item_widget_get_position (list_item),
+ gtk_list_item_widget_get_item (list_item),
+ gtk_list_item_widget_get_selected (list_item));
+}
+
+void
+gtk_column_list_item_factory_remove_column (GtkColumnListItemFactory *factory,
+ GtkListItemWidget *list_item,
+ guint col_pos,
+ GtkColumnViewColumn *column)
+{
+ GtkListItemWidget *cell;
+
+ cell = get_nth_child (list_item, col_pos);
+
+ gtk_list_item_widget_remove_child (GTK_LIST_ITEM_WIDGET (list_item), GTK_WIDGET (cell));
+}
diff --git a/gtk/gtkcolumnlistitemfactoryprivate.h b/gtk/gtkcolumnlistitemfactoryprivate.h
new file mode 100644
index 0000000000..557ca11875
--- /dev/null
+++ b/gtk/gtkcolumnlistitemfactoryprivate.h
@@ -0,0 +1,62 @@
+/*
+ * 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_COLUMN_LIST_ITEM_FACTORY_H__
+#define __GTK_COLUMN_LIST_ITEM_FACTORY_H__
+
+#include <gtk/gtklistitemwidgetprivate.h>
+#include <gtk/gtkcolumnview.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_COLUMN_LIST_ITEM_FACTORY (gtk_column_list_item_factory_get_type ())
+#define GTK_COLUMN_LIST_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o),
GTK_TYPE_COLUMN_LIST_ITEM_FACTORY, GtkColumnListItemFactory))
+#define GTK_COLUMN_LIST_ITEM_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k),
GTK_TYPE_COLUMN_LIST_ITEM_FACTORY, GtkColumnListItemFactoryClass))
+#define GTK_IS_COLUMN_LIST_ITEM_FACTORY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o),
GTK_TYPE_COLUMN_LIST_ITEM_FACTORY))
+#define GTK_IS_COLUMN_LIST_ITEM_FACTORY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k),
GTK_TYPE_COLUMN_LIST_ITEM_FACTORY))
+#define GTK_COLUMN_LIST_ITEM_FACTORY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o),
GTK_TYPE_COLUMN_LIST_ITEM_FACTORY, GtkColumnListItemFactoryClass))
+
+/**
+ * GtkColumnListItemFactory:
+ *
+ * The object for the #GtkColumnListItemFactory.
+ **/
+typedef struct _GtkColumnListItemFactory GtkColumnListItemFactory;
+typedef struct _GtkColumnListItemFactoryClass GtkColumnListItemFactoryClass;
+
+
+GType gtk_column_list_item_factory_get_type (void) G_GNUC_CONST;
+
+GtkColumnListItemFactory *
+ gtk_column_list_item_factory_new (GtkColumnView *view);
+
+void gtk_column_list_item_factory_add_column (GtkColumnListItemFactory *factory,
+ GtkListItemWidget *list_item,
+ GtkColumnViewColumn *column,
+ gboolean check_bind);
+void gtk_column_list_item_factory_remove_column
+ (GtkColumnListItemFactory *factory,
+ GtkListItemWidget *list_item,
+ guint col_pos,
+ GtkColumnViewColumn *column);
+
+
+G_END_DECLS
+
+#endif /* __GTK_COLUMN_LIST_ITEM_FACTORY_H__ */
diff --git a/gtk/gtkcolumnview.c b/gtk/gtkcolumnview.c
index 14dec39135..0b96f295e3 100644
--- a/gtk/gtkcolumnview.c
+++ b/gtk/gtkcolumnview.c
@@ -19,10 +19,11 @@
#include "config.h"
-#include "gtkcolumnview.h"
+#include "gtkcolumnviewprivate.h"
#include "gtkboxlayout.h"
#include "gtkbuildable.h"
+#include "gtkcolumnlistitemfactoryprivate.h"
#include "gtkcolumnviewcolumnprivate.h"
#include "gtkintl.h"
#include "gtklistview.h"
@@ -47,6 +48,7 @@ struct _GtkColumnView
GListStore *columns;
GtkListView *listview;
+ GtkColumnListItemFactory *factory;
};
struct _GtkColumnViewClass
@@ -102,12 +104,37 @@ gtk_column_view_buildable_interface_init (GtkBuildableIface *iface)
iface->add_child = gtk_column_view_buildable_add_child;
}
+
G_DEFINE_TYPE_WITH_CODE (GtkColumnView, gtk_column_view, GTK_TYPE_WIDGET,
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
gtk_column_view_buildable_interface_init))
static GParamSpec *properties[N_PROPS] = { NULL, };
static guint signals[LAST_SIGNAL] = { 0 };
+/* For now we do the iter with the children. We might switch that
+ * to use the item manager or track children directly in the factory
+ * later (depending on how code changes), so having this abstraction makes sense.
+ */
+GtkColumnViewIter *
+gtk_column_view_iter_init (GtkColumnView *self)
+{
+ return (GtkColumnViewIter *) gtk_widget_get_first_child (GTK_WIDGET (self->listview));
+}
+
+GtkWidget *
+gtk_column_view_iter_get_widget (GtkColumnView *self,
+ GtkColumnViewIter *iter)
+{
+ return GTK_WIDGET (iter);
+}
+
+GtkColumnViewIter *
+gtk_column_view_iter_next (GtkColumnView *self,
+ GtkColumnViewIter *iter)
+{
+ return (GtkColumnViewIter *) gtk_widget_get_next_sibling (GTK_WIDGET (iter));
+}
+
static void
gtk_column_view_activate_cb (GtkListView *listview,
guint pos,
@@ -129,6 +156,7 @@ gtk_column_view_dispose (GObject *object)
}
g_clear_pointer ((GtkWidget **) &self->listview, gtk_widget_unparent);
+ g_clear_object (&self->factory);
G_OBJECT_CLASS (gtk_column_view_parent_class)->dispose (object);
}
@@ -277,7 +305,11 @@ gtk_column_view_init (GtkColumnView *self)
{
self->columns = g_list_store_new (GTK_TYPE_COLUMN_VIEW_COLUMN);
- self->listview = GTK_LIST_VIEW (gtk_list_view_new ());
+ self->factory = gtk_column_list_item_factory_new (self);
+ self->listview = GTK_LIST_VIEW (gtk_list_view_new_with_factory (
+ GTK_LIST_ITEM_FACTORY (g_object_ref (self->factory))));
+ gtk_widget_set_hexpand (GTK_WIDGET (self->listview), TRUE);
+ gtk_widget_set_vexpand (GTK_WIDGET (self->listview), TRUE);
g_signal_connect (self->listview, "activate", G_CALLBACK (gtk_column_view_activate_cb), self);
gtk_widget_set_parent (GTK_WIDGET (self->listview), GTK_WIDGET (self));
}
@@ -409,12 +441,24 @@ void
gtk_column_view_append_column (GtkColumnView *self,
GtkColumnViewColumn *column)
{
+ GtkColumnViewIter *iter;
+
g_return_if_fail (GTK_IS_COLUMN_VIEW (self));
g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (column));
g_return_if_fail (gtk_column_view_column_get_column_view (column) == NULL);
gtk_column_view_column_set_column_view (column, self);
g_list_store_append (self->columns, column);
+
+ for (iter = gtk_column_view_iter_init (self);
+ iter != NULL;
+ iter = gtk_column_view_iter_next (self, iter))
+ {
+ gtk_column_list_item_factory_add_column (self->factory,
+ GTK_LIST_ITEM_WIDGET (gtk_column_view_iter_get_widget (self,
iter)),
+ column,
+ TRUE);
+ }
}
/**
@@ -428,6 +472,7 @@ void
gtk_column_view_remove_column (GtkColumnView *self,
GtkColumnViewColumn *column)
{
+ GtkColumnViewIter *iter;
guint i;
g_return_if_fail (GTK_IS_COLUMN_VIEW (self));
@@ -440,13 +485,22 @@ gtk_column_view_remove_column (GtkColumnView *self,
g_object_unref (item);
if (item == column)
- {
- gtk_column_view_column_set_column_view (column, NULL);
- g_list_store_remove (self->columns, i);
- return;
- }
+ break;
+ }
+
+ g_assert (i < g_list_model_get_n_items (G_LIST_MODEL (self->columns)));
+
+ for (iter = gtk_column_view_iter_init (self);
+ iter != NULL;
+ iter = gtk_column_view_iter_next (self, iter))
+ {
+ gtk_column_list_item_factory_remove_column (self->factory,
+ GTK_LIST_ITEM_WIDGET (gtk_column_view_iter_get_widget
(self, iter)),
+ i,
+ column);
}
- g_assert_not_reached ();
+ gtk_column_view_column_set_column_view (column, NULL);
+ g_list_store_remove (self->columns, i);
}
diff --git a/gtk/gtkcolumnviewprivate.h b/gtk/gtkcolumnviewprivate.h
new file mode 100644
index 0000000000..a4e0f17885
--- /dev/null
+++ b/gtk/gtkcolumnviewprivate.h
@@ -0,0 +1,35 @@
+/*
+ * 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_COLUMN_VIEW_PRIVATE_H__
+#define __GTK_COLUMN_VIEW_PRIVATE_H__
+
+#include "gtk/gtkcolumnview.h"
+
+/* This is really just a GtkListItemManagerItem for now, but
+ * proper layering ftw */
+typedef struct _GtkColumnViewIter GtkColumnViewIter;
+
+GtkColumnViewIter * gtk_column_view_iter_init (GtkColumnView *self);
+GtkWidget * gtk_column_view_iter_get_widget (GtkColumnView *self,
+ GtkColumnViewIter *iter);
+GtkColumnViewIter * gtk_column_view_iter_next (GtkColumnView *self,
+ GtkColumnViewIter *iter);
+
+#endif /* __GTK_COLUMN_VIEW_PRIVATE_H__ */
diff --git a/gtk/gtklistitem.c b/gtk/gtklistitem.c
index d5622bb6c4..ee132cbea9 100644
--- a/gtk/gtklistitem.c
+++ b/gtk/gtklistitem.c
@@ -321,6 +321,7 @@ gtk_list_item_set_child (GtkListItem *self,
{
g_object_ref_sink (child);
self->child = child;
+
if (self->owner)
gtk_list_item_widget_add_child (self->owner, child);
}
diff --git a/gtk/meson.build b/gtk/meson.build
index 24b3a4fab3..ea54b9203f 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -205,6 +205,7 @@ gtk_public_sources = files([
'gtkcolorchooserdialog.c',
'gtkcolorchooserwidget.c',
'gtkcolorutils.c',
+ 'gtkcolumnlistitemfactory.c',
'gtkcolumnview.c',
'gtkcolumnviewcolumn.c',
'gtkcombobox.c',
diff --git a/testsuite/gtk/defaultvalue.c b/testsuite/gtk/defaultvalue.c
index 4c79386cac..908d991dd3 100644
--- a/testsuite/gtk/defaultvalue.c
+++ b/testsuite/gtk/defaultvalue.c
@@ -226,6 +226,10 @@ test_type (gconstpointer data)
strcmp (pspec->name, "rgba") == 0))
continue;
+ if (g_type_is_a (type, GTK_TYPE_COLUMN_VIEW) &&
+ strcmp (pspec->name, "columns") == 0)
+ continue;
+
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
if (g_type_is_a (type, GTK_TYPE_COMBO_BOX) &&
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]