mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 10:50:10 +00:00
When dragging text, use a drag icon showing the (ellipsized) text that is
2005-07-11 Matthias Clasen <mclasen@redhat.com> When dragging text, use a drag icon showing the (ellipsized) text that is being dragged: (#161132, Kevin Duffus, patch by Carlos Garnacho Parro) * gtk/gtktextutil.h: * gtk/gtktextutil.c (_gtk_text_util_create_drag_icon): Add a function to create a pixmap for use when dragging text. * gtk/gtktextview.c (gtk_text_view_start_selection_dnd): * gtk/gtklabel.c (gtk_label_motion): * gtk/gtkentry.c (gtk_entry_motion_notify): Use a drag icon showing the text being dragged. 2005-07-11 Matthias Clasen <mclasen@redhat.com> * gtk/gtkentry.c (gtk_entry_move_forward_word) (gtk_entry_move_backward_word): Match the text view change to allow selecting whitespace with double-click.
This commit is contained in:
parent
7912643e8f
commit
13a341e0e9
19
ChangeLog
19
ChangeLog
@ -1,5 +1,24 @@
|
||||
2005-07-11 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
When dragging text, use a drag icon showing the (ellipsized)
|
||||
text that is being dragged: (#161132, Kevin Duffus, patch
|
||||
by Carlos Garnacho Parro)
|
||||
|
||||
* gtk/gtktextutil.h:
|
||||
* gtk/gtktextutil.c (_gtk_text_util_create_drag_icon): Add
|
||||
a function to create a pixmap for use when dragging text.
|
||||
|
||||
* gtk/gtktextview.c (gtk_text_view_start_selection_dnd):
|
||||
* gtk/gtklabel.c (gtk_label_motion):
|
||||
* gtk/gtkentry.c (gtk_entry_motion_notify): Use a drag icon
|
||||
showing the text being dragged.
|
||||
|
||||
2005-07-11 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/gtkentry.c (gtk_entry_move_forward_word)
|
||||
(gtk_entry_move_backward_word): Match the text view change
|
||||
to allow selecting whitespace with double-click.
|
||||
|
||||
* gtk/gtktextview.c (extend_selection): Make double-clicking
|
||||
between words select whitespace. (#309860, Mike Miller, patch
|
||||
by Paolo Borelli)
|
||||
|
@ -1,5 +1,24 @@
|
||||
2005-07-11 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
When dragging text, use a drag icon showing the (ellipsized)
|
||||
text that is being dragged: (#161132, Kevin Duffus, patch
|
||||
by Carlos Garnacho Parro)
|
||||
|
||||
* gtk/gtktextutil.h:
|
||||
* gtk/gtktextutil.c (_gtk_text_util_create_drag_icon): Add
|
||||
a function to create a pixmap for use when dragging text.
|
||||
|
||||
* gtk/gtktextview.c (gtk_text_view_start_selection_dnd):
|
||||
* gtk/gtklabel.c (gtk_label_motion):
|
||||
* gtk/gtkentry.c (gtk_entry_motion_notify): Use a drag icon
|
||||
showing the text being dragged.
|
||||
|
||||
2005-07-11 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/gtkentry.c (gtk_entry_move_forward_word)
|
||||
(gtk_entry_move_backward_word): Match the text view change
|
||||
to allow selecting whitespace with double-click.
|
||||
|
||||
* gtk/gtktextview.c (extend_selection): Make double-clicking
|
||||
between words select whitespace. (#309860, Mike Miller, patch
|
||||
by Paolo Borelli)
|
||||
|
@ -1,5 +1,24 @@
|
||||
2005-07-11 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
When dragging text, use a drag icon showing the (ellipsized)
|
||||
text that is being dragged: (#161132, Kevin Duffus, patch
|
||||
by Carlos Garnacho Parro)
|
||||
|
||||
* gtk/gtktextutil.h:
|
||||
* gtk/gtktextutil.c (_gtk_text_util_create_drag_icon): Add
|
||||
a function to create a pixmap for use when dragging text.
|
||||
|
||||
* gtk/gtktextview.c (gtk_text_view_start_selection_dnd):
|
||||
* gtk/gtklabel.c (gtk_label_motion):
|
||||
* gtk/gtkentry.c (gtk_entry_motion_notify): Use a drag icon
|
||||
showing the text being dragged.
|
||||
|
||||
2005-07-11 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* gtk/gtkentry.c (gtk_entry_move_forward_word)
|
||||
(gtk_entry_move_backward_word): Match the text view change
|
||||
to allow selecting whitespace with double-click.
|
||||
|
||||
* gtk/gtktextview.c (extend_selection): Make double-clicking
|
||||
between words select whitespace. (#309860, Mike Miller, patch
|
||||
by Paolo Borelli)
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
@ -1649,6 +1650,49 @@ gtk_entry_button_release (GtkWidget *widget,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gchar *
|
||||
_gtk_entry_get_selected_text (GtkEntry *entry)
|
||||
{
|
||||
GtkEditable *editable = GTK_EDITABLE (entry);
|
||||
gint start_text, end_text;
|
||||
gchar *text = NULL;
|
||||
|
||||
if (gtk_editable_get_selection_bounds (editable, &start_text, &end_text))
|
||||
text = gtk_editable_get_chars (editable, start_text, end_text);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin_cb (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gpointer data)
|
||||
{
|
||||
GtkEntry *entry;
|
||||
gchar *text;
|
||||
GdkPixmap *pixmap = NULL;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (widget, drag_begin_cb, NULL);
|
||||
|
||||
entry = GTK_ENTRY (widget);
|
||||
|
||||
text = _gtk_entry_get_selected_text (entry);
|
||||
pixmap = _gtk_text_util_create_drag_icon (widget, text, -1);
|
||||
|
||||
if (entry->visible && pixmap)
|
||||
gtk_drag_set_icon_pixmap (context,
|
||||
gdk_drawable_get_colormap (pixmap),
|
||||
pixmap,
|
||||
NULL,
|
||||
-2, -2);
|
||||
else
|
||||
gtk_drag_set_icon_default (context);
|
||||
|
||||
if (pixmap)
|
||||
g_object_unref (pixmap);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static gint
|
||||
gtk_entry_motion_notify (GtkWidget *widget,
|
||||
GdkEventMotion *event)
|
||||
@ -1678,25 +1722,25 @@ gtk_entry_motion_notify (GtkWidget *widget,
|
||||
if (entry->in_drag)
|
||||
{
|
||||
if (gtk_drag_check_threshold (widget,
|
||||
entry->drag_start_x, entry->drag_start_y,
|
||||
event->x + entry->scroll_offset, event->y))
|
||||
{
|
||||
GdkDragContext *context;
|
||||
GtkTargetList *target_list = gtk_target_list_new (NULL, 0);
|
||||
guint actions = entry->editable ? GDK_ACTION_COPY | GDK_ACTION_MOVE : GDK_ACTION_COPY;
|
||||
entry->drag_start_x, entry->drag_start_y,
|
||||
event->x + entry->scroll_offset, event->y))
|
||||
{
|
||||
GdkDragContext *context;
|
||||
GtkTargetList *target_list = gtk_target_list_new (NULL, 0);
|
||||
guint actions = entry->editable ? GDK_ACTION_COPY | GDK_ACTION_MOVE : GDK_ACTION_COPY;
|
||||
|
||||
gtk_target_list_add_text_targets (target_list, 0);
|
||||
gtk_target_list_add_text_targets (target_list, 0);
|
||||
|
||||
context = gtk_drag_begin (widget, target_list, actions,
|
||||
entry->button, (GdkEvent *)event);
|
||||
g_signal_connect (widget, "drag-begin",
|
||||
G_CALLBACK (drag_begin_cb), NULL);
|
||||
context = gtk_drag_begin (widget, target_list, actions,
|
||||
entry->button, (GdkEvent *)event);
|
||||
|
||||
entry->in_drag = FALSE;
|
||||
entry->button = 0;
|
||||
|
||||
entry->in_drag = FALSE;
|
||||
entry->button = 0;
|
||||
|
||||
gtk_target_list_unref (target_list);
|
||||
gtk_drag_set_icon_default (context);
|
||||
}
|
||||
gtk_target_list_unref (target_list);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3549,9 +3593,9 @@ gtk_entry_move_forward_word (GtkEntry *entry,
|
||||
|
||||
pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
|
||||
|
||||
/* Find the next word end */
|
||||
/* Find the next word boundary */
|
||||
new_pos++;
|
||||
while (new_pos < n_attrs && !log_attrs[new_pos].is_word_end)
|
||||
while (new_pos < n_attrs && !(log_attrs[new_pos].is_word_start || log_attrs[new_pos].is_word_end))
|
||||
new_pos++;
|
||||
|
||||
g_free (log_attrs);
|
||||
@ -3582,8 +3626,8 @@ gtk_entry_move_backward_word (GtkEntry *entry,
|
||||
|
||||
new_pos = start - 1;
|
||||
|
||||
/* Find the previous word beginning */
|
||||
while (new_pos > 0 && !log_attrs[new_pos].is_word_start)
|
||||
/* Find the previous word boundary */
|
||||
while (new_pos > 0 && !(log_attrs[new_pos].is_word_start || log_attrs[new_pos].is_word_end))
|
||||
new_pos--;
|
||||
|
||||
g_free (log_attrs);
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "gtkimagemenuitem.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkseparatormenuitem.h"
|
||||
#include "gtktextutil.h"
|
||||
#include "gtkmenuitem.h"
|
||||
#include "gtknotebook.h"
|
||||
#include "gtkstock.h"
|
||||
@ -2832,6 +2833,56 @@ gtk_label_button_release (GtkWidget *widget,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin_cb (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gpointer data)
|
||||
{
|
||||
GtkLabel *label;
|
||||
GdkPixmap *pixmap = NULL;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (widget, drag_begin_cb, NULL);
|
||||
|
||||
label = GTK_LABEL (widget);
|
||||
|
||||
if ((label->select_info->selection_anchor !=
|
||||
label->select_info->selection_end) &&
|
||||
label->text)
|
||||
{
|
||||
gint start, end;
|
||||
gint len;
|
||||
|
||||
start = MIN (label->select_info->selection_anchor,
|
||||
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;
|
||||
|
||||
pixmap = _gtk_text_util_create_drag_icon (widget,
|
||||
label->text + start,
|
||||
end - start);
|
||||
}
|
||||
|
||||
if (pixmap)
|
||||
gtk_drag_set_icon_pixmap (context,
|
||||
gdk_drawable_get_colormap (pixmap),
|
||||
pixmap,
|
||||
NULL,
|
||||
-2, -2);
|
||||
else
|
||||
gtk_drag_set_icon_default (context);
|
||||
|
||||
if (pixmap)
|
||||
g_object_unref (pixmap);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_label_motion (GtkWidget *widget,
|
||||
GdkEventMotion *event)
|
||||
@ -2863,16 +2914,16 @@ gtk_label_motion (GtkWidget *widget,
|
||||
GtkTargetList *target_list = gtk_target_list_new (NULL, 0);
|
||||
|
||||
gtk_target_list_add_text_targets (target_list, 0);
|
||||
|
||||
|
||||
g_signal_connect (widget, "drag-begin",
|
||||
G_CALLBACK (drag_begin_cb), NULL);
|
||||
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
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
||||
*
|
||||
@ -30,6 +31,11 @@
|
||||
#include "gtkmenuitem.h"
|
||||
#include "gtkalias.h"
|
||||
|
||||
#define DRAG_ICON_MAX_WIDTH 250
|
||||
#define DRAG_ICON_LAYOUT_BORDER 2
|
||||
#define DRAG_ICON_MAX_LINES 7
|
||||
#define ELLIPSIS_CHARACTER "\xe2\x80\xa6"
|
||||
|
||||
typedef struct _GtkUnicodeMenuEntry GtkUnicodeMenuEntry;
|
||||
typedef struct _GtkTextUtilCallbackInfo GtkTextUtilCallbackInfo;
|
||||
|
||||
@ -117,3 +123,121 @@ _gtk_text_util_append_special_char_menuitems (GtkMenuShell *menushe
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
append_n_lines (GString *str, const gchar *text, GSList *lines, gint n_lines)
|
||||
{
|
||||
PangoLayoutLine *line;
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < n_lines; i++)
|
||||
{
|
||||
line = lines->data;
|
||||
g_string_append_len (str, &text[line->start_index], line->length);
|
||||
lines = lines->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
limit_layout_lines (PangoLayout *layout)
|
||||
{
|
||||
const gchar *text;
|
||||
GString *str;
|
||||
GSList *lines, *elem;
|
||||
gint n_lines;
|
||||
|
||||
n_lines = pango_layout_get_line_count (layout);
|
||||
|
||||
if (n_lines >= DRAG_ICON_MAX_LINES)
|
||||
{
|
||||
text = pango_layout_get_text (layout);
|
||||
str = g_string_new (NULL);
|
||||
lines = pango_layout_get_lines (layout);
|
||||
|
||||
/* get first lines */
|
||||
elem = lines;
|
||||
append_n_lines (str, text, elem,
|
||||
DRAG_ICON_MAX_LINES / 2);
|
||||
|
||||
g_string_append (str, "\n" ELLIPSIS_CHARACTER "\n");
|
||||
|
||||
/* get last lines */
|
||||
elem = g_slist_nth (lines, n_lines - DRAG_ICON_MAX_LINES / 2);
|
||||
append_n_lines (str, text, elem,
|
||||
DRAG_ICON_MAX_LINES / 2);
|
||||
|
||||
pango_layout_set_text (layout, str->str, -1);
|
||||
g_string_free (str, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _gtk_text_util_create_drag_icon
|
||||
* @widget: #GtkWidget to extract the pango context
|
||||
* @text: a #gchar to render the icon
|
||||
* @len: length of @text, or -1 for NUL-terminated text
|
||||
*
|
||||
* Creates a drag and drop icon from @text.
|
||||
**/
|
||||
GdkPixmap*
|
||||
_gtk_text_util_create_drag_icon (GtkWidget *widget,
|
||||
gchar *text,
|
||||
gsize len)
|
||||
{
|
||||
GdkDrawable *drawable = NULL;
|
||||
PangoContext *context;
|
||||
PangoLayout *layout;
|
||||
gint pixmap_height, pixmap_width;
|
||||
gint layout_width, layout_height;
|
||||
gint n_lines;
|
||||
|
||||
g_return_val_if_fail (widget != NULL, NULL);
|
||||
g_return_val_if_fail (text != NULL, NULL);
|
||||
|
||||
context = gtk_widget_get_pango_context (widget);
|
||||
layout = pango_layout_new (context);
|
||||
|
||||
pango_layout_set_text (layout, text, len);
|
||||
pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
|
||||
pango_layout_get_size (layout, &layout_width, &layout_height);
|
||||
|
||||
layout_width = MIN (layout_width, DRAG_ICON_MAX_WIDTH * PANGO_SCALE);
|
||||
pango_layout_set_width (layout, layout_width);
|
||||
n_lines = pango_layout_get_line_count (layout);
|
||||
|
||||
limit_layout_lines (layout);
|
||||
|
||||
/* get again layout extents, they may have changed */
|
||||
pango_layout_get_size (layout, &layout_width, &layout_height);
|
||||
|
||||
pixmap_width = layout_width / PANGO_SCALE + DRAG_ICON_LAYOUT_BORDER * 2;
|
||||
pixmap_height = layout_height / PANGO_SCALE + DRAG_ICON_LAYOUT_BORDER * 2;
|
||||
|
||||
drawable = gdk_pixmap_new (widget->window,
|
||||
pixmap_width + 2,
|
||||
pixmap_height + 2,
|
||||
-1);
|
||||
|
||||
gdk_draw_rectangle (drawable,
|
||||
widget->style->base_gc [GTK_WIDGET_STATE (widget)],
|
||||
TRUE,
|
||||
0, 0,
|
||||
pixmap_width + 1,
|
||||
pixmap_height + 1);
|
||||
|
||||
gdk_draw_layout (drawable,
|
||||
widget->style->text_gc [GTK_WIDGET_STATE (widget)],
|
||||
1 + DRAG_ICON_LAYOUT_BORDER,
|
||||
1 + DRAG_ICON_LAYOUT_BORDER,
|
||||
layout);
|
||||
|
||||
gdk_draw_rectangle (drawable,
|
||||
widget->style->black_gc,
|
||||
FALSE,
|
||||
0, 0,
|
||||
pixmap_width + 1,
|
||||
pixmap_height + 1);
|
||||
|
||||
g_object_unref (layout);
|
||||
|
||||
return drawable;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include <gtk/gtkwidget.h>
|
||||
#include <gtk/gtkmenushell.h>
|
||||
#include <gtk/gtkeditable.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@ -46,5 +47,8 @@ void _gtk_text_util_append_special_char_menuitems (GtkMenuShell *me
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
GdkPixmap* _gtk_text_util_create_drag_icon (GtkWidget *widget,
|
||||
gchar *text,
|
||||
gsize len);
|
||||
|
||||
#endif /* __GTK_TEXT_UTIL_H__ */
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* GTK - The GIMP Toolkit
|
||||
* gtktextview.c Copyright (C) 2000 Red Hat, Inc.
|
||||
*
|
||||
@ -5977,17 +5978,62 @@ gtk_text_view_reset_im_context (GtkTextView *text_view)
|
||||
}
|
||||
}
|
||||
|
||||
static gchar*
|
||||
_gtk_text_view_get_selected_text (GtkTextView *text_view)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter start, end;
|
||||
gchar *text = NULL;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (text_view);
|
||||
|
||||
if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
|
||||
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
/*
|
||||
* DND feature
|
||||
*/
|
||||
|
||||
static void
|
||||
drag_begin_cb (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gpointer data)
|
||||
{
|
||||
GtkTextView *text_view;
|
||||
gchar *text;
|
||||
GdkPixmap *pixmap = NULL;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (widget, drag_begin_cb, NULL);
|
||||
|
||||
text_view = GTK_TEXT_VIEW (widget);
|
||||
|
||||
text = _gtk_text_view_get_selected_text (text_view);
|
||||
pixmap = _gtk_text_util_create_drag_icon (widget, text, -1);
|
||||
|
||||
if (pixmap)
|
||||
gtk_drag_set_icon_pixmap (context,
|
||||
gdk_drawable_get_colormap (pixmap),
|
||||
pixmap,
|
||||
NULL,
|
||||
-2, -2);
|
||||
else
|
||||
gtk_drag_set_icon_default (context);
|
||||
|
||||
if (pixmap)
|
||||
g_object_unref (pixmap);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_start_selection_dnd (GtkTextView *text_view,
|
||||
const GtkTextIter *iter,
|
||||
GdkEventMotion *event)
|
||||
{
|
||||
GdkDragContext *context;
|
||||
GtkTargetList *target_list;
|
||||
GtkTargetList *target_list;
|
||||
|
||||
text_view->drag_start_x = -1;
|
||||
text_view->drag_start_y = -1;
|
||||
@ -5997,13 +6043,13 @@ gtk_text_view_start_selection_dnd (GtkTextView *text_view,
|
||||
G_N_ELEMENTS (target_table));
|
||||
gtk_target_list_add_text_targets (target_list, 0);
|
||||
|
||||
g_signal_connect (text_view, "drag-begin",
|
||||
G_CALLBACK (drag_begin_cb), NULL);
|
||||
context = gtk_drag_begin (GTK_WIDGET (text_view), target_list,
|
||||
GDK_ACTION_COPY | GDK_ACTION_MOVE,
|
||||
1, (GdkEvent*)event);
|
||||
|
||||
gtk_target_list_unref (target_list);
|
||||
|
||||
gtk_drag_set_icon_default (context);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user