[gtk/wip/otte/listview: 23/113] listview: Add selection properties to ListItem
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/listview: 23/113] listview: Add selection properties to ListItem
- Date: Tue, 5 Nov 2019 17:34:15 +0000 (UTC)
commit 23cb6c320ceecb646a813cdc3a97d9b0097c5bb4
Author: Benjamin Otte <otte redhat com>
Date: Sat Sep 29 22:34:43 2018 +0200
listview: Add selection properties to ListItem
This just brings the infrastructure into place, we're not using the
properties yet.
docs/reference/gtk/gtk4-sections.txt | 3 +
gtk/gtklistitem.c | 128 +++++++++++++++++++++++++++++++++++
gtk/gtklistitem.h | 8 +++
gtk/gtklistitemfactory.c | 13 +++-
gtk/gtklistitemfactoryprivate.h | 6 +-
gtk/gtklistitemmanager.c | 8 +--
gtk/gtklistitemprivate.h | 2 +
7 files changed, 160 insertions(+), 8 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 37e154b0da..68c057beaf 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -501,6 +501,9 @@ gtk_list_item_get_item
gtk_list_item_get_position
gtk_list_item_get_child
gtk_list_item_set_child
+gtk_list_item_get_selected
+gtk_list_item_get_selectable
+gtk_list_item_set_selectable
<SUBSECTION Standard>
GTK_LIST_ITEM
GTK_LIST_ITEM_CLASS
diff --git a/gtk/gtklistitem.c b/gtk/gtklistitem.c
index 7bc294ca33..d4daec987e 100644
--- a/gtk/gtklistitem.c
+++ b/gtk/gtklistitem.c
@@ -57,6 +57,9 @@ struct _GtkListItem
GObject *item;
GtkWidget *child;
guint position;
+
+ guint selectable : 1;
+ guint selected : 1;
};
struct _GtkListItemClass
@@ -70,6 +73,8 @@ enum
PROP_CHILD,
PROP_ITEM,
PROP_POSITION,
+ PROP_SELECTABLE,
+ PROP_SELECTED,
N_PROPS
};
@@ -111,6 +116,14 @@ gtk_list_item_get_property (GObject *object,
g_value_set_uint (value, self->position);
break;
+ case PROP_SELECTABLE:
+ g_value_set_boolean (value, self->selectable);
+ break;
+
+ case PROP_SELECTED:
+ g_value_set_boolean (value, self->selected);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -131,6 +144,10 @@ gtk_list_item_set_property (GObject *object,
gtk_list_item_set_child (self, g_value_get_object (value));
break;
+ case PROP_SELECTABLE:
+ gtk_list_item_set_selectable (self, g_value_get_boolean (value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -183,6 +200,30 @@ gtk_list_item_class_init (GtkListItemClass *klass)
0, G_MAXUINT, GTK_INVALID_LIST_POSITION,
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+ /**
+ * GtkListItem:selectable:
+ *
+ * If the item can be selected by the user
+ */
+ properties[PROP_SELECTABLE] =
+ g_param_spec_boolean ("selectable",
+ P_("Selectable"),
+ P_("If the item can be selected by the user"),
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * GtkListItem:selected:
+ *
+ * If the item is currently selected
+ */
+ properties[PROP_SELECTED] =
+ g_param_spec_boolean ("selected",
+ P_("Selected"),
+ P_("If the item is currently selected"),
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (gobject_class, N_PROPS, properties);
/* This gets overwritten by gtk_list_item_new() but better safe than sorry */
@@ -193,6 +234,7 @@ gtk_list_item_class_init (GtkListItemClass *klass)
static void
gtk_list_item_init (GtkListItem *self)
{
+ self->selectable = TRUE;
}
GtkWidget *
@@ -319,3 +361,89 @@ gtk_list_item_set_position (GtkListItem *self,
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_POSITION]);
}
+/**
+ * gtk_list_item_get_selected:
+ * @self: a #GtkListItem
+ *
+ * Checks if the item is displayed as selected. The selected state is
+ * maintained by the container and its list model and cannot be set
+ * otherwise.
+ *
+ * Returns: %TRUE if the item is selected.
+ **/
+gboolean
+gtk_list_item_get_selected (GtkListItem *self)
+{
+ g_return_val_if_fail (GTK_IS_LIST_ITEM (self), FALSE);
+
+ return self->selected;
+}
+
+void
+gtk_list_item_set_selected (GtkListItem *self,
+ gboolean selected)
+{
+ g_return_if_fail (GTK_IS_LIST_ITEM (self));
+
+ if (self->selected == selected)
+ return;
+
+ self->selected = selected;
+
+ if (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);
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTED]);
+}
+
+/**
+ * gtk_list_item_get_selectable:
+ * @self: a #GtkListItem
+ *
+ * Checks if a list item has been set to be selectable via
+ * gtk_list_item_set_selectable().
+ *
+ * Do not confuse this function with gtk_list_item_get_selected().
+ *
+ * Returns: %TRUE if the item is selectable
+ **/
+gboolean
+gtk_list_item_get_selectable (GtkListItem *self)
+{
+ g_return_val_if_fail (GTK_IS_LIST_ITEM (self), FALSE);
+
+ return self->selectable;
+}
+
+/**
+ * gtk_list_item_set_selectable:
+ * @self: a #GtkListItem
+ * @selectable: if the item should be selectable
+ *
+ * Sets @self to be selectable. If an item is selectable, clicking
+ * on the item or using the keyboard will try to select or unselect
+ * the item. If this succeeds is up to the model to determine, as
+ * it is managing the selected state.
+ *
+ * Note that this means that making an item non-selectable has no
+ * influence on the selected state at all. A non-selectable item
+ * may still be selected.
+ *
+ * By default, list items are selectable. When rebinding them to
+ * a new item, they will also be reset to be selectable by GTK.
+ **/
+void
+gtk_list_item_set_selectable (GtkListItem *self,
+ gboolean selectable)
+{
+ g_return_if_fail (GTK_IS_LIST_ITEM (self));
+
+ if (self->selectable == selectable)
+ return;
+
+ self->selectable = selectable;
+
+ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTABLE]);
+}
diff --git a/gtk/gtklistitem.h b/gtk/gtklistitem.h
index dff9c889ee..4cfadd8996 100644
--- a/gtk/gtklistitem.h
+++ b/gtk/gtklistitem.h
@@ -72,6 +72,14 @@ GDK_AVAILABLE_IN_ALL
gpointer gtk_list_item_get_item (GtkListItem *self);
GDK_AVAILABLE_IN_ALL
guint gtk_list_item_get_position (GtkListItem *self);
+GDK_AVAILABLE_IN_ALL
+gboolean gtk_list_item_get_selected (GtkListItem *self);
+GDK_AVAILABLE_IN_ALL
+gboolean gtk_list_item_get_selectable (GtkListItem *self);
+GDK_AVAILABLE_IN_ALL
+void gtk_list_item_set_selectable (GtkListItem *self,
+ gboolean selectable);
+
GDK_AVAILABLE_IN_ALL
void gtk_list_item_set_child (GtkListItem *self,
diff --git a/gtk/gtklistitemfactory.c b/gtk/gtklistitemfactory.c
index c8e60bc163..6b7c2b3550 100644
--- a/gtk/gtklistitemfactory.c
+++ b/gtk/gtklistitemfactory.c
@@ -104,7 +104,8 @@ void
gtk_list_item_factory_bind (GtkListItemFactory *self,
GtkListItem *list_item,
guint position,
- gpointer item)
+ gpointer item,
+ gboolean selected)
{
g_return_if_fail (GTK_IS_LIST_ITEM_FACTORY (self));
g_return_if_fail (GTK_IS_LIST_ITEM (list_item));
@@ -113,6 +114,7 @@ gtk_list_item_factory_bind (GtkListItemFactory *self,
gtk_list_item_set_item (list_item, item);
gtk_list_item_set_position (list_item, position);
+ gtk_list_item_set_selected (list_item, selected);
if (self->bind_func)
self->bind_func (list_item, self->user_data);
@@ -123,12 +125,18 @@ gtk_list_item_factory_bind (GtkListItemFactory *self,
void
gtk_list_item_factory_update (GtkListItemFactory *self,
GtkListItem *list_item,
- guint position)
+ guint position,
+ gboolean selected)
{
g_return_if_fail (GTK_IS_LIST_ITEM_FACTORY (self));
g_return_if_fail (GTK_IS_LIST_ITEM (list_item));
+ g_object_freeze_notify (G_OBJECT (list_item));
+
gtk_list_item_set_position (list_item, position);
+ gtk_list_item_set_selected (list_item, selected);
+
+ g_object_thaw_notify (G_OBJECT (list_item));
}
void
@@ -142,6 +150,7 @@ gtk_list_item_factory_unbind (GtkListItemFactory *self,
gtk_list_item_set_item (list_item, NULL);
gtk_list_item_set_position (list_item, 0);
+ gtk_list_item_set_selected (list_item, FALSE);
g_object_thaw_notify (G_OBJECT (list_item));
}
diff --git a/gtk/gtklistitemfactoryprivate.h b/gtk/gtklistitemfactoryprivate.h
index 779251344b..3e815fa131 100644
--- a/gtk/gtklistitemfactoryprivate.h
+++ b/gtk/gtklistitemfactoryprivate.h
@@ -48,10 +48,12 @@ GtkListItem * gtk_list_item_factory_create (GtkListItemFact
void gtk_list_item_factory_bind (GtkListItemFactory *self,
GtkListItem *list_item,
guint position,
- gpointer item);
+ gpointer item,
+ gboolean selected);
void gtk_list_item_factory_update (GtkListItemFactory *self,
GtkListItem *list_item,
- guint position);
+ guint position,
+ gboolean selected);
void gtk_list_item_factory_unbind (GtkListItemFactory *self,
GtkListItem *list_item);
diff --git a/gtk/gtklistitemmanager.c b/gtk/gtklistitemmanager.c
index 62888f366a..1e74c8d8e1 100644
--- a/gtk/gtklistitemmanager.c
+++ b/gtk/gtklistitemmanager.c
@@ -262,7 +262,7 @@ gtk_list_item_manager_acquire_list_item (GtkListItemManager *self,
result = gtk_list_item_factory_create (self->factory);
item = g_list_model_get_item (self->model, position);
- gtk_list_item_factory_bind (self->factory, result, position, item);
+ gtk_list_item_factory_bind (self->factory, result, position, item, FALSE);
g_object_unref (item);
gtk_widget_insert_after (GTK_WIDGET (result), self->widget, prev_sibling);
@@ -300,7 +300,7 @@ gtk_list_item_manager_try_reacquire_list_item (GtkListItemManager *self,
item = g_list_model_get_item (self->model, position);
if (g_hash_table_steal_extended (change->items, item, NULL, (gpointer *) &result))
{
- gtk_list_item_factory_update (self->factory, result, position);
+ gtk_list_item_factory_update (self->factory, result, position, FALSE);
gtk_widget_insert_after (GTK_WIDGET (result), self->widget, prev_sibling);
/* XXX: Should we let the listview do this? */
gtk_widget_queue_resize (GTK_WIDGET (result));
@@ -336,7 +336,7 @@ gtk_list_item_manager_move_list_item (GtkListItemManager *self,
gpointer item;
item = g_list_model_get_item (self->model, position);
- gtk_list_item_factory_bind (self->factory, GTK_LIST_ITEM (list_item), position, item);
+ gtk_list_item_factory_bind (self->factory, GTK_LIST_ITEM (list_item), position, item, FALSE);
gtk_widget_insert_after (list_item, _gtk_widget_get_parent (list_item), prev_sibling);
g_object_unref (item);
}
@@ -358,7 +358,7 @@ gtk_list_item_manager_update_list_item (GtkListItemManager *self,
g_return_if_fail (GTK_IS_LIST_ITEM_MANAGER (self));
g_return_if_fail (GTK_IS_LIST_ITEM (item));
- gtk_list_item_factory_update (self->factory, GTK_LIST_ITEM (item), position);
+ gtk_list_item_factory_update (self->factory, GTK_LIST_ITEM (item), position, FALSE);
}
/*
diff --git a/gtk/gtklistitemprivate.h b/gtk/gtklistitemprivate.h
index f238685c76..08ed82f162 100644
--- a/gtk/gtklistitemprivate.h
+++ b/gtk/gtklistitemprivate.h
@@ -30,6 +30,8 @@ void gtk_list_item_set_item (GtkListItem
gpointer item);
void gtk_list_item_set_position (GtkListItem *self,
guint position);
+void gtk_list_item_set_selected (GtkListItem *self,
+ gboolean selected);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]