[gtk+] listbox: Use multipress gesture for row selection/activation
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] listbox: Use multipress gesture for row selection/activation
- Date: Thu, 5 Jun 2014 14:16:44 +0000 (UTC)
commit 933ff62f66c01627b195ea9ef104e8d8d710c555
Author: Carlos Garnacho <carlosg gnome org>
Date: Thu Jun 5 15:40:02 2014 +0200
listbox: Use multipress gesture for row selection/activation
This gesture replaces the button_press/release_event handlers.
gtk/gtklistbox.c | 165 +++++++++++++++++++++++++++---------------------------
1 files changed, 82 insertions(+), 83 deletions(-)
---
diff --git a/gtk/gtklistbox.c b/gtk/gtklistbox.c
index 6bab1b5..2b5a1aa 100644
--- a/gtk/gtklistbox.c
+++ b/gtk/gtklistbox.c
@@ -85,6 +85,8 @@ typedef struct
GtkAdjustment *adjustment;
gboolean activate_single_click;
+ GtkGesture *multipress_gesture;
+
/* DnD */
GtkListBoxRow *drag_highlighted_row;
@@ -158,10 +160,6 @@ static gboolean gtk_list_box_leave_notify_event (GtkWidget
GdkEventCrossing *event);
static gboolean gtk_list_box_motion_notify_event (GtkWidget *widget,
GdkEventMotion *event);
-static gboolean gtk_list_box_button_press_event (GtkWidget *widget,
- GdkEventButton *event);
-static gboolean gtk_list_box_button_release_event (GtkWidget *widget,
- GdkEventButton *event);
static void gtk_list_box_show (GtkWidget *widget);
static gboolean gtk_list_box_focus (GtkWidget *widget,
GtkDirectionType direction);
@@ -225,6 +223,18 @@ static void gtk_list_box_select_all_between (GtkList
static gboolean gtk_list_box_unselect_all_internal (GtkListBox *box);
static void gtk_list_box_selected_rows_changed (GtkListBox *box);
+static void gtk_list_box_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
+ guint n_press,
+ gdouble x,
+ gdouble y,
+ GtkListBox *box);
+static void gtk_list_box_multipress_gesture_released (GtkGestureMultiPress *gesture,
+ guint n_press,
+ gdouble x,
+ gdouble y,
+ GtkListBox *box);
+
+
static GParamSpec *properties[LAST_PROPERTY] = { NULL, };
static guint signals[LAST_SIGNAL] = { 0 };
static guint row_signals[ROW__LAST_SIGNAL] = { 0 };
@@ -261,6 +271,18 @@ gtk_list_box_init (GtkListBox *box)
context = gtk_widget_get_style_context (widget);
gtk_style_context_add_class (context, GTK_STYLE_CLASS_LIST);
+
+ priv->multipress_gesture = gtk_gesture_multi_press_new (widget);
+ gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->multipress_gesture),
+ GTK_PHASE_BUBBLE);
+ gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->multipress_gesture),
+ FALSE);
+ gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (priv->multipress_gesture),
+ GDK_BUTTON_PRIMARY);
+ g_signal_connect (priv->multipress_gesture, "pressed",
+ G_CALLBACK (gtk_list_box_multipress_gesture_pressed), box);
+ g_signal_connect (priv->multipress_gesture, "released",
+ G_CALLBACK (gtk_list_box_multipress_gesture_released), box);
}
static void
@@ -344,8 +366,6 @@ gtk_list_box_class_init (GtkListBoxClass *klass)
widget_class->enter_notify_event = gtk_list_box_enter_notify_event;
widget_class->leave_notify_event = gtk_list_box_leave_notify_event;
widget_class->motion_notify_event = gtk_list_box_motion_notify_event;
- widget_class->button_press_event = gtk_list_box_button_press_event;
- widget_class->button_release_event = gtk_list_box_button_release_event;
widget_class->show = gtk_list_box_show;
widget_class->focus = gtk_list_box_focus;
widget_class->draw = gtk_list_box_draw;
@@ -1646,51 +1666,31 @@ gtk_list_box_motion_notify_event (GtkWidget *widget,
return FALSE;
}
-static gboolean
-gtk_list_box_button_press_event (GtkWidget *widget,
- GdkEventButton *event)
+static void
+gtk_list_box_multipress_gesture_pressed (GtkGestureMultiPress *gesture,
+ guint n_press,
+ gdouble x,
+ gdouble y,
+ GtkListBox *box)
{
- GtkListBox *box = GTK_LIST_BOX (widget);
GtkListBoxPrivate *priv = BOX_PRIV (box);
- gboolean retval = GDK_EVENT_PROPAGATE;
- GdkWindow *window;
- double x, y;
-
- if (event->button == GDK_BUTTON_PRIMARY)
- {
- GtkListBoxRow *row;
-
- priv->active_row = NULL;
+ GtkListBoxRow *row;
- window = event->window;
- x = event->x;
- y = event->y;
+ priv->active_row = NULL;
+ row = gtk_list_box_get_row_at_y (box, y);
- while (window && window != gtk_widget_get_window (widget))
- {
- gdk_window_coords_to_parent (window, x, y, &x, &y);
- window = gdk_window_get_effective_parent (window);
- }
+ if (row != NULL && gtk_widget_is_sensitive (GTK_WIDGET (row)))
+ {
+ priv->active_row = row;
+ priv->active_row_active = TRUE;
+ gtk_widget_set_state_flags (GTK_WIDGET (priv->active_row),
+ GTK_STATE_FLAG_ACTIVE,
+ FALSE);
+ gtk_widget_queue_draw (GTK_WIDGET (box));
- row = gtk_list_box_get_row_at_y (box, y);
- if (row != NULL && gtk_widget_is_sensitive (GTK_WIDGET (row)))
- {
- priv->active_row = row;
- priv->active_row_active = TRUE;
- gtk_widget_set_state_flags (GTK_WIDGET (priv->active_row),
- GTK_STATE_FLAG_ACTIVE,
- FALSE);
- gtk_widget_queue_draw (GTK_WIDGET (box));
- if (event->type == GDK_2BUTTON_PRESS &&
- !priv->activate_single_click)
- {
- g_signal_emit (box, signals[ROW_ACTIVATED], 0, row);
- retval = GDK_EVENT_STOP;
- }
- }
+ if (n_press == 2 && !priv->activate_single_click)
+ g_signal_emit (box, signals[ROW_ACTIVATED], 0, row);
}
-
- return retval;
}
static void
@@ -1715,58 +1715,57 @@ get_current_selection_modifiers (GtkWidget *widget,
}
}
-static gboolean
-gtk_list_box_button_release_event (GtkWidget *widget,
- GdkEventButton *event)
+static void
+gtk_list_box_multipress_gesture_released (GtkGestureMultiPress *gesture,
+ guint n_press,
+ gdouble x,
+ gdouble y,
+ GtkListBox *box)
{
- GtkListBox *box = GTK_LIST_BOX (widget);
GtkListBoxPrivate *priv = BOX_PRIV (box);
- gboolean retval = GDK_EVENT_PROPAGATE;
/* Take a ref to protect against reentrancy
* (the activation may destroy the widget)
*/
g_object_ref (box);
- if (event->button == GDK_BUTTON_PRIMARY)
+ if (priv->active_row != NULL && priv->active_row_active)
{
- if (priv->active_row != NULL && priv->active_row_active)
- {
- gtk_widget_unset_state_flags (GTK_WIDGET (priv->active_row),
- GTK_STATE_FLAG_ACTIVE);
-
- if (priv->activate_single_click)
- gtk_list_box_select_and_activate (box, priv->active_row);
- else
- {
- gboolean modify;
- gboolean extend;
- GdkDevice *device;
+ gtk_widget_unset_state_flags (GTK_WIDGET (priv->active_row),
+ GTK_STATE_FLAG_ACTIVE);
- get_current_selection_modifiers (widget, &modify, &extend);
-
- /* With touch, we default to modifying the selection.
- * You can still clear the selection and start over
- * by holding Ctrl.
- */
- device = gdk_event_get_source_device ((GdkEvent *)event);
- if (gdk_device_get_source (device) == GDK_SOURCE_TOUCHSCREEN)
- modify = !modify;
-
- gtk_list_box_update_selection (box, priv->active_row, modify, extend);
- }
-
- retval = GDK_EVENT_STOP;
+ if (n_press == 1 && priv->activate_single_click)
+ gtk_list_box_select_and_activate (box, priv->active_row);
+ else
+ {
+ GdkEventSequence *sequence;
+ GdkInputSource source;
+ const GdkEvent *event;
+ gboolean modify;
+ gboolean extend;
+
+ get_current_selection_modifiers (GTK_WIDGET (box), &modify, &extend);
+
+ /* With touch, we default to modifying the selection.
+ * You can still clear the selection and start over
+ * by holding Ctrl.
+ */
+ sequence = gtk_gesture_single_get_current_sequence (GTK_GESTURE_SINGLE (gesture));
+ event = gtk_gesture_get_last_event (GTK_GESTURE (gesture), sequence);
+ source = gdk_device_get_source (gdk_event_get_source_device (event));
+
+ if (source == GDK_SOURCE_TOUCHSCREEN)
+ modify = !modify;
+
+ gtk_list_box_update_selection (box, priv->active_row, modify, extend);
}
+ }
- priv->active_row = NULL;
- priv->active_row_active = FALSE;
- gtk_widget_queue_draw (GTK_WIDGET (box));
- }
+ priv->active_row = NULL;
+ priv->active_row_active = FALSE;
+ gtk_widget_queue_draw (GTK_WIDGET (box));
g_object_unref (box);
-
- return retval;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]