child;
child = gtk_widget_get_next_sibling (child))
{
- if (gtk_list_item_widget_get_selected (GTK_LIST_ITEM_WIDGET (child)))
+ if (gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (child)))
{
if (idx == 0)
break;
guint pos;
gboolean ret;
- pos = gtk_list_item_widget_get_position (GTK_LIST_ITEM_WIDGET (child));
+ pos = gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (child));
ret = gtk_selection_model_select_item (model, pos, FALSE);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
guint pos;
gboolean ret;
- pos = gtk_list_item_widget_get_position (GTK_LIST_ITEM_WIDGET (child));
+ pos = gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (child));
ret = gtk_selection_model_unselect_item (model, pos);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
child;
child = gtk_widget_get_next_sibling (child))
{
- if (gtk_list_item_widget_get_selected (GTK_LIST_ITEM_WIDGET (child)))
+ if (gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (child)))
{
if (idx == 0)
break;
guint pos;
gboolean ret;
- pos = gtk_list_item_widget_get_position (GTK_LIST_ITEM_WIDGET (child));
+ pos = gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (child));
ret = gtk_selection_model_unselect_item (model, pos);
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
{
gboolean ret;
- ret = gtk_list_item_widget_get_selected (GTK_LIST_ITEM_WIDGET (child));
+ ret = gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (child));
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", ret));
}
{
GtkListItem *cell_item;
- gtk_list_item_widget_update (GTK_LIST_ITEM_WIDGET (child),
- gtk_list_item_get_position (list_item),
- gtk_list_item_get_item (list_item),
- gtk_list_item_get_selected (list_item));
+ gtk_list_item_base_update (GTK_LIST_ITEM_BASE (child),
+ gtk_list_item_get_position (list_item),
+ gtk_list_item_get_item (list_item),
+ gtk_list_item_get_selected (list_item));
cell_item = gtk_list_item_widget_get_list_item (GTK_LIST_ITEM_WIDGET (child));
if (cell_item)
GtkColumnViewColumn *column,
gboolean check_bind)
{
+ GtkListItemBase *base = GTK_LIST_ITEM_BASE (list_item);
GtkWidget *cell;
cell = gtk_column_view_cell_new (column);
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));
+ gtk_list_item_base_update (GTK_LIST_ITEM_BASE (cell),
+ gtk_list_item_base_get_position (base),
+ gtk_list_item_base_get_item (base),
+ gtk_list_item_base_get_selected (base));
}
row = gtk_widget_get_next_sibling (row))
{
GtkListItemWidget *list_item;
+ GtkListItemBase *base;
GtkWidget *cell;
if (!gtk_widget_get_root (row))
continue;
list_item = GTK_LIST_ITEM_WIDGET (row);
+ base = GTK_LIST_ITEM_BASE (row);
cell = gtk_column_view_cell_new (self);
gtk_list_item_widget_add_child (list_item, 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));
+ gtk_list_item_base_update (GTK_LIST_ITEM_BASE (cell),
+ gtk_list_item_base_get_position (base),
+ gtk_list_item_base_get_item (base),
+ gtk_list_item_base_get_selected (base));
}
}
gtk_stack_set_visible_child_name (GTK_STACK (self->button_stack), "item");
}
- if (selected != gtk_list_item_widget_get_position (GTK_LIST_ITEM_WIDGET (self->button_item)))
+ if (selected != gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self->button_item)))
{
- gtk_list_item_widget_update (GTK_LIST_ITEM_WIDGET (self->button_item),
- selected,
- gtk_single_selection_get_selected_item (GTK_SINGLE_SELECTION (self->selection)),
- FALSE);
+ gtk_list_item_base_update (GTK_LIST_ITEM_BASE (self->button_item),
+ selected,
+ gtk_single_selection_get_selected_item (GTK_SINGLE_SELECTION (self->selection)),
+ FALSE);
}
/* reset the filter so positions are 1-1 */
item = gtk_single_selection_get_selected_item (GTK_SINGLE_SELECTION (self->selection));
- if (item != gtk_list_item_widget_get_item (GTK_LIST_ITEM_WIDGET (self->button_item)))
+ if (item != gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self->button_item)))
{
- gtk_list_item_widget_update (GTK_LIST_ITEM_WIDGET (self->button_item),
- gtk_single_selection_get_selected (GTK_SINGLE_SELECTION (self->selection)),
- item,
- FALSE);
+ gtk_list_item_base_update (GTK_LIST_ITEM_BASE (self->button_item),
+ gtk_single_selection_get_selected (GTK_SINGLE_SELECTION (self->selection)),
+ item,
+ FALSE);
}
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED_ITEM]);
GTK_WIDGET_CLASS (gtk_list_base_parent_class)->set_focus_child (widget, child);
- if (!GTK_IS_LIST_ITEM_WIDGET (child))
+ if (!GTK_IS_LIST_ITEM_BASE (child))
return;
- pos = gtk_list_item_widget_get_position (GTK_LIST_ITEM_WIDGET (child));
+ pos = gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (child));
if (pos != gtk_list_item_tracker_get_position (priv->item_manager, priv->focus))
{
case PROP_ITEM:
if (self->owner)
- g_value_set_object (value, gtk_list_item_widget_get_item (self->owner));
+ g_value_set_object (value, gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self->owner)));
break;
case PROP_POSITION:
if (self->owner)
- g_value_set_uint (value, gtk_list_item_widget_get_position (self->owner));
+ g_value_set_uint (value, gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self->owner)));
else
g_value_set_uint (value, GTK_INVALID_LIST_POSITION);
break;
case PROP_SELECTED:
if (self->owner)
- g_value_set_boolean (value, gtk_list_item_widget_get_selected (self->owner));
+ g_value_set_boolean (value, gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self->owner)));
else
g_value_set_boolean (value, FALSE);
break;
if (self->owner == NULL)
return NULL;
- return gtk_list_item_widget_get_item (self->owner);
+ return gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self->owner));
}
/**
if (self->owner == NULL)
return GTK_INVALID_LIST_POSITION;
- return gtk_list_item_widget_get_position (self->owner);
+ return gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self->owner));
}
/**
if (self->owner == NULL)
return FALSE;
- return gtk_list_item_widget_get_selected (self->owner);
+ return gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self->owner));
}
/**
--- /dev/null
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "config.h"
+
+#include "gtklistitembaseprivate.h"
+
+#include "gtkaccessible.h"
+
+typedef struct _GtkListItemBasePrivate GtkListItemBasePrivate;
+struct _GtkListItemBasePrivate
+{
+ GObject *item;
+ guint position;
+ gboolean selected;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkListItemBase, gtk_list_item_base, GTK_TYPE_WIDGET)
+
+static void
+gtk_list_item_base_default_update (GtkListItemBase *self,
+ guint position,
+ gpointer item,
+ gboolean selected)
+{
+ GtkListItemBasePrivate *priv = gtk_list_item_base_get_instance_private (self);
+
+ g_set_object (&priv->item, item);
+ priv->position = position;
+ priv->selected = selected;
+}
+
+static void
+gtk_list_item_base_dispose (GObject *object)
+{
+ GtkListItemBase *self = GTK_LIST_ITEM_BASE (object);
+ GtkListItemBasePrivate *priv = gtk_list_item_base_get_instance_private (self);
+
+ g_clear_object (&priv->item);
+
+ G_OBJECT_CLASS (gtk_list_item_base_parent_class)->dispose (object);
+}
+
+static void
+gtk_list_item_base_class_init (GtkListItemBaseClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ klass->update = gtk_list_item_base_default_update;
+
+ gobject_class->dispose = gtk_list_item_base_dispose;
+}
+
+static void
+gtk_list_item_base_init (GtkListItemBase *self)
+{
+}
+
+void
+gtk_list_item_base_update (GtkListItemBase *self,
+ guint position,
+ gpointer item,
+ gboolean selected)
+{
+ GtkListItemBasePrivate *priv = gtk_list_item_base_get_instance_private (self);
+ gboolean was_selected;
+
+ was_selected = priv->selected;
+
+ GTK_LIST_ITEM_BASE_GET_CLASS (self)->update (self, position, item, selected);
+
+ /* don't look at selected variable, it's not reentrancy safe */
+ if (was_selected != priv->selected)
+ {
+ if (priv->selected)
+ gtk_widget_set_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_SELECTED, FALSE);
+ else
+ gtk_widget_unset_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_SELECTED);
+
+ gtk_accessible_update_state (GTK_ACCESSIBLE (self),
+ GTK_ACCESSIBLE_STATE_SELECTED, priv->selected,
+ -1);
+ }
+}
+
+guint
+gtk_list_item_base_get_position (GtkListItemBase *self)
+{
+ GtkListItemBasePrivate *priv = gtk_list_item_base_get_instance_private (self);
+
+ return priv->position;
+}
+
+gpointer
+gtk_list_item_base_get_item (GtkListItemBase *self)
+{
+ GtkListItemBasePrivate *priv = gtk_list_item_base_get_instance_private (self);
+
+ return priv->item;
+}
+
+gboolean
+gtk_list_item_base_get_selected (GtkListItemBase *self)
+{
+ GtkListItemBasePrivate *priv = gtk_list_item_base_get_instance_private (self);
+
+ return priv->selected;
+}
+
--- /dev/null
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#ifndef __GTK_LIST_ITEM_BASE_PRIVATE_H__
+#define __GTK_LIST_ITEM_BASE_PRIVATE_H__
+
+#include "gtkwidget.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_LIST_ITEM_BASE (gtk_list_item_base_get_type ())
+#define GTK_LIST_ITEM_BASE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_LIST_ITEM_BASE, GtkListItemBase))
+#define GTK_LIST_ITEM_BASE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_LIST_ITEM_BASE, GtkListItemBaseClass))
+#define GTK_IS_LIST_ITEM_BASE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_LIST_ITEM_BASE))
+#define GTK_IS_LIST_ITEM_BASE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_LIST_ITEM_BASE))
+#define GTK_LIST_ITEM_BASE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_LIST_ITEM_BASE, GtkListItemBaseClass))
+
+typedef struct _GtkListItemBase GtkListItemBase;
+typedef struct _GtkListItemBaseClass GtkListItemBaseClass;
+
+struct _GtkListItemBase
+{
+ GtkWidget parent_instance;
+};
+
+struct _GtkListItemBaseClass
+{
+ GtkWidgetClass parent_class;
+
+ void (* update) (GtkListItemBase *self,
+ guint position,
+ gpointer item,
+ gboolean selected);
+};
+
+GType gtk_list_item_base_get_type (void) G_GNUC_CONST;
+
+void gtk_list_item_base_update (GtkListItemBase *self,
+ guint position,
+ gpointer item,
+ gboolean selected);
+
+guint gtk_list_item_base_get_position (GtkListItemBase *self);
+gpointer gtk_list_item_base_get_item (GtkListItemBase *self);
+gboolean gtk_list_item_base_get_selected (GtkListItemBase *self);
+
+G_END_DECLS
+
+#endif /* __GTK_LIST_ITEM_BASE_PRIVATE_H__ */
#include "gtklistitemmanagerprivate.h"
+#include "gtklistitembaseprivate.h"
#include "gtklistitemwidgetprivate.h"
#include "gtkwidgetprivate.h"
struct _GtkListItemTracker
{
guint position;
- GtkListItemWidget *widget;
+ GtkListItemBase *widget;
guint n_before;
guint n_after;
};
if (tracker->widget == NULL)
continue;
- if (g_hash_table_lookup (change, gtk_list_item_widget_get_item (tracker->widget)))
+ if (g_hash_table_lookup (change, gtk_list_item_base_get_item (tracker->widget)))
break;
}
}
else if (tracker->position >= position)
{
- if (g_hash_table_lookup (change, gtk_list_item_widget_get_item (tracker->widget)))
+ if (g_hash_table_lookup (change, gtk_list_item_base_get_item (tracker->widget)))
{
/* The item is gone. Guess a good new position */
tracker->position = position + (tracker->position - position) * added / removed;
/* item was put in its right place in the expensive loop above,
* and we updated its position while at it. So grab it from there.
*/
- tracker->position = gtk_list_item_widget_get_position (tracker->widget);
+ tracker->position = gtk_list_item_base_get_position (tracker->widget);
}
}
else
tile = gtk_list_item_manager_get_nth (self, tracker->position, NULL);
g_assert (tile != NULL);
g_assert (tile->widget);
- tracker->widget = GTK_LIST_ITEM_WIDGET (tile->widget);
+ tracker->widget = GTK_LIST_ITEM_BASE (tile->widget);
}
g_hash_table_unref (change);
tile = gtk_list_item_manager_get_nth (self, tracker->position, NULL);
g_assert (tile);
- tracker->widget = GTK_LIST_ITEM_WIDGET (tile->widget);
+ tracker->widget = GTK_LIST_ITEM_BASE (tile->widget);
}
}
item = g_list_model_get_item (G_LIST_MODEL (self->model), position);
selected = gtk_selection_model_is_selected (self->model, position);
- gtk_list_item_widget_update (GTK_LIST_ITEM_WIDGET (result), position, item, selected);
+ gtk_list_item_base_update (GTK_LIST_ITEM_BASE (result), position, item, selected);
g_object_unref (item);
gtk_widget_insert_after (result, self->widget, prev_sibling);
item = g_list_model_get_item (G_LIST_MODEL (self->model), position);
if (g_hash_table_steal_extended (change, item, NULL, (gpointer *) &result))
{
- GtkListItemWidget *list_item = GTK_LIST_ITEM_WIDGET (result);
- gtk_list_item_widget_update (list_item,
- position,
- gtk_list_item_widget_get_item (list_item),
- gtk_selection_model_is_selected (self->model, position));
+ GtkListItemBase *list_item = GTK_LIST_ITEM_BASE (result);
+ gtk_list_item_base_update (list_item,
+ position,
+ gtk_list_item_base_get_item (list_item),
+ gtk_selection_model_is_selected (self->model, position));
gtk_widget_insert_after (result, self->widget, prev_sibling);
/* XXX: Should we let the listview do this? */
gtk_widget_queue_resize (result);
item = g_list_model_get_item (G_LIST_MODEL (self->model), position);
selected = gtk_selection_model_is_selected (self->model, position);
- gtk_list_item_widget_update (GTK_LIST_ITEM_WIDGET (list_item),
- position,
- item,
- selected);
+ gtk_list_item_base_update (GTK_LIST_ITEM_BASE (list_item),
+ position,
+ item,
+ selected);
gtk_widget_insert_after (list_item, _gtk_widget_get_parent (list_item), prev_sibling);
g_object_unref (item);
}
GtkWidget *item,
guint position)
{
- GtkListItemWidget *list_item = GTK_LIST_ITEM_WIDGET (item);
+ GtkListItemBase *list_item = GTK_LIST_ITEM_BASE (item);
gboolean selected;
g_return_if_fail (GTK_IS_LIST_ITEM_MANAGER (self));
- g_return_if_fail (GTK_IS_LIST_ITEM_WIDGET (item));
+ g_return_if_fail (GTK_IS_LIST_ITEM_BASE (item));
selected = gtk_selection_model_is_selected (self->model, position);
- gtk_list_item_widget_update (list_item,
- position,
- gtk_list_item_widget_get_item (list_item),
- selected);
+ gtk_list_item_base_update (list_item,
+ position,
+ gtk_list_item_base_get_item (list_item),
+ selected);
}
/*
GtkWidget *item)
{
g_return_if_fail (GTK_IS_LIST_ITEM_MANAGER (self));
- g_return_if_fail (GTK_IS_LIST_ITEM_WIDGET (item));
+ g_return_if_fail (GTK_IS_LIST_ITEM_BASE (item));
if (change != NULL)
{
- if (!g_hash_table_replace (change, gtk_list_item_widget_get_item (GTK_LIST_ITEM_WIDGET (item)), item))
+ if (!g_hash_table_replace (change, gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (item)), item))
{
g_warning ("Duplicate item detected in list. Picking one randomly.");
}
tile = gtk_list_item_manager_get_nth (self, position, NULL);
if (tile)
- tracker->widget = GTK_LIST_ITEM_WIDGET (tile->widget);
+ tracker->widget = GTK_LIST_ITEM_BASE (tile->widget);
gtk_widget_queue_resize (self->widget);
}
GtkListItemFactory *factory;
GtkListItem *list_item;
- GObject *item;
- guint position;
- gboolean selected;
gboolean single_click_activate;
};
LAST_SIGNAL
};
-G_DEFINE_TYPE_WITH_PRIVATE (GtkListItemWidget, gtk_list_item_widget, GTK_TYPE_WIDGET)
+G_DEFINE_TYPE_WITH_PRIVATE (GtkListItemWidget, gtk_list_item_widget, GTK_TYPE_LIST_ITEM_BASE)
static GParamSpec *properties[N_PROPS] = { NULL, };
static guint signals[LAST_SIGNAL] = { 0 };
gtk_widget_activate_action (GTK_WIDGET (self),
"list.activate-item",
"u",
- priv->position);
+ gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)));
}
static gboolean
gtk_list_item_widget_set_activatable (self, list_item->activatable);
gtk_list_item_do_notify (list_item,
- priv->item != NULL,
- priv->position != GTK_INVALID_LIST_POSITION,
- priv->selected);
+ 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_list_item_factory_setup (priv->factory,
G_OBJECT (list_item),
- priv->item != NULL,
+ gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL,
gtk_list_item_widget_setup_func,
self);
gtk_list_item_widget_set_activatable (self, FALSE);
gtk_list_item_do_notify (list_item,
- priv->item != NULL,
- priv->position != GTK_INVALID_LIST_POSITION,
- priv->selected);
+ 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_list_item_set_child (list_item, NULL);
}
gtk_list_item_factory_teardown (priv->factory,
G_OBJECT (list_item),
- priv->item != NULL,
+ gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL,
gtk_list_item_widget_teardown_func,
self);
g_object_unref (list_item);
}
+typedef struct {
+ GtkListItemWidget *widget;
+ guint position;
+ gpointer item;
+ gboolean selected;
+} GtkListItemWidgetUpdate;
+
+static void
+gtk_list_item_widget_update_func (gpointer object,
+ gpointer data)
+{
+ GtkListItemWidgetUpdate *update = data;
+ 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;
+ GtkListItemWidget *self = update->widget;
+ GtkListItemBase *base = GTK_LIST_ITEM_BASE (self);
+
+ /* FIXME: It's kinda evil to notify external objects from here... */
+ notify_item = gtk_list_item_base_get_item (base) != update->item;
+ notify_position = gtk_list_item_base_get_position (base) != update->position;
+ notify_selected = gtk_list_item_base_get_selected (base) != update->selected;
+
+ GTK_LIST_ITEM_BASE_CLASS (gtk_list_item_widget_parent_class)->update (base,
+ update->position,
+ update->item,
+ update->selected);
+ if (list_item)
+ gtk_list_item_do_notify (list_item, notify_item, notify_position, notify_selected);
+}
+
+static void
+gtk_list_item_widget_update (GtkListItemBase *base,
+ guint position,
+ gpointer item,
+ gboolean selected)
+{
+ GtkListItemWidget *self = GTK_LIST_ITEM_WIDGET (base);
+ GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
+ GtkListItemWidgetUpdate update = { self, position, item, selected };
+
+ if (priv->list_item)
+ {
+ gtk_list_item_factory_update (priv->factory,
+ G_OBJECT (priv->list_item),
+ gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL,
+ item != NULL,
+ gtk_list_item_widget_update_func,
+ &update);
+ }
+ else
+ {
+ gtk_list_item_widget_update_func (NULL, &update);
+ }
+}
+
static void
gtk_list_item_widget_root (GtkWidget *widget)
{
g_assert (priv->list_item == NULL);
- g_clear_object (&priv->item);
g_clear_object (&priv->factory);
G_OBJECT_CLASS (gtk_list_item_widget_parent_class)->dispose (object);
gtk_widget_activate_action (GTK_WIDGET (self),
"list.select-item",
"(ubb)",
- priv->position, modify, extend);
+ gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)), modify, extend);
}
static void
const char *action_name,
GVariant *parameter)
{
- GtkListItemWidget *self = GTK_LIST_ITEM_WIDGET (widget);
- GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
-
- gtk_widget_activate_action (GTK_WIDGET (self),
+ gtk_widget_activate_action (widget,
"list.scroll-to-item",
"u",
- priv->position);
+ gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (widget)));
}
static void
gtk_list_item_widget_class_init (GtkListItemWidgetClass *klass)
{
+ GtkListItemBaseClass *base_class = GTK_LIST_ITEM_BASE_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
klass->activate_signal = gtk_list_item_widget_activate_signal;
+ base_class->update = gtk_list_item_widget_update;
+
widget_class->focus = gtk_list_item_widget_focus;
widget_class->grab_focus = gtk_list_item_widget_grab_focus;
widget_class->root = gtk_list_item_widget_root;
gtk_widget_activate_action (GTK_WIDGET (self),
"list.activate-item",
"u",
- priv->position);
+ gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)));
}
}
gtk_widget_activate_action (GTK_WIDGET (self),
"list.activate-item",
"u",
- priv->position);
+ gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)));
return;
}
}
gtk_widget_activate_action (GTK_WIDGET (self),
"list.select-item",
"(ubb)",
- priv->position, modify, extend);
+ gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)), modify, extend);
}
}
gtk_widget_activate_action (GTK_WIDGET (self),
"list.select-item",
"(ubb)",
- priv->position, FALSE, FALSE);
+ gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)), FALSE, FALSE);
}
}
NULL);
}
-typedef struct {
- GtkListItemWidget *widget;
- guint position;
- gpointer item;
- gboolean selected;
-} GtkListItemWidgetUpdate;
-
-static void
-gtk_list_item_widget_update_func (gpointer object,
- gpointer data)
-{
- GtkListItemWidgetUpdate *update = data;
- 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;
- GtkListItemWidget *self = update->widget;
- GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
-
- /* FIXME: It's kinda evil to notify external objects from here... */
-
- if (g_set_object (&priv->item, update->item))
- notify_item = TRUE;
-
- if (priv->position != update->position)
- {
- priv->position = update->position;
- notify_position = TRUE;
- }
-
- if (priv->selected != update->selected)
- {
- priv->selected = update->selected;
- notify_selected = TRUE;
- }
-
- if (list_item)
- gtk_list_item_do_notify (list_item, notify_item, notify_position, notify_selected);
-}
-
-void
-gtk_list_item_widget_update (GtkListItemWidget *self,
- guint position,
- gpointer item,
- gboolean selected)
-{
- GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
- GtkListItemWidgetUpdate update = { self, position, item, selected };
- gboolean was_selected;
-
- was_selected = priv->selected;
-
- if (priv->list_item)
- {
- gtk_list_item_factory_update (priv->factory,
- G_OBJECT (priv->list_item),
- priv->item != NULL,
- item != NULL,
- gtk_list_item_widget_update_func,
- &update);
- }
- else
- {
- gtk_list_item_widget_update_func (NULL, &update);
- }
-
- /* don't look at selected variable, it's not reentrancy safe */
- if (was_selected != priv->selected)
- {
- if (priv->selected)
- gtk_widget_set_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_SELECTED, FALSE);
- else
- gtk_widget_unset_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_SELECTED);
-
- gtk_accessible_update_state (GTK_ACCESSIBLE (self),
- GTK_ACCESSIBLE_STATE_SELECTED, priv->selected,
- -1);
- }
-}
-
void
gtk_list_item_widget_set_factory (GtkListItemWidget *self,
GtkListItemFactory *factory)
return priv->list_item;
}
-guint
-gtk_list_item_widget_get_position (GtkListItemWidget *self)
-{
- GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
-
- return priv->position;
-}
-
-gpointer
-gtk_list_item_widget_get_item (GtkListItemWidget *self)
-{
- GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
-
- return priv->item;
-}
-
-gboolean
-gtk_list_item_widget_get_selected (GtkListItemWidget *self)
-{
- GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
-
- return priv->selected;
-}
-
#ifndef __GTK_LIST_ITEM_WIDGET_PRIVATE_H__
#define __GTK_LIST_ITEM_WIDGET_PRIVATE_H__
+#include "gtklistitembaseprivate.h"
+
#include "gtklistitemfactory.h"
-#include "gtkwidget.h"
G_BEGIN_DECLS
struct _GtkListItemWidget
{
- GtkWidget parent_instance;
+ GtkListItemBase parent_instance;
};
struct _GtkListItemWidgetClass
{
- GtkWidgetClass parent_class;
+ GtkListItemBaseClass parent_class;
void (* activate_signal) (GtkListItemWidget *self);
};
const char *css_name,
GtkAccessibleRole role);
-void gtk_list_item_widget_update (GtkListItemWidget *self,
- guint position,
- gpointer item,
- gboolean selected);
GtkListItem * gtk_list_item_widget_get_list_item (GtkListItemWidget *self);
void gtk_list_item_widget_set_factory (GtkListItemWidget *self,
void gtk_list_item_widget_remove_child (GtkListItemWidget *self,
GtkWidget *child);
-guint gtk_list_item_widget_get_position (GtkListItemWidget *self);
-gpointer gtk_list_item_widget_get_item (GtkListItemWidget *self);
-gboolean gtk_list_item_widget_get_selected (GtkListItemWidget *self);
-
G_END_DECLS
#endif /* __GTK_LIST_ITEM_WIDGET_PRIVATE_H__ */
'gtklinkbutton.c',
'gtklistbox.c',
'gtklistitem.c',
+ 'gtklistitembase.c',
'gtklistitemfactory.c',
'gtklistitemmanager.c',
'gtklistitemwidget.c',