columnviewcellwidget: Untangle from GtkListItemWidget
This is step 1 in switching cells to their own ListItem subclass.
This commit is contained in:
@@ -25,8 +25,8 @@
|
||||
#include "gtkcolumnviewrowwidgetprivate.h"
|
||||
#include "gtkcssboxesprivate.h"
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtklistfactorywidgetprivate.h"
|
||||
#include "gtklistitemprivate.h"
|
||||
#include "gtklistitemwidgetprivate.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
|
||||
@@ -47,7 +47,72 @@ struct _GtkColumnViewCellWidgetClass
|
||||
GtkListItemWidgetClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkColumnViewCellWidget, gtk_column_view_cell_widget, GTK_TYPE_LIST_ITEM_WIDGET)
|
||||
G_DEFINE_TYPE (GtkColumnViewCellWidget, gtk_column_view_cell_widget, GTK_TYPE_LIST_FACTORY_WIDGET)
|
||||
|
||||
static gboolean
|
||||
gtk_column_view_cell_widget_focus (GtkWidget *widget,
|
||||
GtkDirectionType direction)
|
||||
{
|
||||
GtkWidget *child = gtk_widget_get_first_child (widget);
|
||||
|
||||
if (gtk_widget_get_focus_child (widget))
|
||||
{
|
||||
/* focus is in the child */
|
||||
if (direction == GTK_DIR_TAB_BACKWARD)
|
||||
return gtk_widget_grab_focus_self (widget);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
else if (gtk_widget_is_focus (widget))
|
||||
{
|
||||
/* The widget has focus */
|
||||
if (direction == GTK_DIR_TAB_FORWARD)
|
||||
{
|
||||
if (child)
|
||||
return gtk_widget_child_focus (child, direction);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* focus coming in from the outside */
|
||||
if (direction == GTK_DIR_TAB_BACKWARD)
|
||||
{
|
||||
if (child &&
|
||||
gtk_widget_child_focus (child, direction))
|
||||
return TRUE;
|
||||
|
||||
return gtk_widget_grab_focus_self (widget);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gtk_widget_grab_focus_self (widget))
|
||||
return TRUE;
|
||||
|
||||
if (child &&
|
||||
gtk_widget_child_focus (child, direction))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_column_view_cell_widget_grab_focus (GtkWidget *widget)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
if (GTK_WIDGET_CLASS (gtk_column_view_cell_widget_parent_class)->grab_focus (widget))
|
||||
return TRUE;
|
||||
|
||||
child = gtk_widget_get_first_child (widget);
|
||||
if (child && gtk_widget_grab_focus (child))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gtk_column_view_cell_widget_create_object (GtkListFactoryWidget *fw)
|
||||
@@ -63,13 +128,81 @@ gtk_column_view_cell_widget_create_object (GtkListFactoryWidget *fw)
|
||||
return list_item;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_column_view_cell_widget_setup_object (GtkListFactoryWidget *fw,
|
||||
gpointer object)
|
||||
{
|
||||
GtkColumnViewCellWidget *self = GTK_COLUMN_VIEW_CELL_WIDGET (fw);
|
||||
GtkListItem *list_item = object;
|
||||
|
||||
GTK_LIST_FACTORY_WIDGET_CLASS (gtk_column_view_cell_widget_parent_class)->setup_object (fw, object);
|
||||
|
||||
list_item->cell = self;
|
||||
|
||||
gtk_list_factory_widget_set_activatable (fw, list_item->activatable);
|
||||
gtk_list_factory_widget_set_selectable (fw, list_item->selectable);
|
||||
gtk_column_view_cell_widget_set_child (GTK_COLUMN_VIEW_CELL_WIDGET (self), list_item->child);
|
||||
|
||||
gtk_widget_set_focusable (GTK_WIDGET (self), list_item->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)));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_column_view_cell_widget_teardown_object (GtkListFactoryWidget *fw,
|
||||
gpointer object)
|
||||
{
|
||||
GtkColumnViewCellWidget *self = GTK_COLUMN_VIEW_CELL_WIDGET (fw);
|
||||
GtkListItem *list_item = object;
|
||||
|
||||
GTK_LIST_FACTORY_WIDGET_CLASS (gtk_column_view_cell_widget_parent_class)->teardown_object (fw, object);
|
||||
|
||||
gtk_widget_set_focusable (GTK_WIDGET (fw), FALSE);
|
||||
list_item->cell = NULL;
|
||||
|
||||
gtk_column_view_cell_widget_set_child (GTK_COLUMN_VIEW_CELL_WIDGET (self), NULL);
|
||||
|
||||
gtk_list_factory_widget_set_activatable (fw, FALSE);
|
||||
gtk_list_factory_widget_set_selectable (fw, FALSE);
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_column_view_cell_widget_update_object (GtkListFactoryWidget *fw,
|
||||
gpointer object,
|
||||
guint position,
|
||||
gpointer item,
|
||||
gboolean selected)
|
||||
{
|
||||
GtkColumnViewCellWidget *self = GTK_COLUMN_VIEW_CELL_WIDGET (fw);
|
||||
GtkListItemBase *base = GTK_LIST_ITEM_BASE (self);
|
||||
GtkListItem *list_item = object;
|
||||
/* Track notify manually instead of freeze/thaw_notify for performance reasons. */
|
||||
gboolean notify_item = FALSE, notify_position = FALSE, notify_selected = FALSE;
|
||||
|
||||
/* FIXME: It's kinda evil to notify external objects from here... */
|
||||
notify_item = gtk_list_item_base_get_item (base) != item;
|
||||
notify_position = gtk_list_item_base_get_position (base) != position;
|
||||
notify_selected = gtk_list_item_base_get_selected (base) != selected;
|
||||
|
||||
GTK_LIST_FACTORY_WIDGET_CLASS (gtk_column_view_cell_widget_parent_class)->update_object (fw,
|
||||
object,
|
||||
position,
|
||||
item,
|
||||
selected);
|
||||
|
||||
if (list_item)
|
||||
gtk_list_item_do_notify (list_item, notify_item, notify_position, notify_selected);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -193,8 +326,12 @@ gtk_column_view_cell_widget_class_init (GtkColumnViewCellWidgetClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
factory_class->create_object = gtk_column_view_cell_widget_create_object;
|
||||
factory_class->setup_object = gtk_column_view_cell_widget_setup_object;
|
||||
factory_class->update_object = gtk_column_view_cell_widget_update_object;
|
||||
factory_class->teardown_object = gtk_column_view_cell_widget_teardown_object;
|
||||
|
||||
widget_class->focus = gtk_column_view_cell_widget_focus;
|
||||
widget_class->grab_focus = gtk_column_view_cell_widget_grab_focus;
|
||||
widget_class->measure = gtk_column_view_cell_widget_measure;
|
||||
widget_class->size_allocate = gtk_column_view_cell_widget_size_allocate;
|
||||
widget_class->get_request_mode = gtk_column_view_cell_widget_get_request_mode;
|
||||
@@ -272,3 +409,18 @@ gtk_column_view_cell_widget_get_column (GtkColumnViewCellWidget *self)
|
||||
{
|
||||
return self->column;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_column_view_cell_widget_set_child (GtkColumnViewCellWidget *self,
|
||||
GtkWidget *child)
|
||||
{
|
||||
GtkWidget *cur_child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||
|
||||
if (cur_child == child)
|
||||
return;
|
||||
|
||||
g_clear_pointer (&cur_child, gtk_widget_unparent);
|
||||
|
||||
if (child)
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
@@ -38,6 +38,9 @@ GType gtk_column_view_cell_widget_get_type (
|
||||
GtkWidget * gtk_column_view_cell_widget_new (GtkColumnViewColumn *column,
|
||||
gboolean inert);
|
||||
|
||||
void gtk_column_view_cell_widget_set_child (GtkColumnViewCellWidget *self,
|
||||
GtkWidget *child);
|
||||
|
||||
void gtk_column_view_cell_widget_remove (GtkColumnViewCellWidget *self);
|
||||
|
||||
GtkColumnViewCellWidget * gtk_column_view_cell_widget_get_next (GtkColumnViewCellWidget *self);
|
||||
|
||||
@@ -70,6 +70,7 @@ 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);
|
||||
@@ -100,11 +101,15 @@ 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;
|
||||
@@ -116,6 +121,8 @@ 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;
|
||||
@@ -287,10 +294,12 @@ gtk_list_item_get_item (GtkListItem *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_LIST_ITEM (self), NULL);
|
||||
|
||||
if (self->owner == NULL)
|
||||
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
|
||||
return NULL;
|
||||
|
||||
return gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self->owner));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -347,6 +356,8 @@ 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]);
|
||||
}
|
||||
@@ -388,10 +399,12 @@ gtk_list_item_get_selected (GtkListItem *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_LIST_ITEM (self), FALSE);
|
||||
|
||||
if (self->owner == NULL)
|
||||
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
|
||||
return FALSE;
|
||||
|
||||
return gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self->owner));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -444,6 +457,8 @@ gtk_list_item_set_selectable (GtkListItem *self,
|
||||
|
||||
if (self->owner)
|
||||
gtk_list_factory_widget_set_selectable (GTK_LIST_FACTORY_WIDGET (self->owner), selectable);
|
||||
if (self->cell)
|
||||
gtk_list_factory_widget_set_selectable (GTK_LIST_FACTORY_WIDGET (self->cell), selectable);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTABLE]);
|
||||
}
|
||||
@@ -493,6 +508,8 @@ gtk_list_item_set_activatable (GtkListItem *self,
|
||||
|
||||
if (self->owner)
|
||||
gtk_list_factory_widget_set_activatable (GTK_LIST_FACTORY_WIDGET (self->owner), activatable);
|
||||
if (self->cell)
|
||||
gtk_list_factory_widget_set_activatable (GTK_LIST_FACTORY_WIDGET (self->cell), activatable);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACTIVATABLE]);
|
||||
}
|
||||
@@ -548,6 +565,8 @@ 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]);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "gtklistitem.h"
|
||||
|
||||
#include "gtklistitemwidgetprivate.h"
|
||||
#include "gtkcolumnviewcellwidgetprivate.h"
|
||||
#include "gtkversion.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -31,6 +32,7 @@ struct _GtkListItem
|
||||
GObject parent_instance;
|
||||
|
||||
GtkListItemWidget *owner; /* has a reference */
|
||||
GtkColumnViewCellWidget *cell; /* has a reference */
|
||||
|
||||
GtkWidget *child;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user