[gtk/dnd-gestures: 18/29] iconbrowser: Port to GtkDragSource



commit b0e06b2caa47499cdf76effb9ff6fae1adfd278e
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Dec 31 21:06:43 2019 -0500

    iconbrowser: Port to GtkDragSource

 demos/icon-browser/iconbrowserwin.c | 139 +++++++++++++++++++-----------------
 1 file changed, 72 insertions(+), 67 deletions(-)
---
diff --git a/demos/icon-browser/iconbrowserwin.c b/demos/icon-browser/iconbrowserwin.c
index 593c8cf917..9445661d5f 100644
--- a/demos/icon-browser/iconbrowserwin.c
+++ b/demos/icon-browser/iconbrowserwin.c
@@ -5,9 +5,6 @@
 #include <gtk/gtk.h>
 
 /* Drag 'n Drop */
-static const char *target_table[] = {
-  "text/uri-list"
-};
 
 typedef struct
 {
@@ -76,30 +73,11 @@ search_text_changed (GtkEntry *entry, IconBrowserWindow *win)
   gtk_tree_model_filter_refilter (win->filter_model);
 }
 
-static GdkPixbuf *
-get_icon (GtkWidget *image, const gchar *name, gint size)
-{
-  GtkIconInfo *info;
-  GtkStyleContext *context;
-  GdkTexture *texture;
-  GdkPixbuf *pixbuf;
-
-  context = gtk_widget_get_style_context (image);
-  info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (), name, size, 0);
-  texture = GDK_TEXTURE (gtk_icon_info_load_symbolic_for_context (info, context, NULL, NULL));
-  pixbuf = gdk_pixbuf_get_from_texture (texture);
-  g_object_unref (texture);
-  g_object_unref (info);
-
-  return pixbuf;
-}
-
 static void
 set_image (GtkWidget *image, const gchar *name, gint size)
 {
   gtk_image_set_from_icon_name (GTK_IMAGE (image), name);
   gtk_image_set_pixel_size (GTK_IMAGE (image), size);
-  gtk_drag_source_set_icon_name (image, name);
 }
 
 static void
@@ -365,78 +343,106 @@ search_mode_toggled (GObject *searchbar, GParamSpec *pspec, IconBrowserWindow *w
     gtk_list_box_unselect_all (GTK_LIST_BOX (win->context_list));
 }
 
+static GdkPaintable *
+get_image_paintable (GtkImage *image)
+{
+  const gchar *icon_name;
+  GtkIconTheme *icon_theme;
+  GtkIconInfo *icon_info;
+  int size;
+
+  switch (gtk_image_get_storage_type (image))
+    {
+    case GTK_IMAGE_PAINTABLE:
+      return g_object_ref (gtk_image_get_paintable (image));
+    case GTK_IMAGE_ICON_NAME:
+      icon_name = gtk_image_get_icon_name (image);
+      size = gtk_image_get_pixel_size (image);
+      icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image)));
+      icon_info = gtk_icon_theme_lookup_icon (icon_theme, icon_name, size,
+                                              GTK_ICON_LOOKUP_FORCE_SIZE | GTK_ICON_LOOKUP_GENERIC_FALLBACK);
+      if (icon_info == NULL)
+        return NULL;
+      return gtk_icon_info_load_icon (icon_info, NULL);
+    default:
+      g_warning ("Image storage type %d not handled",
+                 gtk_image_get_storage_type (image));
+      return NULL;
+    }
+}
+
 static void
-get_image_data (GtkWidget        *widget,
-                GdkDrag          *drag,
-                GtkSelectionData *selection,
-                guint             target_info,
-                gpointer          data)
+drag_begin (GtkDragSource *source,
+            GtkWidget     *widget)
 {
-  GtkWidget *image;
-  const gchar *name;
-  gint size;
-  GdkPixbuf *pixbuf;
+  GdkPaintable *paintable;
 
-  image = gtk_bin_get_child (GTK_BIN (widget));
+  paintable = get_image_paintable (GTK_IMAGE (widget));
+  if (paintable)
+    {
+      int w, h;
 
-  name = gtk_image_get_icon_name (GTK_IMAGE (image));
-  size = gtk_image_get_pixel_size (GTK_IMAGE (image));
+      w = gdk_paintable_get_intrinsic_width (paintable);
+      h = gdk_paintable_get_intrinsic_height (paintable);
+      gtk_drag_source_set_icon (source, paintable, w, h);
+      g_object_unref (paintable);
+    }
+}
 
-  pixbuf = get_icon (image, name, size);
-  gtk_selection_data_set_pixbuf (selection, pixbuf);
-  g_object_unref (pixbuf);
+static void
+get_texture (GValue   *value,
+             gpointer  data)
+{
+  GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (data));
+
+  if (GDK_IS_TEXTURE (paintable))
+    g_value_set_object (value, paintable);
 }
 
 static void
-get_scalable_image_data (GtkWidget        *widget,
-                         GdkDrag          *drag,
-                         GtkSelectionData *selection,
-                         guint             target_info,
-                         gpointer          data)
+get_file (GValue   *value,
+          gpointer  data)
 {
-  gchar *uris[2];
+  const char *name;
   GtkIconInfo *info;
-  GtkWidget *image;
   GFile *file;
-  const gchar *name;
 
-  image = gtk_bin_get_child (GTK_BIN (widget));
-  name = gtk_image_get_icon_name (GTK_IMAGE (image));
+  name = gtk_image_get_icon_name (GTK_IMAGE (data));
 
   info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (), name, -1, 0);
   file = g_file_new_for_path (gtk_icon_info_get_filename (info));
-  uris[0] = g_file_get_uri (file);
-  uris[1] = NULL;
-
-  gtk_selection_data_set_uris (selection, uris);
-
-  g_free (uris[0]);
-  g_object_unref (info);
+  g_value_set_object (value, file);
   g_object_unref (file);
+  g_object_unref (info);
 }
 
 static void
 setup_image_dnd (GtkWidget *image)
 {
-  gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, GDK_ACTION_COPY);
-  gtk_drag_source_add_image_targets (image);
-  g_signal_connect (image, "drag-data-get", G_CALLBACK (get_image_data), NULL);
+  GdkContentProvider *content;
+  GtkDragSource *source;
+
+  content = gdk_content_provider_new_with_callback (GDK_TYPE_TEXTURE, get_texture, image);
+  source = gtk_drag_source_new (content, GDK_ACTION_COPY);
+  g_object_unref (content);
+  gtk_drag_source_attach (source, image, GDK_BUTTON1_MASK);
+  g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
+  g_object_unref (source);
 }
 
 static void
 setup_scalable_image_dnd (GtkWidget *image)
 {
-  GtkWidget *parent;
-  GdkContentFormats *targets;
+  GdkContentProvider *content;
+  GtkDragSource *source;
 
-  parent = gtk_widget_get_parent (image);
-  targets = gdk_content_formats_new (target_table, G_N_ELEMENTS (target_table));
-  gtk_drag_source_set (parent, GDK_BUTTON1_MASK,
-                       targets,
-                       GDK_ACTION_COPY);
-  gdk_content_formats_unref (targets);
+  content = gdk_content_provider_new_with_callback (G_TYPE_FILE, get_file, image);
+  source = gtk_drag_source_new (content, GDK_ACTION_COPY);
+  g_object_unref (content);
 
-  g_signal_connect (parent, "drag-data-get", G_CALLBACK (get_scalable_image_data), NULL);
+  gtk_drag_source_attach (source, image, GDK_BUTTON1_MASK);
+  g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
+  g_object_unref (source);
 }
 
 static void
@@ -459,7 +465,6 @@ icon_browser_window_init (IconBrowserWindow *win)
   setup_image_dnd (win->image3);
   setup_image_dnd (win->image4);
   setup_image_dnd (win->image5);
-  setup_image_dnd (win->image6);
   setup_scalable_image_dnd (win->image6);
 
   win->contexts = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, context_free);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]