listitem: Add a press gesture to select the item
This requires a bunch of refactoring because so far the ListItem had no knowledge of the manager, but it needs the manager so it can access the selection to trigger the select/unselect operation.
This commit is contained in:
@@ -22,7 +22,9 @@
|
||||
#include "gtklistitemprivate.h"
|
||||
|
||||
#include "gtkcssnodeprivate.h"
|
||||
#include "gtkgesturemultipress.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
|
||||
/**
|
||||
@@ -53,6 +55,8 @@ struct _GtkListItem
|
||||
{
|
||||
GtkBin parent_instance;
|
||||
|
||||
GtkListItemManager *manager; /* no ref, the manager refs us */
|
||||
|
||||
GObject *item;
|
||||
guint position;
|
||||
|
||||
@@ -201,22 +205,101 @@ gtk_list_item_class_init (GtkListItemClass *klass)
|
||||
gtk_widget_class_set_css_name (widget_class, I_("row"));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
GtkListItem *self)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
GdkModifierType state;
|
||||
GdkModifierType mask;
|
||||
gboolean extend = FALSE, modify = FALSE;
|
||||
|
||||
if (!self->selectable)
|
||||
{
|
||||
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gtk_get_current_event_state (&state))
|
||||
{
|
||||
mask = gtk_widget_get_modifier_mask (widget, GDK_MODIFIER_INTENT_MODIFY_SELECTION);
|
||||
if ((state & mask) == mask)
|
||||
modify = TRUE;
|
||||
mask = gtk_widget_get_modifier_mask (widget, GDK_MODIFIER_INTENT_EXTEND_SELECTION);
|
||||
if ((state & mask) == mask)
|
||||
extend = TRUE;
|
||||
}
|
||||
|
||||
gtk_list_item_manager_select (self->manager, self, modify, extend);
|
||||
|
||||
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_ACTIVE, FALSE);
|
||||
|
||||
if (gtk_widget_get_focus_on_click (widget))
|
||||
gtk_widget_grab_focus (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_multipress_gesture_released (GtkGestureMultiPress *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
GtkListItem *self)
|
||||
{
|
||||
gtk_widget_unset_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_ACTIVE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_multipress_gesture_canceled (GtkGestureMultiPress *gesture,
|
||||
GdkEventSequence *sequence,
|
||||
GtkListItem *self)
|
||||
{
|
||||
gtk_widget_unset_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_ACTIVE);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_item_init (GtkListItem *self)
|
||||
{
|
||||
GtkGesture *gesture;
|
||||
|
||||
gtk_widget_set_has_surface (GTK_WIDGET (self), FALSE);
|
||||
|
||||
self->selectable = TRUE;
|
||||
gtk_widget_set_can_focus (GTK_WIDGET (self), TRUE);
|
||||
|
||||
gesture = gtk_gesture_multi_press_new ();
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
|
||||
GTK_PHASE_BUBBLE);
|
||||
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (gesture),
|
||||
FALSE);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture),
|
||||
GDK_BUTTON_PRIMARY);
|
||||
g_signal_connect (gesture, "pressed",
|
||||
G_CALLBACK (gtk_list_item_multipress_gesture_pressed), self);
|
||||
g_signal_connect (gesture, "released",
|
||||
G_CALLBACK (gtk_list_item_multipress_gesture_released), self);
|
||||
g_signal_connect (gesture, "cancel",
|
||||
G_CALLBACK (gtk_list_item_multipress_gesture_canceled), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (gesture));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_list_item_new (const char *css_name)
|
||||
GtkListItem *
|
||||
gtk_list_item_new (GtkListItemManager *manager,
|
||||
const char *css_name)
|
||||
{
|
||||
GtkListItem *result;
|
||||
|
||||
g_return_val_if_fail (css_name != NULL, NULL);
|
||||
|
||||
return g_object_new (GTK_TYPE_LIST_ITEM,
|
||||
"css-name", css_name,
|
||||
NULL);
|
||||
result = g_object_new (GTK_TYPE_LIST_ITEM,
|
||||
"css-name", css_name,
|
||||
NULL);
|
||||
|
||||
result->manager = manager;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -370,5 +453,7 @@ gtk_list_item_set_selectable (GtkListItem *self,
|
||||
|
||||
self->selectable = selectable;
|
||||
|
||||
gtk_widget_set_can_focus (GTK_WIDGET (self), self->selectable);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTABLE]);
|
||||
}
|
||||
|
||||
@@ -85,19 +85,14 @@ gtk_list_item_factory_new (GtkListItemSetupFunc setup_func,
|
||||
return self;
|
||||
}
|
||||
|
||||
GtkListItem *
|
||||
gtk_list_item_factory_create (GtkListItemFactory *self)
|
||||
void
|
||||
gtk_list_item_factory_setup (GtkListItemFactory *self,
|
||||
GtkListItem *list_item)
|
||||
{
|
||||
GtkWidget *result;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_LIST_ITEM_FACTORY (self), NULL);
|
||||
|
||||
result = gtk_list_item_new ("row");
|
||||
g_return_if_fail (GTK_IS_LIST_ITEM_FACTORY (self));
|
||||
|
||||
if (self->setup_func)
|
||||
self->setup_func (GTK_LIST_ITEM (result), self->user_data);
|
||||
|
||||
return GTK_LIST_ITEM (result);
|
||||
self->setup_func (list_item, self->user_data);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -43,7 +43,8 @@ GtkListItemFactory * gtk_list_item_factory_new (GtkListItemSetu
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_destroy);
|
||||
|
||||
GtkListItem * gtk_list_item_factory_create (GtkListItemFactory *self);
|
||||
void gtk_list_item_factory_setup (GtkListItemFactory *self,
|
||||
GtkListItem *list_item);
|
||||
|
||||
void gtk_list_item_factory_bind (GtkListItemFactory *self,
|
||||
GtkListItem *list_item,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "gtklistitemmanagerprivate.h"
|
||||
|
||||
#include "gtklistitemprivate.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
|
||||
struct _GtkListItemManager
|
||||
@@ -129,6 +130,27 @@ gtk_list_item_manager_get_model (GtkListItemManager *self)
|
||||
return self->model;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_list_item_manager_select (GtkListItemManager *self,
|
||||
GtkListItem *item,
|
||||
gboolean modify,
|
||||
gboolean extend)
|
||||
{
|
||||
guint pos = gtk_list_item_get_position (item);
|
||||
|
||||
if (modify)
|
||||
{
|
||||
if (gtk_list_item_get_selected (item))
|
||||
gtk_selection_model_unselect_item (self->model, pos);
|
||||
else
|
||||
gtk_selection_model_select_item (self->model, pos, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_selection_model_select_item (self->model, pos, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* gtk_list_item_manager_get_size:
|
||||
@@ -260,7 +282,8 @@ gtk_list_item_manager_acquire_list_item (GtkListItemManager *self,
|
||||
g_return_val_if_fail (GTK_IS_LIST_ITEM_MANAGER (self), NULL);
|
||||
g_return_val_if_fail (prev_sibling == NULL || GTK_IS_WIDGET (prev_sibling), NULL);
|
||||
|
||||
result = gtk_list_item_factory_create (self->factory);
|
||||
result = gtk_list_item_new (self, "row");
|
||||
gtk_list_item_factory_setup (self->factory, result);
|
||||
|
||||
item = g_list_model_get_item (G_LIST_MODEL (self->model), position);
|
||||
selected = gtk_selection_model_is_selected (self->model, position);
|
||||
|
||||
@@ -52,6 +52,11 @@ GtkSelectionModel * gtk_list_item_manager_get_model (GtkListItemMana
|
||||
|
||||
guint gtk_list_item_manager_get_size (GtkListItemManager *self);
|
||||
|
||||
void gtk_list_item_manager_select (GtkListItemManager *self,
|
||||
GtkListItem *item,
|
||||
gboolean modify,
|
||||
gboolean extend);
|
||||
|
||||
GtkListItemManagerChange *
|
||||
gtk_list_item_manager_begin_change (GtkListItemManager *self);
|
||||
void gtk_list_item_manager_end_change (GtkListItemManager *self,
|
||||
|
||||
@@ -22,9 +22,12 @@
|
||||
|
||||
#include "gtklistitem.h"
|
||||
|
||||
#include "gtklistitemmanagerprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GtkWidget * gtk_list_item_new (const char *css_name);
|
||||
GtkListItem * gtk_list_item_new (GtkListItemManager *manager,
|
||||
const char *css_name);
|
||||
|
||||
void gtk_list_item_set_item (GtkListItem *self,
|
||||
gpointer item);
|
||||
|
||||
Reference in New Issue
Block a user