From 002fafc160f9e05a47188b78052497a2dd5a703e Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 28 Oct 2019 20:50:49 +0100 Subject: [PATCH] columnview: Allow adding/removing columns ... and make that work in UI files via , too. --- gtk/gtkcolumnview.c | 100 ++++++++++++++++++++++++++++++- gtk/gtkcolumnview.h | 7 +++ gtk/gtkcolumnviewcolumn.c | 14 ++++- gtk/gtkcolumnviewcolumnprivate.h | 29 +++++++++ 4 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 gtk/gtkcolumnviewcolumnprivate.h diff --git a/gtk/gtkcolumnview.c b/gtk/gtkcolumnview.c index 63124085b5..14dec39135 100644 --- a/gtk/gtkcolumnview.c +++ b/gtk/gtkcolumnview.c @@ -22,7 +22,8 @@ #include "gtkcolumnview.h" #include "gtkboxlayout.h" -#include "gtkcolumnviewcolumn.h" +#include "gtkbuildable.h" +#include "gtkcolumnviewcolumnprivate.h" #include "gtkintl.h" #include "gtklistview.h" #include "gtkmain.h" @@ -68,7 +69,41 @@ enum { LAST_SIGNAL }; -G_DEFINE_TYPE (GtkColumnView, gtk_column_view, GTK_TYPE_WIDGET) +static GtkBuildableIface *parent_buildable_iface; + +static void +gtk_column_view_buildable_add_child (GtkBuildable *buildable, + GtkBuilder *builder, + GObject *child, + const gchar *type) +{ + if (GTK_IS_COLUMN_VIEW_COLUMN (child)) + { + if (type != NULL) + { + GTK_BUILDER_WARN_INVALID_CHILD_TYPE (buildable, type); + } + else + { + gtk_column_view_append_column (GTK_COLUMN_VIEW (buildable), + GTK_COLUMN_VIEW_COLUMN (child)); + } + } + else + { + parent_buildable_iface->add_child (buildable, builder, child, type); + } +} + +static void +gtk_column_view_buildable_interface_init (GtkBuildableIface *iface) +{ + parent_buildable_iface = g_type_interface_peek_parent (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 }; @@ -86,7 +121,12 @@ gtk_column_view_dispose (GObject *object) { GtkColumnView *self = GTK_COLUMN_VIEW (object); - g_list_store_remove_all (self->columns); + while (g_list_model_get_n_items (G_LIST_MODEL (self->columns)) > 0) + { + GtkColumnViewColumn *column = g_list_model_get_item (G_LIST_MODEL (self->columns), 0); + gtk_column_view_remove_column (self, column); + g_object_unref (column); + } g_clear_pointer ((GtkWidget **) &self->listview, gtk_widget_unparent); @@ -356,3 +396,57 @@ gtk_column_view_get_show_separators (GtkColumnView *self) return gtk_list_view_get_show_separators (self->listview); } + +/** + * gtk_column_view_append_column: + * @self: a #GtkColumnView + * @column: a #GtkColumnViewColumn that hasn't been added to a + * #GtkColumnView yet + * + * Appends the @column to the end of the columns in @self. + **/ +void +gtk_column_view_append_column (GtkColumnView *self, + GtkColumnViewColumn *column) +{ + 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); +} + +/** + * gtk_column_view_remove_column: + * @self: a #GtkColumnView + * @column: a #GtkColumnViewColumn that's part of @self + * + * Removes the @column from the list of columns of @self. + **/ +void +gtk_column_view_remove_column (GtkColumnView *self, + GtkColumnViewColumn *column) +{ + guint i; + + 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) == self); + + for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (self->columns)); i++) + { + GtkColumnViewColumn *item = g_list_model_get_item (G_LIST_MODEL (self->columns), i); + + g_object_unref (item); + if (item == column) + { + gtk_column_view_column_set_column_view (column, NULL); + g_list_store_remove (self->columns, i); + return; + } + } + + g_assert_not_reached (); +} + diff --git a/gtk/gtkcolumnview.h b/gtk/gtkcolumnview.h index 2781c84052..a4ac08a8b1 100644 --- a/gtk/gtkcolumnview.h +++ b/gtk/gtkcolumnview.h @@ -53,6 +53,13 @@ GtkWidget * gtk_column_view_new (void); GDK_AVAILABLE_IN_ALL GListModel * gtk_column_view_get_columns (GtkColumnView *self); +GDK_AVAILABLE_IN_ALL +void gtk_column_view_append_column (GtkColumnView *self, + GtkColumnViewColumn *column); +GDK_AVAILABLE_IN_ALL +void gtk_column_view_remove_column (GtkColumnView *self, + GtkColumnViewColumn *column); + GDK_AVAILABLE_IN_ALL GListModel * gtk_column_view_get_model (GtkColumnView *self); GDK_AVAILABLE_IN_ALL diff --git a/gtk/gtkcolumnviewcolumn.c b/gtk/gtkcolumnviewcolumn.c index c44beecd6b..444cb54cb7 100644 --- a/gtk/gtkcolumnviewcolumn.c +++ b/gtk/gtkcolumnviewcolumn.c @@ -19,7 +19,7 @@ #include "config.h" -#include "gtkcolumnviewcolumn.h" +#include "gtkcolumnviewcolumnprivate.h" #include "gtkintl.h" #include "gtklistbaseprivate.h" @@ -259,6 +259,18 @@ gtk_column_view_column_get_column_view (GtkColumnViewColumn *self) return self->view; } +void +gtk_column_view_column_set_column_view (GtkColumnViewColumn *self, + GtkColumnView *view) +{ + if (self->view == view) + return; + + self->view = view; + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COLUMN_VIEW]); +} + /** * gtk_column_view_column_get_factory: * @self: a #GtkColumnViewColumn diff --git a/gtk/gtkcolumnviewcolumnprivate.h b/gtk/gtkcolumnviewcolumnprivate.h new file mode 100644 index 0000000000..fcdcdaaf1a --- /dev/null +++ b/gtk/gtkcolumnviewcolumnprivate.h @@ -0,0 +1,29 @@ +/* + * 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 . + * + * Authors: Benjamin Otte + */ + +#ifndef __GTK_COLUMN_VIEW_COLUMN_PRIVATE_H__ +#define __GTK_COLUMN_VIEW_COLUMN_PRIVATE_H__ + +#include "gtk/gtkcolumnviewcolumn.h" + +void gtk_column_view_column_set_column_view (GtkColumnViewColumn *self, + GtkColumnView *view); + + +#endif /* __GTK_COLUMN_VIEW_COLUMN_PRIVATE_H__ */