[gtk/wip/otte/dnd: 5/9] dragicon: Add gtk_drag_icon_create_widget_for_value()
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/dnd: 5/9] dragicon: Add gtk_drag_icon_create_widget_for_value()
- Date: Mon, 2 Mar 2020 03:33:21 +0000 (UTC)
commit 7a6546f476bc124922cdb6c6b8b57baa2edbf26f
Author: Benjamin Otte <otte redhat com>
Date: Mon Mar 2 03:11:14 2020 +0100
dragicon: Add gtk_drag_icon_create_widget_for_value()
... and use it to set a drag icon.
docs/reference/gtk/gtk4-sections.txt | 3 ++
gtk/gtkdragicon.c | 64 ++++++++++++++++++++++++++++++++++++
gtk/gtkdragicon.h | 2 ++
gtk/gtkdragsource.c | 64 ++++++++++++++++++++++++++----------
4 files changed, 116 insertions(+), 17 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 419b28193c..689ac2b024 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -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
diff --git a/gtk/gtkdragicon.c b/gtk/gtkdragicon.c
index 4e1afa522a..a01e088946 100644
--- a/gtk/gtkdragicon.c
+++ b/gtk/gtkdragicon.c
@@ -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;
+ }
+}
+
diff --git a/gtk/gtkdragicon.h b/gtk/gtkdragicon.h
index b8c70d6f86..3be995773a 100644
--- a/gtk/gtkdragicon.h
+++ b/gtk/gtkdragicon.h
@@ -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
diff --git a/gtk/gtkdragsource.c b/gtk/gtkdragsource.c
index 6b6c4d38de..017bee493c 100644
--- a/gtk/gtkdragsource.c
+++ b/gtk/gtkdragsource.c
@@ -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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]