diff options
author | Matthias Clasen <mclasen@redhat.com> | 2005-07-11 17:51:54 +0000 |
---|---|---|
committer | Matthias Clasen <matthiasc@src.gnome.org> | 2005-07-11 17:51:54 +0000 |
commit | 13a341e0e9f8f99c3749161ab60424eb10815d59 (patch) | |
tree | d56ea566430bbf66e69f7509cb9a0780f63de429 /gtk/gtktextutil.c | |
parent | 7912643e8f2f7a98d625ce99e8a924b1a2fd744c (diff) | |
download | gtk+-13a341e0e9f8f99c3749161ab60424eb10815d59.tar.gz |
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.
Diffstat (limited to 'gtk/gtktextutil.c')
-rw-r--r-- | gtk/gtktextutil.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/gtk/gtktextutil.c b/gtk/gtktextutil.c index 9d72c18646..e9f535c7c3 100644 --- a/gtk/gtktextutil.c +++ b/gtk/gtktextutil.c @@ -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; +} |