[gtk/dnd-gestures-2] Add another dnd testcase



commit cff177bacf8e0e0507937bb816c6219f13edec23
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Jan 8 10:34:56 2020 -0500

    Add another dnd testcase
    
    This one tests nested drop sites.

 tests/meson.build |   1 +
 tests/testdnd3.c  | 310 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 311 insertions(+)
---
diff --git a/tests/meson.build b/tests/meson.build
index 8becf6a9f3..37d6f0d87f 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -31,6 +31,7 @@ gtk_tests = [
   ['testdialog'],
   ['testdnd'],
   ['testdnd2'],
+  ['testdnd3'],
   ['testellipsise'],
   ['testemblems'],
   ['testentrycompletion'],
diff --git a/tests/testdnd3.c b/tests/testdnd3.c
new file mode 100644
index 0000000000..cfee7fa98b
--- /dev/null
+++ b/tests/testdnd3.c
@@ -0,0 +1,310 @@
+#include <gtk/gtk.h>
+
+static GdkContentProvider *
+prepare (GtkDragSource *source,  double x, double y)
+{
+  GtkWidget *canvas;
+  GtkWidget *item;
+  GdkContentProvider *provider;
+  GBytes *bytes;
+
+  canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
+  item = gtk_widget_pick (canvas, x, y, GTK_PICK_DEFAULT);
+
+  if (!GTK_IS_LABEL (item))
+    return NULL;
+
+  bytes = g_bytes_new (&item, sizeof (gpointer));
+  provider = gdk_content_provider_new_for_bytes ("CANVAS_ITEM", bytes);
+  g_bytes_unref (bytes);
+
+  g_object_set_data (G_OBJECT (canvas), "dragged-item", item);
+
+  return provider;
+}
+
+static void
+drag_begin (GtkDragSource *source, GdkDrag *drag)
+{
+  GtkWidget *canvas;
+  GtkWidget *item;
+
+  canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
+  item = g_object_get_data (G_OBJECT (canvas), "dragged-item");
+
+  gtk_widget_set_opacity (item, 0.5);
+}
+
+static void
+drag_end (GtkDragSource *source, GdkDrag *drag)
+{
+  GtkWidget *canvas;
+  GtkWidget *item;
+
+  canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
+  item = g_object_get_data (G_OBJECT (canvas), "dragged-item");
+  g_object_set_data (G_OBJECT (canvas), "dragged-item", NULL);
+
+  gtk_widget_set_opacity (item, 1.0);
+}
+
+typedef struct {
+  GtkWidget *canvas;
+  double x;
+  double y;
+} DropData;
+
+static void
+got_data (GObject      *source,
+          GAsyncResult *result,
+          gpointer      user_data)
+{
+  GdkDrop *drop = GDK_DROP (source);
+  DropData *data = user_data;
+  GInputStream *stream;
+  GBytes *bytes;
+  GtkWidget *item;
+  const char *mime_type;
+  GError *error = NULL;
+
+  stream = gdk_drop_read_finish (drop, result, &mime_type, &error);
+  bytes = g_input_stream_read_bytes (stream, sizeof (gpointer), NULL, NULL);
+  item = (gpointer) *(gpointer *)g_bytes_get_data (bytes, NULL);
+
+  g_print ("received item %p, %s, at %g %g\n",
+           item, gtk_label_get_label (GTK_LABEL (item)),
+           data->x, data->y);
+
+  gtk_fixed_move (GTK_FIXED (data->canvas), item, data->x, data->y);
+
+  gdk_drop_finish (drop, GDK_ACTION_MOVE);
+
+  g_bytes_unref (bytes);
+  g_object_unref (stream);
+  g_free (data);
+}
+
+static gboolean
+drag_drop (GtkDropTarget *dest,
+           GdkDrop       *drop,
+           int            x,
+           int            y)
+{
+  DropData *data;
+
+  data = g_new (DropData, 1);
+  data->canvas = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
+  data->x = x;
+  data->y = y;
+
+  gdk_drop_read_async (drop, (const char *[]){"CANVAS_ITEM", NULL}, G_PRIORITY_DEFAULT, NULL, got_data, 
data);
+
+  return TRUE;
+}
+
+static GtkWidget *
+canvas_new (void)
+{
+  GtkWidget *canvas;
+  GtkDragSource *source;
+  GtkDropTarget *dest;
+  GdkContentFormats *formats;
+
+  canvas = gtk_fixed_new ();
+  gtk_widget_set_hexpand (canvas, TRUE);
+  gtk_widget_set_vexpand (canvas, TRUE);
+  gtk_style_context_add_class (gtk_widget_get_style_context (canvas), "frame");
+
+  source = gtk_drag_source_new ();
+  gtk_drag_source_set_actions (source, GDK_ACTION_MOVE);
+  g_signal_connect (source, "prepare", G_CALLBACK (prepare), NULL);
+  g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), NULL);
+  g_signal_connect (source, "drag-end", G_CALLBACK (drag_end), NULL);
+  gtk_widget_add_controller (canvas, GTK_EVENT_CONTROLLER (source));
+
+  formats = gdk_content_formats_new ((const char *[]){"CANVAS_ITEM", NULL}, 1);
+  dest = gtk_drop_target_new (formats, GDK_ACTION_MOVE);
+  g_signal_connect (dest, "drag-drop", G_CALLBACK (drag_drop), NULL);
+  gtk_widget_add_controller (canvas, GTK_EVENT_CONTROLLER (dest));
+  gdk_content_formats_unref (formats);
+
+  return canvas;
+}
+
+static void
+set_color (GtkWidget *item,
+           GdkRGBA   *color)
+{
+  char *css;
+  char *str;
+  GtkStyleContext *context;
+  GtkCssProvider *provider;
+
+  str = gdk_rgba_to_string (color);
+  css = g_strdup_printf ("* { background: %s; padding: 10px; }", str);
+
+  context = gtk_widget_get_style_context (item);
+  provider = g_object_get_data (G_OBJECT (context), "style-provider");
+  if (provider)
+    gtk_style_context_remove_provider (context, GTK_STYLE_PROVIDER (provider));
+
+  provider = gtk_css_provider_new ();
+  gtk_css_provider_load_from_data (provider, css, -1);
+  gtk_style_context_add_provider (gtk_widget_get_style_context (item), GTK_STYLE_PROVIDER (provider), 800);
+  g_object_set_data_full (G_OBJECT (context), "style-provider", provider, g_object_unref);
+
+  g_free (str);
+  g_free (css);
+}
+
+static void
+got_color (GObject *source,
+           GAsyncResult *result,
+           gpointer data)
+{
+  GdkDrop *drop = GDK_DROP (source);
+  GtkDropTarget *dest = data;
+  GtkWidget *item = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
+  const GValue *value;
+  GdkRGBA *color;
+
+  value = gdk_drop_read_value_finish (drop, result, NULL);
+  color = g_value_get_boxed (value);
+  set_color (item, color);
+
+  gdk_drop_finish (drop, GDK_ACTION_COPY);
+}
+
+static gboolean
+item_drag_drop (GtkDropTarget *dest,
+                GdkDrop       *drop,
+               int            x,
+               int            y)
+{
+  if (gtk_drop_target_find_mimetype (dest))
+    {
+      gdk_drop_read_value_async (drop, GDK_TYPE_RGBA, G_PRIORITY_DEFAULT, NULL, got_color, dest);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+item_drag_motion (GtkDropTarget *dest,
+                  GdkDrop       *drop,
+                  int            x,
+                  int            y)
+{
+  g_print ("item drag-motion: %s\n", gtk_drop_target_find_mimetype (dest));
+  if (gtk_drop_target_find_mimetype (dest) != NULL)
+    {
+      gdk_drop_status (drop, GDK_ACTION_COPY);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static GtkWidget *
+canvas_item_new (int i)
+{
+  GtkWidget *widget;
+  char *label;
+  char *id;
+  GdkRGBA rgba;
+  GtkDropTarget *dest;
+  GdkContentFormats *formats;
+
+  label = g_strdup_printf ("Item %d", i);
+  id = g_strdup_printf ("item%d", i);
+
+  gdk_rgba_parse (&rgba, "yellow");
+
+  widget = gtk_label_new (label);
+  gtk_style_context_add_class (gtk_widget_get_style_context (widget), "frame");
+  gtk_widget_set_name (widget, id);
+
+  set_color (widget, &rgba);
+
+  g_free (label);
+  g_free (id);
+
+  formats = gdk_content_formats_new_for_gtype (GDK_TYPE_RGBA);
+  dest = gtk_drop_target_new (formats, GDK_ACTION_COPY);
+  g_signal_connect (dest, "drag-drop", G_CALLBACK (item_drag_drop), NULL);
+  g_signal_connect (dest, "drag-motion", G_CALLBACK (item_drag_motion), NULL);
+  gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (dest));
+  gdk_content_formats_unref (formats);
+
+  return widget;
+}
+
+int main (int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *sw;
+  GtkWidget *canvas;
+  GtkWidget *widget;
+  GtkWidget *box, *box2, *box3;
+  const char *colors[] = {
+    "red", "green", "blue", "magenta", "orange", "gray", "black", "yellow",
+    "white", "gray", "brown", "pink",  NULL
+  };
+  int i;
+
+  gtk_init ();
+
+  widget = gtk_color_button_new ();
+  gtk_widget_destroy (widget);
+  
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
+
+  box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+  gtk_container_add (GTK_CONTAINER (window), box);
+
+  box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+  gtk_container_add (GTK_CONTAINER (box), box2);
+
+  canvas = canvas_new ();
+  gtk_container_add (GTK_CONTAINER (box2), canvas);
+
+  for (i = 0; i < 4; i++)
+    {
+      GtkWidget *item;
+
+      item = canvas_item_new (i);
+      gtk_fixed_put (GTK_FIXED (canvas), item, 50 * i, 50 * i);
+    }
+
+  sw = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+                                  GTK_POLICY_AUTOMATIC,
+                                  GTK_POLICY_NEVER);
+  gtk_container_add (GTK_CONTAINER (box), sw);
+
+  box3 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+  gtk_style_context_add_class (gtk_widget_get_style_context (box3), "linked");
+  gtk_container_add (GTK_CONTAINER (sw), box3);
+
+  for (i = 0; colors[i]; i++)
+    {
+      GdkRGBA rgba;
+      GtkWidget *swatch;
+
+      gdk_rgba_parse (&rgba, colors[i]);
+
+      swatch = g_object_new (g_type_from_name ("GtkColorSwatch"),
+                             "rgba", &rgba,
+                             "selectable", FALSE,
+                             NULL);
+      gtk_container_add (GTK_CONTAINER (box3), swatch);
+    }
+
+  gtk_widget_show (window);
+
+  gtk_main ();
+
+  return 0;
+}


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