From c7169e119e7e8a85e2421c4a8ae7a77d50a67412 Mon Sep 17 00:00:00 2001 From: William Jon McCann Date: Fri, 18 Jan 2013 00:59:55 -0500 Subject: [PATCH] Add optional single click activation mode for icon view https://bugzilla.gnome.org/show_bug.cgi?id=345023 --- docs/reference/gtk/gtk3-sections.txt | 2 + gtk/gtk.symbols | 2 + gtk/gtkiconview.c | 115 +++++++++++++++++++++++++-- gtk/gtkiconview.h | 5 ++ gtk/gtkiconviewprivate.h | 1 + 5 files changed, 117 insertions(+), 8 deletions(-) diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt index b2a29554af..554f072ffd 100644 --- a/docs/reference/gtk/gtk3-sections.txt +++ b/docs/reference/gtk/gtk3-sections.txt @@ -1756,6 +1756,8 @@ gtk_icon_view_set_margin gtk_icon_view_get_margin gtk_icon_view_set_item_padding gtk_icon_view_get_item_padding +gtk_icon_view_set_activate_on_single_click +gtk_icon_view_get_activate_on_single_click gtk_icon_view_get_cell_rect gtk_icon_view_select_path gtk_icon_view_unselect_path diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index 460125e997..f2fc109af8 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -1329,6 +1329,7 @@ gtk_icon_view_create_drag_icon gtk_icon_view_drop_position_get_type gtk_icon_view_enable_model_drag_dest gtk_icon_view_enable_model_drag_source +gtk_icon_view_get_activate_on_single_click gtk_icon_view_get_cell_rect gtk_icon_view_get_columns gtk_icon_view_get_column_spacing @@ -1365,6 +1366,7 @@ gtk_icon_view_scroll_to_path gtk_icon_view_select_all gtk_icon_view_selected_foreach gtk_icon_view_select_path +gtk_icon_view_set_activate_on_single_click gtk_icon_view_set_columns gtk_icon_view_set_column_spacing gtk_icon_view_set_cursor diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c index f34f883a8e..19d4f66c05 100644 --- a/gtk/gtkiconview.c +++ b/gtk/gtkiconview.c @@ -107,12 +107,11 @@ enum PROP_TOOLTIP_COLUMN, PROP_ITEM_PADDING, PROP_CELL_AREA, - - /* For scrollable interface */ PROP_HADJUSTMENT, PROP_VADJUSTMENT, PROP_HSCROLL_POLICY, - PROP_VSCROLL_POLICY + PROP_VSCROLL_POLICY, + PROP_ACTIVATE_ON_SINGLE_CLICK }; /* GObject vfuncs */ @@ -639,6 +638,22 @@ gtk_icon_view_class_init (GtkIconViewClass *klass) GTK_TYPE_CELL_AREA, GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + /** + * GtkIconView:activate-on-single-click: + * + * The activate-on-single-click property specifies whether the "item-activated" signal + * will be emitted after a single click. + * + * Since: 3.8 + */ + g_object_class_install_property (gobject_class, + PROP_ACTIVATE_ON_SINGLE_CLICK, + g_param_spec_boolean ("activate-on-single-click", + P_("Activate on Single Click"), + P_("Activate row on a single click"), + FALSE, + GTK_PARAM_READWRITE)); + /* Scrollable interface properties */ g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment"); g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment"); @@ -668,10 +683,12 @@ gtk_icon_view_class_init (GtkIconViewClass *klass) * @path: the #GtkTreePath for the activated item * * The ::item-activated signal is emitted when the method - * gtk_icon_view_item_activated() is called or the user double - * clicks an item. It is also emitted when a non-editable item - * is selected and one of the keys: Space, Return or Enter is - * pressed. + * gtk_icon_view_item_activated() is called, when the user double + * clicks an item with the "activate-on-single-click" property set + * to %FALSE, or when the user single clicks an item when the + * "activate-on-single-click" property set to %TRUE. It is also + * emitted when a non-editable item is selected and one of the keys: + * Space, Return or Enter is pressed. */ icon_view_signals[ITEM_ACTIVATED] = g_signal_new (I_("item-activated"), @@ -964,6 +981,7 @@ gtk_icon_view_init (GtkIconView *icon_view) icon_view->priv->column_spacing = 6; icon_view->priv->margin = 6; icon_view->priv->item_padding = 6; + icon_view->priv->activate_on_single_click = FALSE; icon_view->priv->draw_focus = TRUE; @@ -1091,6 +1109,10 @@ gtk_icon_view_set_property (GObject *object, gtk_icon_view_set_item_padding (icon_view, g_value_get_int (value)); break; + case PROP_ACTIVATE_ON_SINGLE_CLICK: + gtk_icon_view_set_activate_on_single_click (icon_view, g_value_get_boolean (value)); + break; + case PROP_CELL_AREA: /* Construct-only, can only be assigned once */ area = g_value_get_object (value); @@ -1187,6 +1209,10 @@ gtk_icon_view_get_property (GObject *object, g_value_set_int (value, icon_view->priv->item_padding); break; + case PROP_ACTIVATE_ON_SINGLE_CLICK: + g_value_set_boolean (value, icon_view->priv->activate_on_single_click); + break; + case PROP_CELL_AREA: g_value_set_object (value, icon_view->priv->cell_area); break; @@ -2312,7 +2338,9 @@ gtk_icon_view_button_press (GtkWidget *widget, icon_view->priv->draw_focus = FALSE; } - if (event->button == GDK_BUTTON_PRIMARY && event->type == GDK_2BUTTON_PRESS) + if (!icon_view->priv->activate_on_single_click + && event->button == GDK_BUTTON_PRIMARY + && event->type == GDK_2BUTTON_PRESS) { item = _gtk_icon_view_get_item_at_coords (icon_view, event->x, event->y, @@ -2338,6 +2366,12 @@ gtk_icon_view_button_press (GtkWidget *widget, return event->button == GDK_BUTTON_PRIMARY; } +static gboolean +button_event_modifies_selection (GdkEventButton *event) +{ + return (event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) != 0; +} + static gboolean gtk_icon_view_button_release (GtkWidget *widget, GdkEventButton *event) @@ -2353,6 +2387,28 @@ gtk_icon_view_button_release (GtkWidget *widget, remove_scroll_timeout (icon_view); + if (event->button == GDK_BUTTON_PRIMARY + && icon_view->priv->activate_on_single_click + && !button_event_modifies_selection (event) + && icon_view->priv->last_single_clicked != NULL) + { + GtkIconViewItem *item; + + item = _gtk_icon_view_get_item_at_coords (icon_view, + event->x, event->y, + FALSE, + NULL); + if (item == icon_view->priv->last_single_clicked) + { + GtkTreePath *path; + path = gtk_tree_path_new_from_indices (item->index, -1); + gtk_icon_view_item_activated (icon_view, path); + gtk_tree_path_free (path); + } + + icon_view->priv->last_single_clicked = NULL; + } + return TRUE; } @@ -7134,6 +7190,49 @@ gtk_icon_view_set_reorderable (GtkIconView *icon_view, g_object_notify (G_OBJECT (icon_view), "reorderable"); } +/** + * gtk_icon_view_set_activate_on_single_click: + * @icon_view: a #GtkIconView + * @setting: %TRUE to emit item-activated on a single click + * + * Causes the "item-activated" signal to be emitted on a single click + * instead of a double click. + * + * Since: 3.8 + **/ +void +gtk_icon_view_set_activate_on_single_click (GtkIconView *icon_view, + gboolean setting) +{ + g_return_if_fail (GTK_IS_ICON_VIEW (icon_view)); + + setting = setting != FALSE; + + if (icon_view->priv->activate_on_single_click == setting) + return; + + icon_view->priv->activate_on_single_click = setting; + g_object_notify (G_OBJECT (icon_view), "activate-on-single-click"); +} + +/** + * gtk_icon_view_get_activate_on_single_click: + * @icon_view: a #GtkIconView + * + * Gets the setting set by gtk_icon_view_set_activate_on_single_click(). + * + * Return value: %TRUE if item-activated will be emitted on a single click + * + * Since: 3.8 + **/ +gboolean +gtk_icon_view_get_activate_on_single_click (GtkIconView *icon_view) +{ + g_return_val_if_fail (GTK_IS_ICON_VIEW (icon_view), FALSE); + + return icon_view->priv->activate_on_single_click; +} + static gboolean gtk_icon_view_buildable_custom_tag_start (GtkBuildable *buildable, GtkBuilder *builder, diff --git a/gtk/gtkiconview.h b/gtk/gtkiconview.h index 49d796bf03..2adcc64c98 100644 --- a/gtk/gtkiconview.h +++ b/gtk/gtkiconview.h @@ -163,6 +163,11 @@ gboolean gtk_icon_view_get_item_at_pos (GtkIconView *icon_view, gboolean gtk_icon_view_get_visible_range (GtkIconView *icon_view, GtkTreePath **start_path, GtkTreePath **end_path); +GDK_AVAILABLE_IN_3_8 +void gtk_icon_view_set_activate_on_single_click (GtkIconView *icon_view, + gboolean single); +GDK_AVAILABLE_IN_3_8 +gboolean gtk_icon_view_get_activate_on_single_click (GtkIconView *icon_view); void gtk_icon_view_selected_foreach (GtkIconView *icon_view, GtkIconViewForeachFunc func, diff --git a/gtk/gtkiconviewprivate.h b/gtk/gtkiconviewprivate.h index 093a19c4dc..69bca20ff7 100644 --- a/gtk/gtkiconviewprivate.h +++ b/gtk/gtkiconviewprivate.h @@ -115,6 +115,7 @@ struct _GtkIconViewPrivate guint dest_set : 1; guint reorderable : 1; guint empty_view_drop :1; + guint activate_on_single_click : 1; guint modify_selection_pressed : 1; guint extend_selection_pressed : 1;