columnview: Implement inertness

This properly implements the same behavior as
62e9d1e470 and avoids randomly losing
factories.

Oops.
This commit is contained in:
Benjamin Otte 2023-03-29 10:33:51 +02:00
parent e8f0aa6ef8
commit d1bc552b5f
8 changed files with 121 additions and 14 deletions

View File

@ -179,7 +179,7 @@ gtk_column_list_view_create_list_widget (GtkListBase *base)
GtkWidget *result;
guint i;
result = gtk_column_view_row_widget_new (FALSE);
result = gtk_column_view_row_widget_new (gtk_list_view_get_factory (self->listview), FALSE);
gtk_list_factory_widget_set_single_click_activate (GTK_LIST_FACTORY_WIDGET (result), GTK_LIST_VIEW (base)->single_click_activate);
@ -191,7 +191,7 @@ gtk_column_list_view_create_list_widget (GtkListBase *base)
{
GtkWidget *cell;
cell = gtk_column_view_cell_widget_new (column);
cell = gtk_column_view_cell_widget_new (column, gtk_column_view_is_inert (self));
gtk_column_view_row_widget_add_child (GTK_COLUMN_VIEW_ROW_WIDGET (result), cell);
}
@ -297,6 +297,31 @@ G_DEFINE_TYPE_WITH_CODE (GtkColumnView, gtk_column_view, GTK_TYPE_WIDGET,
static GParamSpec *properties[N_PROPS] = { NULL, };
static guint signals[LAST_SIGNAL] = { 0 };
gboolean
gtk_column_view_is_inert (GtkColumnView *self)
{
GtkWidget *widget = GTK_WIDGET (self);
return !gtk_widget_get_visible (widget) ||
gtk_widget_get_root (widget) == NULL;
}
static void
gtk_column_view_update_cell_factories (GtkColumnView *self,
gboolean inert)
{
guint i, n;
n = g_list_model_get_n_items (G_LIST_MODEL (self->columns));
for (i = 0; i < n; i++)
{
GtkColumnViewColumn *column = g_list_model_get_item (G_LIST_MODEL (self->columns), i);
gtk_column_view_column_update_factory (column, inert);
}
}
static void
gtk_column_view_measure (GtkWidget *widget,
GtkOrientation orientation,
@ -475,6 +500,50 @@ gtk_column_view_allocate (GtkWidget *widget,
gtk_adjustment_configure (self->hadjustment, x, 0, full_width, width * 0.1, width * 0.9, width);
}
static void
gtk_column_view_root (GtkWidget *widget)
{
GtkColumnView *self = GTK_COLUMN_VIEW (widget);
GTK_WIDGET_CLASS (gtk_column_view_parent_class)->root (widget);
if (!gtk_column_view_is_inert (self))
gtk_column_view_update_cell_factories (self, FALSE);
}
static void
gtk_column_view_unroot (GtkWidget *widget)
{
GtkColumnView *self = GTK_COLUMN_VIEW (widget);
if (!gtk_column_view_is_inert (self))
gtk_column_view_update_cell_factories (self, TRUE);
GTK_WIDGET_CLASS (gtk_column_view_parent_class)->unroot (widget);
}
static void
gtk_column_view_show (GtkWidget *widget)
{
GtkColumnView *self = GTK_COLUMN_VIEW (widget);
GTK_WIDGET_CLASS (gtk_column_view_parent_class)->show (widget);
if (!gtk_column_view_is_inert (self))
gtk_column_view_update_cell_factories (self, FALSE);
}
static void
gtk_column_view_hide (GtkWidget *widget)
{
GtkColumnView *self = GTK_COLUMN_VIEW (widget);
if (!gtk_column_view_is_inert (self))
gtk_column_view_update_cell_factories (self, TRUE);
GTK_WIDGET_CLASS (gtk_column_view_parent_class)->hide (widget);
}
static void
gtk_column_view_activate_cb (GtkListView *listview,
guint pos,
@ -702,6 +771,10 @@ gtk_column_view_class_init (GtkColumnViewClass *klass)
widget_class->grab_focus = gtk_widget_grab_focus_child;
widget_class->measure = gtk_column_view_measure;
widget_class->size_allocate = gtk_column_view_allocate;
widget_class->root = gtk_column_view_root;
widget_class->unroot = gtk_column_view_unroot;
widget_class->show = gtk_column_view_show;
widget_class->hide = gtk_column_view_hide;
gobject_class->dispose = gtk_column_view_dispose;
gobject_class->finalize = gtk_column_view_finalize;
@ -1329,7 +1402,7 @@ gtk_column_view_init (GtkColumnView *self)
self->columns = g_list_store_new (GTK_TYPE_COLUMN_VIEW_COLUMN);
self->header = gtk_column_view_row_widget_new (TRUE);
self->header = gtk_column_view_row_widget_new (NULL, TRUE);
gtk_widget_set_can_focus (self->header, FALSE);
gtk_widget_set_parent (self->header, GTK_WIDGET (self));

View File

@ -237,12 +237,13 @@ gtk_column_view_cell_widget_init (GtkColumnViewCellWidget *self)
}
GtkWidget *
gtk_column_view_cell_widget_new (GtkColumnViewColumn *column)
gtk_column_view_cell_widget_new (GtkColumnViewColumn *column,
gboolean inert)
{
GtkColumnViewCellWidget *self;
self = g_object_new (GTK_TYPE_COLUMN_VIEW_CELL_WIDGET,
"factory", gtk_column_view_column_get_factory (column),
"factory", inert ? NULL : gtk_column_view_column_get_factory (column),
NULL);
self->column = g_object_ref (column);

View File

@ -35,7 +35,8 @@ typedef struct _GtkColumnViewCellWidgetClass GtkColumnViewCellWidgetClass;
GType gtk_column_view_cell_widget_get_type (void) G_GNUC_CONST;
GtkWidget * gtk_column_view_cell_widget_new (GtkColumnViewColumn *column);
GtkWidget * gtk_column_view_cell_widget_new (GtkColumnViewColumn *column,
gboolean inert);
void gtk_column_view_cell_widget_remove (GtkColumnViewCellWidget *self);

View File

@ -532,12 +532,9 @@ gtk_column_view_column_create_cells (GtkColumnViewColumn *self)
GtkListItemBase *base;
GtkWidget *cell;
if (!gtk_widget_get_root (row))
continue;
list_item = GTK_COLUMN_VIEW_ROW_WIDGET (row);
base = GTK_LIST_ITEM_BASE (row);
cell = gtk_column_view_cell_widget_new (self);
cell = gtk_column_view_cell_widget_new (self, gtk_column_view_is_inert (self->view));
gtk_column_view_row_widget_add_child (list_item, cell);
gtk_list_item_base_update (GTK_LIST_ITEM_BASE (cell),
gtk_list_item_base_get_position (base),
@ -581,8 +578,7 @@ gtk_column_view_column_remove_header (GtkColumnViewColumn *self)
static void
gtk_column_view_column_ensure_cells (GtkColumnViewColumn *self)
{
if (self->view && gtk_widget_get_root (GTK_WIDGET (self->view)) &&
gtk_column_view_column_get_visible (self))
if (self->view && gtk_column_view_column_get_visible (self))
gtk_column_view_column_create_cells (self);
else
gtk_column_view_column_remove_cells (self);
@ -664,6 +660,29 @@ gtk_column_view_column_get_factory (GtkColumnViewColumn *self)
return self->factory;
}
void
gtk_column_view_column_update_factory (GtkColumnViewColumn *self,
gboolean inert)
{
GtkListItemFactory *factory;
GtkColumnViewCellWidget *cell;
if (self->factory == NULL)
return;
if (inert)
factory = NULL;
else
factory = self->factory;
for (cell = self->first_cell;
cell;
cell = gtk_column_view_cell_widget_get_next (cell))
{
gtk_list_factory_widget_set_factory (GTK_LIST_FACTORY_WIDGET (cell), factory);
}
}
/**
* gtk_column_view_column_set_factory: (attributes org.gtk.Method.set_property=factory)
* @self: a `GtkColumnViewColumn`
@ -679,9 +698,15 @@ gtk_column_view_column_set_factory (GtkColumnViewColumn *self,
g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self));
g_return_if_fail (factory == NULL || GTK_LIST_ITEM_FACTORY (factory));
if (self->factory && !factory)
gtk_column_view_column_update_factory (self, TRUE);
if (!g_set_object (&self->factory, factory))
return;
if (self->view && !gtk_column_view_is_inert (self->view))
gtk_column_view_column_update_factory (self, FALSE);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]);
}

View File

@ -37,6 +37,8 @@ void gtk_column_view_column_remove_cell (GtkColu
GtkColumnViewCellWidget * gtk_column_view_column_get_first_cell (GtkColumnViewColumn *self);
GtkWidget * gtk_column_view_column_get_header (GtkColumnViewColumn *self);
void gtk_column_view_column_update_factory (GtkColumnViewColumn *self,
gboolean inert);
void gtk_column_view_column_queue_resize (GtkColumnViewColumn *self);
void gtk_column_view_column_measure (GtkColumnViewColumn *self,
int *minimum,

View File

@ -26,6 +26,8 @@
#include "gtk/gtkcolumnviewsorterprivate.h"
#include "gtk/gtkcolumnviewrowwidgetprivate.h"
gboolean gtk_column_view_is_inert (GtkColumnView *self);
GtkColumnViewRowWidget *gtk_column_view_get_header_widget (GtkColumnView *self);
GtkListView * gtk_column_view_get_list_view (GtkColumnView *self);

View File

@ -532,9 +532,11 @@ gtk_column_view_row_widget_init (GtkColumnViewRowWidget *self)
}
GtkWidget *
gtk_column_view_row_widget_new (gboolean is_header)
gtk_column_view_row_widget_new (GtkListItemFactory *factory,
gboolean is_header)
{
return g_object_new (GTK_TYPE_COLUMN_VIEW_ROW_WIDGET,
"factory", factory,
"css-name", is_header ? "header" : "row",
"selectable", TRUE,
"activatable", TRUE,

View File

@ -45,7 +45,8 @@ struct _GtkColumnViewRowWidgetClass
GType gtk_column_view_row_widget_get_type (void) G_GNUC_CONST;
GtkWidget * gtk_column_view_row_widget_new (gboolean is_header);
GtkWidget * gtk_column_view_row_widget_new (GtkListItemFactory *factory,
gboolean is_header);
void gtk_column_view_row_widget_add_child (GtkColumnViewRowWidget *self,
GtkWidget *child);