Commit 2a697827 authored by Benjamin Otte's avatar Benjamin Otte
Browse files

dragicon: Add gtk_drag_icon_create_widget_for_value()

... and use it to set a drag icon.
parent b2c3e39c
......@@ -6885,6 +6885,9 @@ gtk_drag_icon_set_child
gtk_drag_icon_get_child
gtk_drag_icon_set_from_paintable
<SUBSECTION>
gtk_drag_icon_create_widget_for_value
<SUBSECTION Standard>
GTK_TYPE_DRAG_ICON
GTK_DRAG_ICON
......
......@@ -29,6 +29,11 @@
#include "gtkpicture.h"
#include "gtkcssnumbervalueprivate.h"
/* for the drag icons */
#include "gtkcolorswatchprivate.h"
#include "gtklabel.h"
#include "gtktextutil.h"
/**
* SECTION:gtkdragicon
......@@ -497,3 +502,62 @@ gtk_drag_icon_get_child (GtkDragIcon *self)
return self->child;
}
/**
* gtk_drag_icon_create_widget_for_value:
* @value: a #GValue
*
* Creates a widget that can be used as a drag icon for the given
* @value.
*
* If GTK does not know how to create a widget for a given value,
* it will return %NULL.
*
* This method is used to set the default drag icon on drag'n'drop
* operations started by #GtkDragSource, so you don't need to set
* a drag icon using this function there.
*
* Returns: (nullable) (transfer full): A new #GtkWidget
* for displaying @value as a drag icon.
**/
GtkWidget *
gtk_drag_icon_create_widget_for_value (const GValue *value)
{
g_return_val_if_fail (G_IS_VALUE (value), NULL);
if (G_VALUE_HOLDS (value, G_TYPE_STRING))
{
return gtk_label_new (g_value_get_string (value));
}
else if (G_VALUE_HOLDS (value, GDK_TYPE_RGBA))
{
GtkWidget *swatch;
swatch = gtk_color_swatch_new ();
gtk_color_swatch_set_rgba (GTK_COLOR_SWATCH (swatch), g_value_get_boxed (value));
return swatch;
}
else if (G_VALUE_HOLDS (value, GTK_TYPE_TEXT_BUFFER))
{
GtkTextBuffer *buffer = g_value_get_object (value);
GtkTextIter start, end;
GdkPaintable *paintable;
GtkWidget *picture;
if (buffer == NULL || !gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
return NULL;
picture = gtk_picture_new ();
paintable = gtk_text_util_create_rich_drag_icon (picture, buffer, &start, &end);
gtk_picture_set_paintable (GTK_PICTURE (picture), paintable);
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
g_object_unref (paintable);
return picture;
}
else
{
return NULL;
}
}
......@@ -52,6 +52,8 @@ void gtk_drag_icon_set_from_paintable (GdkDrag *drag,
int hot_x,
int hot_y);
GtkWidget * gtk_drag_icon_create_widget_for_value (const GValue *value);
G_END_DECLS
......
......@@ -439,6 +439,52 @@ gtk_drag_source_cancel_cb (GdkDrag *drag,
drag_end (source, FALSE);
}
static void
gtk_drag_source_ensure_icon (GtkDragSource *self,
GdkDrag *drag)
{
GdkContentProvider *provider;
GtkWidget *icon, *child;
GdkContentFormats *formats;
const GType *types;
gsize i, n_types;
icon = gtk_drag_icon_get_for_drag (drag);
/* If an icon has been set already, we don't need to set one. */
if (gtk_drag_icon_get_child (GTK_DRAG_ICON (icon)))
return;
gdk_drag_set_hotspot (drag, -2, -2);
provider = gdk_drag_get_content (drag);
formats = gdk_content_provider_ref_formats (provider);
types = gdk_content_formats_get_gtypes (formats, &n_types);
for (i = 0; i < n_types; i++)
{
GValue value = G_VALUE_INIT;
g_value_init (&value, types[i]);
if (gdk_content_provider_get_value (provider, &value, NULL))
{
child = gtk_drag_icon_create_widget_for_value (&value);
if (child)
{
gtk_drag_icon_set_child (GTK_DRAG_ICON (icon), child);
g_value_unset (&value);
gdk_content_formats_unref (formats);
return;
}
}
g_value_unset (&value);
}
gdk_content_formats_unref (formats);
child = gtk_image_new_from_icon_name ("text-x-generic");
gtk_image_set_icon_size (GTK_IMAGE (child), GTK_ICON_SIZE_LARGE);
gtk_drag_icon_set_child (GTK_DRAG_ICON (icon), child);
}
static void
gtk_drag_source_drag_begin (GtkDragSource *source)
{
......@@ -481,23 +527,7 @@ gtk_drag_source_drag_begin (GtkDragSource *source)
g_signal_emit (source, signals[DRAG_BEGIN], 0, source->drag);
if (!source->paintable)
{
GtkIconTheme *theme;
theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
source->paintable = GDK_PAINTABLE(gtk_icon_theme_lookup_icon (theme,
"text-x-generic",
NULL,
32,
1,
gtk_widget_get_direction (widget),
0));
source->hot_x = 0;
source->hot_y = 0;
}
gtk_drag_icon_set_from_paintable (source->drag, source->paintable, source->hot_x, source->hot_y);
gtk_drag_source_ensure_icon (source, source->drag);
g_signal_connect (source->drag, "dnd-finished",
G_CALLBACK (gtk_drag_source_dnd_finished_cb), source);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment