From cb87aa11c9eb58c22dc19f054393ee71766a2d84 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 12 Nov 2004 21:52:04 +0000 Subject: [PATCH] Implement DND for selectable labels. 2004-11-12 Matthias Clasen * gtk/gtklabel.c (gtk_label_button_press, gtk_label_button_release) (gtk_label_drag_data_get): Implement DND for selectable labels. --- ChangeLog | 2 + ChangeLog.pre-2-10 | 2 + ChangeLog.pre-2-6 | 2 + ChangeLog.pre-2-8 | 2 + gtk/gtklabel.c | 129 ++++++++++++++++++++++++++++++++++----------- 5 files changed, 106 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 15282ce968..ec88f55018 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,8 @@ * gtk/gtklabel.c (gtk_label_do_popup): Adjust to the current entry popup menu. + (gtk_label_button_press, gtk_label_button_release) + (gtk_label_drag_data_get): Implement DND for selectable labels. Make GDK+ compile with X11R5 (#148032) diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 15282ce968..ec88f55018 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -2,6 +2,8 @@ * gtk/gtklabel.c (gtk_label_do_popup): Adjust to the current entry popup menu. + (gtk_label_button_press, gtk_label_button_release) + (gtk_label_drag_data_get): Implement DND for selectable labels. Make GDK+ compile with X11R5 (#148032) diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 15282ce968..ec88f55018 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -2,6 +2,8 @@ * gtk/gtklabel.c (gtk_label_do_popup): Adjust to the current entry popup menu. + (gtk_label_button_press, gtk_label_button_release) + (gtk_label_drag_data_get): Implement DND for selectable labels. Make GDK+ compile with X11R5 (#148032) diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 15282ce968..ec88f55018 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -2,6 +2,8 @@ * gtk/gtklabel.c (gtk_label_do_popup): Adjust to the current entry popup menu. + (gtk_label_button_press, gtk_label_button_release) + (gtk_label_drag_data_get): Implement DND for selectable labels. Make GDK+ compile with X11R5 (#148032) diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index 769275f4f2..8c94d4db01 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -57,6 +57,11 @@ struct _GtkLabelSelectionInfo gint selection_anchor; gint selection_end; GtkWidget *popup_menu; + + gint drag_start_x; + gint drag_start_y; + + guint in_drag : 1; }; enum { @@ -160,6 +165,12 @@ static gboolean gtk_label_mnemonic_activate (GtkWidget *widget, gboolean group_cycling); static void gtk_label_setup_mnemonic (GtkLabel *label, guint last_key); +static void gtk_label_drag_data_get (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time); + /* For selectable lables: */ static void gtk_label_move_cursor (GtkLabel *label, @@ -261,6 +272,7 @@ gtk_label_class_init (GtkLabelClass *class) widget_class->hierarchy_changed = gtk_label_hierarchy_changed; widget_class->screen_changed = gtk_label_screen_changed; widget_class->mnemonic_activate = gtk_label_mnemonic_activate; + widget_class->drag_data_get = gtk_label_drag_data_get; class->move_cursor = gtk_label_move_cursor; class->copy_clipboard = gtk_label_copy_clipboard; @@ -2497,12 +2509,14 @@ gtk_label_button_press (GtkWidget *widget, { GtkLabel *label; gint index = 0; + gint min, max; label = GTK_LABEL (widget); if (label->select_info == NULL) return FALSE; + label->select_info->in_drag = FALSE; if (event->button == 1) { if (!GTK_WIDGET_HAS_FOCUS (widget)) @@ -2522,18 +2536,16 @@ gtk_label_button_press (GtkWidget *widget, get_layout_index (label, event->x, event->y, &index); + min = MIN (label->select_info->selection_anchor, + label->select_info->selection_end); + max = MAX (label->select_info->selection_anchor, + label->select_info->selection_end); + if ((label->select_info->selection_anchor != label->select_info->selection_end) && (event->state & GDK_SHIFT_MASK)) { - gint min, max; - /* extend (same as motion) */ - min = MIN (label->select_info->selection_anchor, - label->select_info->selection_end); - max = MAX (label->select_info->selection_anchor, - label->select_info->selection_end); - min = MIN (min, index); max = MAX (max, index); @@ -2547,13 +2559,19 @@ gtk_label_button_press (GtkWidget *widget, gtk_label_select_region_index (label, min, max); } - else + else { if (event->type == GDK_3BUTTON_PRESS) - gtk_label_select_region_index (label, 0, strlen (label->text)); + gtk_label_select_region_index (label, 0, strlen (label->text)); else if (event->type == GDK_2BUTTON_PRESS) - gtk_label_select_word (label); - else + gtk_label_select_word (label); + else if (min < max && min <= index && index <= max) + { + label->select_info->in_drag = TRUE; + label->select_info->drag_start_x = event->x; + label->select_info->drag_start_y = event->y; + } + else /* start a replacement */ gtk_label_select_region_index (label, index, index); } @@ -2575,13 +2593,22 @@ gtk_label_button_release (GtkWidget *widget, GdkEventButton *event) { - GtkLabel *label; - - label = GTK_LABEL (widget); + GtkLabel *label = GTK_LABEL (widget); + gint index; if (label->select_info == NULL) return FALSE; + if (label->select_info->in_drag) + { + label->select_info->in_drag = 0; + + get_layout_index (label, event->x, event->y, &index); + gtk_label_select_region_index (label, index, index); + + return FALSE; + } + if (event->button != 1) return FALSE; @@ -2605,18 +2632,45 @@ gtk_label_motion (GtkWidget *widget, if (label->select_info == NULL) return FALSE; + if ((event->state & GDK_BUTTON1_MASK) == 0) return FALSE; gdk_window_get_pointer (label->select_info->window, &x, &y, NULL); - get_layout_index (label, x, y, &index); + if (label->select_info->in_drag) + { + if (gtk_drag_check_threshold (widget, + label->select_info->drag_start_x, + label->select_info->drag_start_y, + event->x, event->y)) + { + GdkDragContext *context; + GtkTargetList *target_list = gtk_target_list_new (NULL, 0); + + gtk_target_list_add_text_targets (target_list, 0); + + context = gtk_drag_begin (widget, target_list, + GDK_ACTION_COPY, + 1, (GdkEvent *)event); + + + label->select_info->in_drag = FALSE; + + gtk_target_list_unref (target_list); + gtk_drag_set_icon_default (context); + } + } + else + { + get_layout_index (label, x, y, &index); + + gtk_label_select_region_index (label, + label->select_info->selection_anchor, + index); + } - gtk_label_select_region_index (label, - label->select_info->selection_anchor, - index); - return TRUE; } @@ -2753,15 +2807,9 @@ gtk_label_get_selectable (GtkLabel *label) } static void -get_text_callback (GtkClipboard *clipboard, - GtkSelectionData *selection_data, - guint info, - gpointer user_data_or_owner) +gtk_label_set_selection_text (GtkLabel *label, + GtkSelectionData *selection_data) { - GtkLabel *label; - - label = GTK_LABEL (user_data_or_owner); - if ((label->select_info->selection_anchor != label->select_info->selection_end) && label->text) @@ -2773,21 +2821,40 @@ get_text_callback (GtkClipboard *clipboard, label->select_info->selection_end); end = MAX (label->select_info->selection_anchor, label->select_info->selection_end); - + len = strlen (label->text); - + if (end > len) end = len; - + if (start > len) start = len; - + gtk_selection_data_set_text (selection_data, label->text + start, end - start); } } +static void +gtk_label_drag_data_get (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time) +{ + gtk_label_set_selection_text (GTK_LABEL (widget), selection_data); +} + +static void +get_text_callback (GtkClipboard *clipboard, + GtkSelectionData *selection_data, + guint info, + gpointer user_data_or_owner) +{ + gtk_label_set_selection_text (GTK_LABEL (user_data_or_owner), selection_data); +} + static void clear_text_callback (GtkClipboard *clipboard, gpointer user_data_or_owner)