Implement DND for selectable labels.

2004-11-12  Matthias Clasen  <mclasen@redhat.com>

	* gtk/gtklabel.c (gtk_label_button_press, gtk_label_button_release)
	(gtk_label_drag_data_get): Implement DND for selectable labels.
This commit is contained in:
Matthias Clasen 2004-11-12 21:52:04 +00:00 committed by Matthias Clasen
parent 9e847e411f
commit cb87aa11c9
5 changed files with 106 additions and 31 deletions

View File

@ -2,6 +2,8 @@
* gtk/gtklabel.c (gtk_label_do_popup): Adjust to the current * gtk/gtklabel.c (gtk_label_do_popup): Adjust to the current
entry popup menu. 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) Make GDK+ compile with X11R5 (#148032)

View File

@ -2,6 +2,8 @@
* gtk/gtklabel.c (gtk_label_do_popup): Adjust to the current * gtk/gtklabel.c (gtk_label_do_popup): Adjust to the current
entry popup menu. 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) Make GDK+ compile with X11R5 (#148032)

View File

@ -2,6 +2,8 @@
* gtk/gtklabel.c (gtk_label_do_popup): Adjust to the current * gtk/gtklabel.c (gtk_label_do_popup): Adjust to the current
entry popup menu. 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) Make GDK+ compile with X11R5 (#148032)

View File

@ -2,6 +2,8 @@
* gtk/gtklabel.c (gtk_label_do_popup): Adjust to the current * gtk/gtklabel.c (gtk_label_do_popup): Adjust to the current
entry popup menu. 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) Make GDK+ compile with X11R5 (#148032)

View File

@ -57,6 +57,11 @@ struct _GtkLabelSelectionInfo
gint selection_anchor; gint selection_anchor;
gint selection_end; gint selection_end;
GtkWidget *popup_menu; GtkWidget *popup_menu;
gint drag_start_x;
gint drag_start_y;
guint in_drag : 1;
}; };
enum { enum {
@ -160,6 +165,12 @@ static gboolean gtk_label_mnemonic_activate (GtkWidget *widget,
gboolean group_cycling); gboolean group_cycling);
static void gtk_label_setup_mnemonic (GtkLabel *label, static void gtk_label_setup_mnemonic (GtkLabel *label,
guint last_key); guint last_key);
static void gtk_label_drag_data_get (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint time);
/* For selectable lables: */ /* For selectable lables: */
static void gtk_label_move_cursor (GtkLabel *label, 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->hierarchy_changed = gtk_label_hierarchy_changed;
widget_class->screen_changed = gtk_label_screen_changed; widget_class->screen_changed = gtk_label_screen_changed;
widget_class->mnemonic_activate = gtk_label_mnemonic_activate; 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->move_cursor = gtk_label_move_cursor;
class->copy_clipboard = gtk_label_copy_clipboard; class->copy_clipboard = gtk_label_copy_clipboard;
@ -2497,12 +2509,14 @@ gtk_label_button_press (GtkWidget *widget,
{ {
GtkLabel *label; GtkLabel *label;
gint index = 0; gint index = 0;
gint min, max;
label = GTK_LABEL (widget); label = GTK_LABEL (widget);
if (label->select_info == NULL) if (label->select_info == NULL)
return FALSE; return FALSE;
label->select_info->in_drag = FALSE;
if (event->button == 1) if (event->button == 1)
{ {
if (!GTK_WIDGET_HAS_FOCUS (widget)) 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); 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 != if ((label->select_info->selection_anchor !=
label->select_info->selection_end) && label->select_info->selection_end) &&
(event->state & GDK_SHIFT_MASK)) (event->state & GDK_SHIFT_MASK))
{ {
gint min, max;
/* extend (same as motion) */ /* 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); min = MIN (min, index);
max = MAX (max, index); max = MAX (max, index);
@ -2547,13 +2559,19 @@ gtk_label_button_press (GtkWidget *widget,
gtk_label_select_region_index (label, min, max); gtk_label_select_region_index (label, min, max);
} }
else else
{ {
if (event->type == GDK_3BUTTON_PRESS) 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) else if (event->type == GDK_2BUTTON_PRESS)
gtk_label_select_word (label); gtk_label_select_word (label);
else 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 */ /* start a replacement */
gtk_label_select_region_index (label, index, index); gtk_label_select_region_index (label, index, index);
} }
@ -2575,13 +2593,22 @@ gtk_label_button_release (GtkWidget *widget,
GdkEventButton *event) GdkEventButton *event)
{ {
GtkLabel *label; GtkLabel *label = GTK_LABEL (widget);
gint index;
label = GTK_LABEL (widget);
if (label->select_info == NULL) if (label->select_info == NULL)
return FALSE; 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) if (event->button != 1)
return FALSE; return FALSE;
@ -2605,18 +2632,45 @@ gtk_label_motion (GtkWidget *widget,
if (label->select_info == NULL) if (label->select_info == NULL)
return FALSE; return FALSE;
if ((event->state & GDK_BUTTON1_MASK) == 0) if ((event->state & GDK_BUTTON1_MASK) == 0)
return FALSE; return FALSE;
gdk_window_get_pointer (label->select_info->window, gdk_window_get_pointer (label->select_info->window,
&x, &y, NULL); &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; return TRUE;
} }
@ -2753,15 +2807,9 @@ gtk_label_get_selectable (GtkLabel *label)
} }
static void static void
get_text_callback (GtkClipboard *clipboard, gtk_label_set_selection_text (GtkLabel *label,
GtkSelectionData *selection_data, GtkSelectionData *selection_data)
guint info,
gpointer user_data_or_owner)
{ {
GtkLabel *label;
label = GTK_LABEL (user_data_or_owner);
if ((label->select_info->selection_anchor != if ((label->select_info->selection_anchor !=
label->select_info->selection_end) && label->select_info->selection_end) &&
label->text) label->text)
@ -2773,21 +2821,40 @@ get_text_callback (GtkClipboard *clipboard,
label->select_info->selection_end); label->select_info->selection_end);
end = MAX (label->select_info->selection_anchor, end = MAX (label->select_info->selection_anchor,
label->select_info->selection_end); label->select_info->selection_end);
len = strlen (label->text); len = strlen (label->text);
if (end > len) if (end > len)
end = len; end = len;
if (start > len) if (start > len)
start = len; start = len;
gtk_selection_data_set_text (selection_data, gtk_selection_data_set_text (selection_data,
label->text + start, label->text + start,
end - 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 static void
clear_text_callback (GtkClipboard *clipboard, clear_text_callback (GtkClipboard *clipboard,
gpointer user_data_or_owner) gpointer user_data_or_owner)