From 185da29b689370d00914ca6c7c5a7bf99fbb702f Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 27 Mar 2014 12:31:28 +0100 Subject: [PATCH] treeview: Use multipress gesture for row activation Replace custom double click detection with multipress gesture --- gtk/gtktreeview.c | 108 ++++++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 62 deletions(-) diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index c0e855d16c..cc18ffaa7a 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -436,6 +436,10 @@ struct _GtkTreeViewPrivate gpointer row_separator_data; GDestroyNotify row_separator_destroy; + /* Gestures */ + GtkGesture *multipress_gesture; + GtkGesture *drag_gesture; + /* Tooltip support */ gint tooltip_column; @@ -883,6 +887,8 @@ static gboolean scroll_row_timeout (gpointer data); static void add_scroll_timeout (GtkTreeView *tree_view); static void remove_scroll_timeout (GtkTreeView *tree_view); +static void grab_focus_and_unset_draw_keyfocus (GtkTreeView *tree_view); + static guint tree_view_signals [LAST_SIGNAL] = { 0 }; @@ -1731,6 +1737,38 @@ G_GNUC_END_IGNORE_DEPRECATIONS gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_TREE_VIEW_ACCESSIBLE); } +static void +_tree_view_multipress_pressed (GtkGestureMultiPress *gesture, + gint n_press, + gdouble x, + gdouble y, + GtkTreeView *tree_view) +{ + GtkTreeViewColumn *column; + GtkTreePath *path; + gint bin_x, bin_y; + + gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, x, y, + &bin_x, &bin_y); + gtk_tree_view_get_path_at_pos (tree_view, bin_x, bin_y, + &path, &column, NULL, NULL); + + if (n_press == 2 || (n_press == 1 && tree_view->priv->activate_on_single_click)) + gtk_tree_view_row_activated (tree_view, path, column); + else + { + if (n_press == 1) + { + tree_view->priv->button_pressed_node = tree_view->priv->prelight_node; + tree_view->priv->button_pressed_tree = tree_view->priv->prelight_tree; + } + + grab_focus_and_unset_draw_keyfocus (tree_view); + } + + gtk_tree_path_free (path); +} + static void gtk_tree_view_init (GtkTreeView *tree_view) { @@ -1799,6 +1837,14 @@ gtk_tree_view_init (GtkTreeView *tree_view) gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (tree_view)), GTK_STYLE_CLASS_VIEW); + + tree_view->priv->multipress_gesture = gtk_gesture_multi_press_new (GTK_WIDGET (tree_view)); + gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (tree_view->priv->multipress_gesture), FALSE); + g_signal_connect (tree_view->priv->multipress_gesture, "pressed", + G_CALLBACK (_tree_view_multipress_pressed), tree_view); + gtk_widget_add_gesture (GTK_WIDGET (tree_view), + tree_view->priv->multipress_gesture, + GTK_PHASE_BUBBLE); } @@ -2995,7 +3041,6 @@ gtk_tree_view_button_press (GtkWidget *widget, gint pre_val, aft_val; GtkTreeViewColumn *column = NULL; gint column_handled_click = FALSE; - gboolean row_double_click = FALSE; gboolean rtl; gboolean node_selected; GdkModifierType extend_mod_mask; @@ -3245,67 +3290,6 @@ gtk_tree_view_button_press (GtkWidget *widget, } } - if (event->button == GDK_BUTTON_PRIMARY && event->type == GDK_BUTTON_PRESS) - { - - /* Test if a double click happened on the same row. */ - if (!tree_view->priv->activate_on_single_click) - { - int double_click_time, double_click_distance; - - g_object_get (gtk_settings_get_default (), - "gtk-double-click-time", &double_click_time, - "gtk-double-click-distance", &double_click_distance, - NULL); - - /* Same conditions as _gdk_event_button_generate */ - if (tree_view->priv->last_button_x != -1 && - (event->time < tree_view->priv->last_button_time + double_click_time) && - (ABS (event->x - tree_view->priv->last_button_x) <= double_click_distance) && - (ABS (event->y - tree_view->priv->last_button_y) <= double_click_distance)) - { - /* We do no longer compare paths of this row and the - * row clicked previously. We use the double click - * distance to decide whether this is a valid click, - * allowing the mouse to slightly move over another row. - */ - row_double_click = TRUE; - - tree_view->priv->last_button_time = 0; - tree_view->priv->last_button_x = -1; - tree_view->priv->last_button_y = -1; - } - else - { - tree_view->priv->last_button_time = event->time; - tree_view->priv->last_button_x = event->x; - tree_view->priv->last_button_y = event->y; - } - } - else - { - tree_view->priv->button_pressed_node = tree_view->priv->prelight_node; - tree_view->priv->button_pressed_tree = tree_view->priv->prelight_tree; - } - } - - if (row_double_click) - { - gtk_grab_remove (widget); - gtk_tree_view_row_activated (tree_view, path, column); - - if (tree_view->priv->pressed_button == event->button) - tree_view->priv->pressed_button = -1; - } - - gtk_tree_path_free (path); - - /* If we activated the row through a double click we don't want to grab - * focus back, as moving focus to another widget is pretty common. - */ - if (!row_double_click) - grab_focus_and_unset_draw_keyfocus (tree_view); - return TRUE; }