From 7a4ad81ed61cf39bcad5d89942bebe6f52e2dce2 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Thu, 30 Mar 2023 13:18:15 +0200 Subject: [PATCH] columnview: Add GtkColumnViewCell This splits GtkListItem into 2 objects. It is fully backwards compatible. Using GtkListItem for GtkColumnView is now de-facto deprecated. --- gtk/gtk.h | 1 + gtk/gtkcolumnviewcell.c | 424 +++++++++++++++++++++++++++++++++ gtk/gtkcolumnviewcell.h | 54 +++++ gtk/gtkcolumnviewcellprivate.h | 49 ++++ gtk/gtkcolumnviewcellwidget.c | 49 ++-- gtk/gtklistitem.c | 42 ++-- gtk/gtklistitemprivate.h | 6 +- gtk/meson.build | 2 + 8 files changed, 573 insertions(+), 54 deletions(-) create mode 100644 gtk/gtkcolumnviewcell.c create mode 100644 gtk/gtkcolumnviewcell.h create mode 100644 gtk/gtkcolumnviewcellprivate.h diff --git a/gtk/gtk.h b/gtk/gtk.h index 0f2d44da7e..a3973437f3 100644 --- a/gtk/gtk.h +++ b/gtk/gtk.h @@ -86,6 +86,7 @@ #include #include #include +#include #include #include #include diff --git a/gtk/gtkcolumnviewcell.c b/gtk/gtkcolumnviewcell.c new file mode 100644 index 0000000000..c32bc0fd09 --- /dev/null +++ b/gtk/gtkcolumnviewcell.c @@ -0,0 +1,424 @@ +/* + * 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 . + * + * Authors: Benjamin Otte + */ + +#include "config.h" + +#include "gtkcolumnviewcellprivate.h" + +#include "gtklistitembaseprivate.h" + +/** + * GtkColumnViewCell: + * + * `GtkColumnViewCell` is used by [class@Gtk.ColumnViewColumn] to represent items + * in a cell in [class@Gtk.ColumnView]. + * + * The `GtkColumnViewCell`s are managed by the columnview widget (with its factory) + * and cannot be created by applications, but they need to be populated + * by application code. This is done by calling [method@Gtk.ColumnViewCell.set_child]. + * + * `GtkColumnViewCell`s exist in 2 stages: + * + * 1. The unbound stage where the listitem is not currently connected to + * an item in the list. In that case, the [property@Gtk.ColumnViewCell:item] + * property is set to %NULL. + * + * 2. The bound stage where the listitem references an item from the list. + * The [property@Gtk.ColumnViewCell:item] property is not %NULL. + * + * Since: 4.12 + */ + +struct _GtkColumnViewCellClass +{ + GtkListItemClass parent_class; +}; + +enum +{ + PROP_0, + PROP_CHILD, + PROP_FOCUSABLE, + PROP_ITEM, + PROP_POSITION, + PROP_SELECTED, + + N_PROPS +}; + +G_DEFINE_TYPE (GtkColumnViewCell, gtk_column_view_cell, GTK_TYPE_LIST_ITEM) + +static GParamSpec *properties[N_PROPS] = { NULL, }; + +static void +gtk_column_view_cell_dispose (GObject *object) +{ + GtkColumnViewCell *self = GTK_COLUMN_VIEW_CELL (object); + + g_assert (self->cell == NULL); /* would hold a reference */ + g_clear_object (&self->child); + + G_OBJECT_CLASS (gtk_column_view_cell_parent_class)->dispose (object); +} + +static void +gtk_column_view_cell_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GtkColumnViewCell *self = GTK_COLUMN_VIEW_CELL (object); + + switch (property_id) + { + case PROP_CHILD: + g_value_set_object (value, self->child); + break; + + case PROP_FOCUSABLE: + g_value_set_boolean (value, self->focusable); + break; + + case PROP_ITEM: + if (self->cell) + g_value_set_object (value, gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self->cell))); + break; + + case PROP_POSITION: + if (self->cell) + g_value_set_uint (value, gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self->cell))); + else + g_value_set_uint (value, GTK_INVALID_LIST_POSITION); + break; + + case PROP_SELECTED: + if (self->cell) + g_value_set_boolean (value, gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self->cell))); + else + g_value_set_boolean (value, FALSE); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gtk_column_view_cell_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkColumnViewCell *self = GTK_COLUMN_VIEW_CELL (object); + + switch (property_id) + { + case PROP_CHILD: + gtk_column_view_cell_set_child (self, g_value_get_object (value)); + break; + + case PROP_FOCUSABLE: + gtk_column_view_cell_set_focusable (self, g_value_get_boolean (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gtk_column_view_cell_class_init (GtkColumnViewCellClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->dispose = gtk_column_view_cell_dispose; + gobject_class->get_property = gtk_column_view_cell_get_property; + gobject_class->set_property = gtk_column_view_cell_set_property; + + /** + * GtkColumnViewCell:child: (attributes org.gtk.Property.get=gtk_column_view_cell_get_child org.gtk.Property.set=gtk_column_view_cell_set_child) + * + * Widget used for display. + * + * Since: 4.12 + */ + properties[PROP_CHILD] = + g_param_spec_object ("child", NULL, NULL, + GTK_TYPE_WIDGET, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GtkColumnViewCell:focusable: (attributes org.gtk.Property.get=gtk_column_view_cell_get_focusable org.gtk.Property.set=gtk_column_view_cell_set_focusable) + * + * If the item can be focused with the keyboard. + * + * Since: 4.12 + */ + properties[PROP_FOCUSABLE] = + g_param_spec_boolean ("focusable", NULL, NULL, + FALSE, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GtkColumnViewCell:item: (attributes org.gtk.Property.get=gtk_column_view_cell_get_item) + * + * Displayed item. + * + * Since: 4.12 + */ + properties[PROP_ITEM] = + g_param_spec_object ("item", NULL, NULL, + G_TYPE_OBJECT, + G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GtkColumnViewCell:position: (attributes org.gtk.Property.get=gtk_column_view_cell_get_position) + * + * Position of the item. + * + * Since: 4.12 + */ + properties[PROP_POSITION] = + g_param_spec_uint ("position", NULL, NULL, + 0, G_MAXUINT, GTK_INVALID_LIST_POSITION, + G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GtkColumnViewCell:selected: (attributes org.gtk.Property.get=gtk_column_view_cell_get_selected) + * + * If the item is currently selected. + * + * Since: 4.12 + */ + properties[PROP_SELECTED] = + g_param_spec_boolean ("selected", NULL, NULL, + FALSE, + G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, N_PROPS, properties); +} + +static void +gtk_column_view_cell_init (GtkColumnViewCell *self) +{ + self->focusable = FALSE; +} + +GtkColumnViewCell * +gtk_column_view_cell_new (void) +{ + return g_object_new (GTK_TYPE_COLUMN_VIEW_CELL, NULL); +} + +void +gtk_column_view_cell_do_notify (GtkColumnViewCell *column_view_cell, + gboolean notify_item, + gboolean notify_position, + gboolean notify_selected) +{ + GObject *object = G_OBJECT (column_view_cell); + + if (notify_item) + g_object_notify_by_pspec (object, properties[PROP_ITEM]); + if (notify_position) + g_object_notify_by_pspec (object, properties[PROP_POSITION]); + if (notify_selected) + g_object_notify_by_pspec (object, properties[PROP_SELECTED]); +} + +/** + * gtk_column_view_cell_get_item: (attributes org.gtk.Method.get_property=item) + * @self: a `GtkColumnViewCell` + * + * Gets the model item that associated with @self. + * + * If @self is unbound, this function returns %NULL. + * + * Returns: (nullable) (transfer none) (type GObject): The item displayed + * + * Since: 4.12 + **/ +gpointer +gtk_column_view_cell_get_item (GtkColumnViewCell *self) +{ + g_return_val_if_fail (GTK_IS_COLUMN_VIEW_CELL (self), NULL); + + if (self->cell == NULL) + return NULL; + + return gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self->cell)); +} + +/** + * gtk_column_view_cell_get_child: (attributes org.gtk.Method.get_property=child) + * @self: a `GtkColumnViewCell` + * + * Gets the child previously set via gtk_column_view_cell_set_child() or + * %NULL if none was set. + * + * Returns: (transfer none) (nullable): The child + * + * Since: 4.12 + */ +GtkWidget * +gtk_column_view_cell_get_child (GtkColumnViewCell *self) +{ + g_return_val_if_fail (GTK_IS_COLUMN_VIEW_CELL (self), NULL); + + return self->child; +} + +/** + * gtk_column_view_cell_set_child: (attributes org.gtk.Method.set_property=child) + * @self: a `GtkColumnViewCell` + * @child: (nullable): The list item's child or %NULL to unset + * + * Sets the child to be used for this listitem. + * + * This function is typically called by applications when + * setting up a listitem so that the widget can be reused when + * binding it multiple times. + * + * Since: 4.12 + */ +void +gtk_column_view_cell_set_child (GtkColumnViewCell *self, + GtkWidget *child) +{ + g_return_if_fail (GTK_IS_COLUMN_VIEW_CELL (self)); + g_return_if_fail (child == NULL || GTK_IS_WIDGET (child)); + + if (self->child == child) + return; + + g_clear_object (&self->child); + + if (child) + { + g_object_ref_sink (child); + self->child = child; + } + + if (self->cell) + gtk_column_view_cell_widget_set_child (self->cell, child); + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CHILD]); +} + +/** + * gtk_column_view_cell_get_position: (attributes org.gtk.Method.get_property=position) + * @self: a `GtkColumnViewCell` + * + * Gets the position in the model that @self currently displays. + * + * If @self is unbound, %GTK_INVALID_LIST_POSITION is returned. + * + * Returns: The position of this item + * + * Since: 4.12 + */ +guint +gtk_column_view_cell_get_position (GtkColumnViewCell *self) +{ + g_return_val_if_fail (GTK_IS_COLUMN_VIEW_CELL (self), GTK_INVALID_LIST_POSITION); + + if (self->cell == NULL) + return GTK_INVALID_LIST_POSITION; + + return gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self->cell)); +} + +/** + * gtk_column_view_cell_get_selected: (attributes org.gtk.Method.get_property=selected) + * @self: a `GtkColumnViewCell` + * + * Checks if the item is displayed as selected. + * + * The selected state is maintained by the liste widget and its model + * and cannot be set otherwise. + * + * Returns: %TRUE if the item is selected. + * + * Since: 4.12 + */ +gboolean +gtk_column_view_cell_get_selected (GtkColumnViewCell *self) +{ + g_return_val_if_fail (GTK_IS_COLUMN_VIEW_CELL (self), FALSE); + + if (self->cell == NULL) + return FALSE; + + return gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self->cell)); +} + +/** + * gtk_column_view_cell_get_focusable: (attributes org.gtk.Method.get_property=focusable) + * @self: a `GtkColumnViewCell` + * + * Checks if a list item has been set to be focusable via + * gtk_column_view_cell_set_focusable(). + * + * Returns: %TRUE if the item is focusable + * + * Since: 4.12 + */ +gboolean +gtk_column_view_cell_get_focusable (GtkColumnViewCell *self) +{ + g_return_val_if_fail (GTK_IS_COLUMN_VIEW_CELL (self), FALSE); + + return self->focusable; +} + +/** + * gtk_column_view_cell_set_focusable: (attributes org.gtk.Method.set_property=focusable) + * @self: a `GtkColumnViewCell` + * @focusable: if the item should be focusable + * + * Sets @self to be focusable. + * + * If an item is focusable, it can be focused using the keyboard. + * This works similar to [method@Gtk.Widget.set_focusable]. + * + * Note that if items are not focusable, the keyboard cannot be used to activate + * them and selecting only works if one of the listitem's children is focusable. + * + * By default, list items are focusable. + * + * Since: 4.12 + */ +void +gtk_column_view_cell_set_focusable (GtkColumnViewCell *self, + gboolean focusable) +{ + g_return_if_fail (GTK_IS_COLUMN_VIEW_CELL (self)); + + if (self->focusable == focusable) + return; + + self->focusable = focusable; + + if (self->cell) + gtk_widget_set_focusable (GTK_WIDGET (self->cell), focusable); + + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FOCUSABLE]); +} diff --git a/gtk/gtkcolumnviewcell.h b/gtk/gtkcolumnviewcell.h new file mode 100644 index 0000000000..f1490ea80d --- /dev/null +++ b/gtk/gtkcolumnviewcell.h @@ -0,0 +1,54 @@ +/* + * 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 . + * + * Authors: Benjamin Otte + */ + +#pragma once + +#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define GTK_TYPE_COLUMN_VIEW_CELL (gtk_column_view_cell_get_type ()) +GDK_AVAILABLE_IN_4_12 +GDK_DECLARE_INTERNAL_TYPE(GtkColumnViewCell, gtk_column_view_cell, GTK, COLUMN_VIEW_CELL, GtkListItem); + +GDK_AVAILABLE_IN_4_12 +gpointer gtk_column_view_cell_get_item (GtkColumnViewCell *self); +GDK_AVAILABLE_IN_4_12 +guint gtk_column_view_cell_get_position (GtkColumnViewCell *self) G_GNUC_PURE; +GDK_AVAILABLE_IN_4_12 +gboolean gtk_column_view_cell_get_selected (GtkColumnViewCell *self) G_GNUC_PURE; +GDK_AVAILABLE_IN_4_12 +gboolean gtk_column_view_cell_get_focusable (GtkColumnViewCell *self) G_GNUC_PURE; +GDK_AVAILABLE_IN_4_12 +void gtk_column_view_cell_set_focusable (GtkColumnViewCell *self, + gboolean focusable); + +GDK_AVAILABLE_IN_4_12 +void gtk_column_view_cell_set_child (GtkColumnViewCell *self, + GtkWidget *child); +GDK_AVAILABLE_IN_4_12 +GtkWidget * gtk_column_view_cell_get_child (GtkColumnViewCell *self); + +G_END_DECLS + diff --git a/gtk/gtkcolumnviewcellprivate.h b/gtk/gtkcolumnviewcellprivate.h new file mode 100644 index 0000000000..40964d25d4 --- /dev/null +++ b/gtk/gtkcolumnviewcellprivate.h @@ -0,0 +1,49 @@ +/* + * 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 . + * + * Authors: Benjamin Otte + */ + +#pragma once + +#include "gtkcolumnviewcell.h" + +#include "gtkcolumnviewcellwidgetprivate.h" +#include "gtklistitemprivate.h" + +G_BEGIN_DECLS + +struct _GtkColumnViewCell +{ + GtkListItem parent_instance; + + GtkColumnViewCellWidget *cell; /* has a reference */ + + GtkWidget *child; + + guint focusable : 1; +}; + +GtkColumnViewCell * gtk_column_view_cell_new (void); + +void gtk_column_view_cell_do_notify (GtkColumnViewCell *column_view_cell, + gboolean notify_item, + gboolean notify_position, + gboolean notify_selected); + + +G_END_DECLS + diff --git a/gtk/gtkcolumnviewcellwidget.c b/gtk/gtkcolumnviewcellwidget.c index 7020de1c0e..eb3ab7835e 100644 --- a/gtk/gtkcolumnviewcellwidget.c +++ b/gtk/gtkcolumnviewcellwidget.c @@ -21,12 +21,12 @@ #include "gtkcolumnviewcellwidgetprivate.h" +#include "gtkcolumnviewcellprivate.h" #include "gtkcolumnviewcolumnprivate.h" #include "gtkcolumnviewrowwidgetprivate.h" #include "gtkcssboxesprivate.h" #include "gtkcssnodeprivate.h" #include "gtklistfactorywidgetprivate.h" -#include "gtklistitemprivate.h" #include "gtkprivate.h" #include "gtkwidgetprivate.h" @@ -117,15 +117,7 @@ gtk_column_view_cell_widget_grab_focus (GtkWidget *widget) static gpointer gtk_column_view_cell_widget_create_object (GtkListFactoryWidget *fw) { - GtkListItem *list_item; - - list_item = gtk_list_item_new (); - - gtk_list_item_set_selectable (list_item, FALSE); - gtk_list_item_set_activatable (list_item, FALSE); - gtk_list_item_set_focusable (list_item, FALSE); - - return list_item; + return gtk_column_view_cell_new (); } static void @@ -133,20 +125,20 @@ gtk_column_view_cell_widget_setup_object (GtkListFactoryWidget *fw, gpointer object) { GtkColumnViewCellWidget *self = GTK_COLUMN_VIEW_CELL_WIDGET (fw); - GtkListItem *list_item = object; + GtkColumnViewCell *cell = object; GTK_LIST_FACTORY_WIDGET_CLASS (gtk_column_view_cell_widget_parent_class)->setup_object (fw, object); - list_item->cell = self; + cell->cell = self; - gtk_column_view_cell_widget_set_child (GTK_COLUMN_VIEW_CELL_WIDGET (self), list_item->child); + gtk_column_view_cell_widget_set_child (GTK_COLUMN_VIEW_CELL_WIDGET (self), cell->child); - gtk_widget_set_focusable (GTK_WIDGET (self), list_item->focusable); + gtk_widget_set_focusable (GTK_WIDGET (self), cell->focusable); - gtk_list_item_do_notify (list_item, - gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL, - gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)) != GTK_INVALID_LIST_POSITION, - gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self))); + gtk_column_view_cell_do_notify (cell, + gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL, + gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)) != GTK_INVALID_LIST_POSITION, + gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self))); } static void @@ -154,23 +146,20 @@ gtk_column_view_cell_widget_teardown_object (GtkListFactoryWidget *fw, gpointer object) { GtkColumnViewCellWidget *self = GTK_COLUMN_VIEW_CELL_WIDGET (fw); - GtkListItem *list_item = object; + GtkColumnViewCell *cell = object; GTK_LIST_FACTORY_WIDGET_CLASS (gtk_column_view_cell_widget_parent_class)->teardown_object (fw, object); - list_item->cell = NULL; + cell->cell = NULL; gtk_column_view_cell_widget_set_child (GTK_COLUMN_VIEW_CELL_WIDGET (self), NULL); gtk_widget_set_focusable (GTK_WIDGET (self), FALSE); - gtk_list_item_do_notify (list_item, - gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL, - gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)) != GTK_INVALID_LIST_POSITION, - gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self))); - - /* FIXME: This is technically not correct, the child is user code, isn't it? */ - gtk_list_item_set_child (list_item, NULL); + gtk_column_view_cell_do_notify (cell, + gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL, + gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)) != GTK_INVALID_LIST_POSITION, + gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self))); } static void @@ -182,7 +171,7 @@ gtk_column_view_cell_widget_update_object (GtkListFactoryWidget *fw, { GtkColumnViewCellWidget *self = GTK_COLUMN_VIEW_CELL_WIDGET (fw); GtkListItemBase *base = GTK_LIST_ITEM_BASE (self); - GtkListItem *list_item = object; + GtkColumnViewCell *cell = object; /* Track notify manually instead of freeze/thaw_notify for performance reasons. */ gboolean notify_item = FALSE, notify_position = FALSE, notify_selected = FALSE; @@ -197,8 +186,8 @@ gtk_column_view_cell_widget_update_object (GtkListFactoryWidget *fw, item, selected); - if (list_item) - gtk_list_item_do_notify (list_item, notify_item, notify_position, notify_selected); + if (cell) + gtk_column_view_cell_do_notify (cell, notify_item, notify_position, notify_selected); } static int diff --git a/gtk/gtklistitem.c b/gtk/gtklistitem.c index bbda5d6386..267b9ea6c5 100644 --- a/gtk/gtklistitem.c +++ b/gtk/gtklistitem.c @@ -21,6 +21,7 @@ #include "gtklistitemprivate.h" +#include "gtkcolumnviewcell.h" /** * GtkListItem: @@ -41,11 +42,6 @@ * The [property@Gtk.ListItem:item] property is not %NULL. */ -struct _GtkListItemClass -{ - GObjectClass parent_class; -}; - enum { PROP_0, @@ -70,7 +66,6 @@ gtk_list_item_dispose (GObject *object) GtkListItem *self = GTK_LIST_ITEM (object); g_assert (self->owner == NULL); /* would hold a reference */ - g_assert (self->cell == NULL); /* would hold a reference */ g_clear_object (&self->child); G_OBJECT_CLASS (gtk_list_item_parent_class)->dispose (object); @@ -101,15 +96,11 @@ gtk_list_item_get_property (GObject *object, case PROP_ITEM: if (self->owner) g_value_set_object (value, gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self->owner))); - else if (self->cell) - g_value_set_object (value, gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self->cell))); break; case PROP_POSITION: if (self->owner) g_value_set_uint (value, gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self->owner))); - else if (self->cell) - g_value_set_uint (value, gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self->cell))); else g_value_set_uint (value, GTK_INVALID_LIST_POSITION); break; @@ -121,8 +112,6 @@ gtk_list_item_get_property (GObject *object, case PROP_SELECTED: if (self->owner) g_value_set_boolean (value, gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self->owner))); - if (self->cell) - g_value_set_boolean (value, gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self->cell))); else g_value_set_boolean (value, FALSE); break; @@ -296,8 +285,8 @@ gtk_list_item_get_item (GtkListItem *self) if (self->owner) return gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self->owner)); - else if (self->cell) - return gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self->cell)); + else if (GTK_IS_COLUMN_VIEW_CELL (self)) + return gtk_column_view_cell_get_item (GTK_COLUMN_VIEW_CELL (self)); else return NULL; } @@ -316,6 +305,9 @@ gtk_list_item_get_child (GtkListItem *self) { g_return_val_if_fail (GTK_IS_LIST_ITEM (self), NULL); + if (GTK_IS_COLUMN_VIEW_CELL (self)) + return gtk_column_view_cell_get_child (GTK_COLUMN_VIEW_CELL (self)); + return self->child; } @@ -337,6 +329,12 @@ gtk_list_item_set_child (GtkListItem *self, g_return_if_fail (GTK_IS_LIST_ITEM (self)); g_return_if_fail (child == NULL || gtk_widget_get_parent (child) == NULL); + if (GTK_IS_COLUMN_VIEW_CELL (self)) + { + gtk_column_view_cell_set_child (GTK_COLUMN_VIEW_CELL (self), child); + return; + } + if (self->child == child) return; @@ -356,8 +354,6 @@ gtk_list_item_set_child (GtkListItem *self, if (self->owner) gtk_list_item_widget_set_child (self->owner, child); - else if (self->cell) - gtk_column_view_cell_widget_set_child (self->cell, child); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CHILD]); } @@ -377,10 +373,12 @@ gtk_list_item_get_position (GtkListItem *self) { g_return_val_if_fail (GTK_IS_LIST_ITEM (self), GTK_INVALID_LIST_POSITION); - if (self->owner == NULL) + if (self->owner) + return gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self->owner)); + else if (GTK_IS_COLUMN_VIEW_CELL (self)) + return gtk_column_view_cell_get_position (GTK_COLUMN_VIEW_CELL (self)); + else return GTK_INVALID_LIST_POSITION; - - return gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self->owner)); } /** @@ -401,8 +399,8 @@ gtk_list_item_get_selected (GtkListItem *self) if (self->owner) return gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self->owner)); - if (self->cell) - return gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self->cell)); + else if (GTK_IS_COLUMN_VIEW_CELL (self)) + return gtk_column_view_cell_get_selected (GTK_COLUMN_VIEW_CELL (self)); else return FALSE; } @@ -561,8 +559,6 @@ gtk_list_item_set_focusable (GtkListItem *self, if (self->owner) gtk_widget_set_focusable (GTK_WIDGET (self->owner), focusable); - if (self->cell) - gtk_widget_set_focusable (GTK_WIDGET (self->cell), focusable); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FOCUSABLE]); } diff --git a/gtk/gtklistitemprivate.h b/gtk/gtklistitemprivate.h index 6858419821..60e122bc10 100644 --- a/gtk/gtklistitemprivate.h +++ b/gtk/gtklistitemprivate.h @@ -32,7 +32,6 @@ struct _GtkListItem GObject parent_instance; GtkListItemWidget *owner; /* has a reference */ - GtkColumnViewCellWidget *cell; /* has a reference */ GtkWidget *child; @@ -44,6 +43,11 @@ struct _GtkListItem #endif }; +struct _GtkListItemClass +{ + GObjectClass parent_class; +}; + GtkListItem * gtk_list_item_new (void); void gtk_list_item_do_notify (GtkListItem *list_item, diff --git a/gtk/meson.build b/gtk/meson.build index 1914193d48..b3975fb3fc 100644 --- a/gtk/meson.build +++ b/gtk/meson.build @@ -187,6 +187,7 @@ gtk_public_sources = files([ 'gtkcolordialogbutton.c', 'gtkcolorutils.c', 'gtkcolumnview.c', + 'gtkcolumnviewcell.c', 'gtkcolumnviewcolumn.c', 'gtkcolumnviewrow.c', 'gtkcolumnviewsorter.c', @@ -441,6 +442,7 @@ gtk_public_headers = files([ 'gtkcolordialogbutton.h', 'gtkcolorutils.h', 'gtkcolumnview.h', + 'gtkcolumnviewcell.h', 'gtkcolumnviewcolumn.h', 'gtkcolumnviewrow.h', 'gtkcolumnviewsorter.h',