X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkiconview.c;h=0c6dc038ce354701c740569e7f2b9e35d77f2ef9;hb=fd51c8f5e9d6fb68c8e81b9b1e2ab80931f963f0;hp=f34f883a8e164d6b3681ba6c8b6b8c13ff964b39;hpb=e4b5e94eb9500a83769771e6132f9abb08badb32;p=~andy%2Fgtk diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c index f34f883a8..0c6dc038c 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 */ @@ -133,6 +132,9 @@ static void gtk_icon_view_get_property (GObject static void gtk_icon_view_destroy (GtkWidget *widget); static void gtk_icon_view_realize (GtkWidget *widget); static void gtk_icon_view_unrealize (GtkWidget *widget); +static void gtk_icon_view_style_updated (GtkWidget *widget); +static void gtk_icon_view_state_flags_changed (GtkWidget *widget, + GtkStateFlags previous_state); static GtkSizeRequestMode gtk_icon_view_get_request_mode (GtkWidget *widget); static void gtk_icon_view_get_preferred_width (GtkWidget *widget, gint *minimum, @@ -349,6 +351,7 @@ gtk_icon_view_class_init (GtkIconViewClass *klass) widget_class->destroy = gtk_icon_view_destroy; widget_class->realize = gtk_icon_view_realize; widget_class->unrealize = gtk_icon_view_unrealize; + widget_class->style_updated = gtk_icon_view_style_updated; widget_class->get_request_mode = gtk_icon_view_get_request_mode; widget_class->get_preferred_width = gtk_icon_view_get_preferred_width; widget_class->get_preferred_height = gtk_icon_view_get_preferred_height; @@ -369,6 +372,7 @@ gtk_icon_view_class_init (GtkIconViewClass *klass) widget_class->drag_motion = gtk_icon_view_drag_motion; widget_class->drag_drop = gtk_icon_view_drag_drop; widget_class->drag_data_received = gtk_icon_view_drag_data_received; + widget_class->state_flags_changed = gtk_icon_view_state_flags_changed; container_class->remove = gtk_icon_view_remove; container_class->forall = gtk_icon_view_forall; @@ -639,6 +643,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 +688,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 +986,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 +1114,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 +1214,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; @@ -1249,6 +1280,7 @@ gtk_icon_view_realize (GtkWidget *widget) GdkWindow *window; GdkWindowAttr attributes; gint attributes_mask; + GtkStyleContext *context; gtk_widget_set_realized (widget, TRUE); @@ -1269,7 +1301,7 @@ gtk_icon_view_realize (GtkWidget *widget) window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); gtk_widget_set_window (widget, window); - gdk_window_set_user_data (window, widget); + gtk_widget_register_window (widget, window); gtk_widget_get_allocation (widget, &allocation); @@ -1290,7 +1322,12 @@ gtk_icon_view_realize (GtkWidget *widget) icon_view->priv->bin_window = gdk_window_new (window, &attributes, attributes_mask); - gdk_window_set_user_data (icon_view->priv->bin_window, widget); + gtk_widget_register_window (widget, icon_view->priv->bin_window); + + context = gtk_widget_get_style_context (widget); + gtk_style_context_set_background (context, icon_view->priv->bin_window); + gtk_style_context_set_background (context, window); + gdk_window_show (icon_view->priv->bin_window); } @@ -1301,13 +1338,45 @@ gtk_icon_view_unrealize (GtkWidget *widget) icon_view = GTK_ICON_VIEW (widget); - gdk_window_set_user_data (icon_view->priv->bin_window, NULL); + gtk_widget_unregister_window (widget, icon_view->priv->bin_window); gdk_window_destroy (icon_view->priv->bin_window); icon_view->priv->bin_window = NULL; GTK_WIDGET_CLASS (gtk_icon_view_parent_class)->unrealize (widget); } +static void +_gtk_icon_view_update_background (GtkIconView *icon_view) +{ + GtkWidget *widget = GTK_WIDGET (icon_view); + + if (gtk_widget_get_realized (widget)) + { + GtkStyleContext *context; + + context = gtk_widget_get_style_context (widget); + gtk_style_context_set_background (context, gtk_widget_get_window (widget)); + gtk_style_context_set_background (context, icon_view->priv->bin_window); + } +} + +static void +gtk_icon_view_state_flags_changed (GtkWidget *widget, + GtkStateFlags previous_state) +{ + _gtk_icon_view_update_background (GTK_ICON_VIEW (widget)); + gtk_widget_queue_draw (widget); +} + +static void +gtk_icon_view_style_updated (GtkWidget *widget) +{ + GTK_WIDGET_CLASS (gtk_icon_view_parent_class)->style_updated (widget); + + _gtk_icon_view_update_background (GTK_ICON_VIEW (widget)); + gtk_widget_queue_resize (widget); +} + static gint gtk_icon_view_get_n_items (GtkIconView *icon_view) { @@ -2312,7 +2381,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 +2409,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 +2430,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 +7233,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 + * @single: %TRUE to emit item-activated on a single click + * + * Causes the #GtkIconView::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 single) +{ + g_return_if_fail (GTK_IS_ICON_VIEW (icon_view)); + + single = single != FALSE; + + if (icon_view->priv->activate_on_single_click == single) + return; + + icon_view->priv->activate_on_single_click = single; + 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,