summaryrefslogtreecommitdiff
path: root/gtk/gtktextutil.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2005-07-11 17:51:54 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2005-07-11 17:51:54 +0000
commit13a341e0e9f8f99c3749161ab60424eb10815d59 (patch)
treed56ea566430bbf66e69f7509cb9a0780f63de429 /gtk/gtktextutil.c
parent7912643e8f2f7a98d625ce99e8a924b1a2fd744c (diff)
downloadgtk+-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.c124
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;
+}