listitemwidget: Add single-click-activate

Add a mode to GtkListItemWidget that activates on
single click and selects on hover. Make
GtkListItemManager set this on its items
when its own 'property' of the same name is set.
This commit is contained in:
Matthias Clasen 2019-12-13 20:56:32 -05:00
parent 21eac434c3
commit 69c86ae385
4 changed files with 91 additions and 1 deletions

View File

@ -33,6 +33,7 @@ struct _GtkListItemManager
GtkWidget *widget;
GtkSelectionModel *model;
GtkListItemFactory *factory;
gboolean single_click_activate;
const char *item_css_name;
GtkRbTree *items;
@ -932,6 +933,8 @@ gtk_list_item_manager_acquire_list_item (GtkListItemManager *self,
result = gtk_list_item_widget_new (self->factory,
self->item_css_name);
gtk_list_item_widget_set_single_click_activate (GTK_LIST_ITEM_WIDGET (result), self->single_click_activate);
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);
@ -1079,6 +1082,33 @@ gtk_list_item_manager_release_list_item (GtkListItemManager *self,
gtk_widget_unparent (item);
}
void
gtk_list_item_manager_set_single_click_activate (GtkListItemManager *self,
gboolean single_click_activate)
{
GtkListItemManagerItem *item;
g_return_if_fail (GTK_IS_LIST_ITEM_MANAGER (self));
self->single_click_activate = single_click_activate;
for (item = gtk_rb_tree_get_first (self->items);
item != NULL;
item = gtk_rb_tree_node_get_next (item))
{
if (item->widget)
gtk_list_item_widget_set_single_click_activate (GTK_LIST_ITEM_WIDGET (item->widget), single_click_activate);
}
}
gboolean
gtk_list_item_manager_get_single_click_activate (GtkListItemManager *self)
{
g_return_val_if_fail (GTK_IS_LIST_ITEM_MANAGER (self), FALSE);
return self->single_click_activate;
}
GtkListItemTracker *
gtk_list_item_tracker_new (GtkListItemManager *self)
{

View File

@ -87,6 +87,11 @@ void gtk_list_item_manager_set_model (GtkListItemMana
GtkSelectionModel * gtk_list_item_manager_get_model (GtkListItemManager *self);
guint gtk_list_item_manager_get_size (GtkListItemManager *self);
void gtk_list_item_manager_set_single_click_activate
(GtkListItemManager *self,
gboolean single_click_activate);
gboolean gtk_list_item_manager_get_single_click_activate
(GtkListItemManager *self);
GtkListItemTracker * gtk_list_item_tracker_new (GtkListItemManager *self);
void gtk_list_item_tracker_free (GtkListItemManager *self,

View File

@ -24,6 +24,7 @@
#include "gtkbinlayout.h"
#include "gtkcssnodeprivate.h"
#include "gtkeventcontrollerfocus.h"
#include "gtkeventcontrollermotion.h"
#include "gtkgestureclick.h"
#include "gtkintl.h"
#include "gtklistitemfactoryprivate.h"
@ -42,11 +43,13 @@ struct _GtkListItemWidgetPrivate
GObject *item;
guint position;
gboolean selected;
gboolean single_click_activate;
};
enum {
PROP_0,
PROP_FACTORY,
PROP_SINGLE_CLICK_ACTIVATE,
N_PROPS
};
@ -161,6 +164,10 @@ gtk_list_item_widget_set_property (GObject *object,
gtk_list_item_widget_set_factory (self, g_value_get_object (value));
break;
case PROP_SINGLE_CLICK_ACTIVATE:
gtk_list_item_widget_set_single_click_activate (self, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@ -224,6 +231,13 @@ gtk_list_item_widget_class_init (GtkListItemWidgetClass *klass)
GTK_TYPE_LIST_ITEM_FACTORY,
G_PARAM_WRITABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_SINGLE_CLICK_ACTIVATE] =
g_param_spec_boolean ("single-click-activate",
"Single click activate",
"Activate on single click",
FALSE,
G_PARAM_WRITABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
signals[ACTIVATE_SIGNAL] =
@ -322,7 +336,7 @@ gtk_list_item_widget_click_gesture_pressed (GtkGestureClick *gesture,
if (!priv->list_item || priv->list_item->activatable)
{
if (n_press == 2)
if (n_press == 2 || priv->single_click_activate)
{
gtk_widget_activate_action (GTK_WIDGET (self),
"list.activate-item",
@ -350,6 +364,26 @@ gtk_list_item_widget_enter_cb (GtkEventControllerFocus *controller,
priv->position);
}
static void
gtk_list_item_widget_hover_cb (GtkEventControllerMotion *controller,
double x,
double y,
GtkListItemWidget *self)
{
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
if (!priv->single_click_activate)
return;
if (!priv->list_item || priv->list_item->selectable)
{
gtk_widget_activate_action (GTK_WIDGET (self),
"list.select-item",
"(ubb)",
priv->position, FALSE, FALSE);
}
}
static void
gtk_list_item_widget_click_gesture_released (GtkGestureClick *gesture,
int n_press,
@ -394,6 +428,10 @@ gtk_list_item_widget_init (GtkListItemWidget *self)
controller = gtk_event_controller_focus_new ();
g_signal_connect (controller, "enter", G_CALLBACK (gtk_list_item_widget_enter_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
controller = gtk_event_controller_motion_new ();
g_signal_connect (controller, "enter", G_CALLBACK (gtk_list_item_widget_hover_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
}
GtkWidget *
@ -528,6 +566,20 @@ gtk_list_item_widget_set_factory (GtkListItemWidget *self,
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]);
}
void
gtk_list_item_widget_set_single_click_activate (GtkListItemWidget *self,
gboolean single_click_activate)
{
GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
if (priv->single_click_activate == single_click_activate)
return;
priv->single_click_activate = single_click_activate;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SINGLE_CLICK_ACTIVATE]);
}
void
gtk_list_item_widget_add_child (GtkListItemWidget *self,
GtkWidget *child)

View File

@ -70,6 +70,9 @@ void gtk_list_item_widget_default_update (GtkListItemWidg
void gtk_list_item_widget_set_factory (GtkListItemWidget *self,
GtkListItemFactory *factory);
void gtk_list_item_widget_set_single_click_activate
(GtkListItemWidget *self,
gboolean single_click_activate);
void gtk_list_item_widget_add_child (GtkListItemWidget *self,
GtkWidget *child);
void gtk_list_item_widget_remove_child (GtkListItemWidget *self,