[gtk/wip/otte/listview: 322/327] listview: Add selection properties to ListItem
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/listview: 322/327] listview: Add selection properties to ListItem
- Date: Fri, 4 Jan 2019 23:37:42 +0000 (UTC)
commit 498351784c4ac5dc045c5672a31135cd918cc4f3
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 | 131 ++++++++++++++++++++++++++++++++++-
gtk/gtklistitem.h | 8 +++
gtk/gtklistitemfactory.c | 12 +++-
gtk/gtklistitemfactoryprivate.h | 6 +-
gtk/gtklistitemmanager.c | 8 +--
gtk/gtklistitemprivate.h | 2 +
7 files changed, 161 insertions(+), 9 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index a852649c52..00cba2b9a6 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -448,6 +448,9 @@ gtk_list_box_row_get_type
GtkListItem
gtk_list_item_get_item
gtk_list_item_get_position
+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 e72067b48b..959b152331 100644
--- a/gtk/gtklistitem.c
+++ b/gtk/gtklistitem.c
@@ -53,6 +53,9 @@ struct _GtkListItem
GObject *item;
guint position;
+
+ guint selectable : 1;
+ guint selected : 1;
};
enum
@@ -60,6 +63,8 @@ enum
PROP_0,
PROP_ITEM,
PROP_POSITION,
+ PROP_SELECTABLE,
+ PROP_SELECTED,
N_PROPS
};
@@ -96,6 +101,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;
@@ -108,10 +121,14 @@ gtk_list_item_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
- //GtkListItem *self = GTK_LIST_ITEM (object);
+ GtkListItem *self = GTK_LIST_ITEM (object);
switch (property_id)
{
+ 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;
@@ -152,6 +169,30 @@ gtk_list_item_class_init (GtkListItemClass *klass)
0, G_MAXUINT, 0,
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 */
@@ -162,6 +203,8 @@ static void
gtk_list_item_init (GtkListItem *self)
{
gtk_widget_set_has_surface (GTK_WIDGET (self), FALSE);
+
+ self->selectable = TRUE;
}
GtkWidget *
@@ -239,3 +282,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 5e977f35a5..107a1846cc 100644
--- a/gtk/gtklistitem.h
+++ b/gtk/gtklistitem.h
@@ -37,6 +37,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);
+
G_END_DECLS
diff --git a/gtk/gtklistitemfactory.c b/gtk/gtklistitemfactory.c
index c8e60bc163..454344ae9b 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
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]