[gtk/dnd-gestures-2] Add another dnd testcase
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/dnd-gestures-2] Add another dnd testcase
- Date: Wed, 8 Jan 2020 18:01:28 +0000 (UTC)
commit a51a9c38aab39467135ff479640e0bc2d8684785
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 and interaction between
DND and other gestures.
tests/meson.build | 1 +
tests/testdnd3.c | 377 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 378 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..e0289b138e
--- /dev/null
+++ b/tests/testdnd3.c
@@ -0,0 +1,377 @@
+#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;
+
+typedef struct {
+ double x, y;
+ double angle;
+ double delta;
+} TransformData;
+
+static void
+apply_transform (GtkWidget *item)
+{
+ GtkWidget *canvas = gtk_widget_get_parent (item);
+ TransformData *data;
+ GskTransform *transform;
+
+ data = g_object_get_data (G_OBJECT (item), "transform-data");
+ transform = gsk_transform_rotate (gsk_transform_translate (NULL, &(graphene_point_t){data->x, data->y}),
+ data->angle + data->delta);
+ gtk_fixed_set_child_transform (GTK_FIXED (canvas), item, transform);
+ gsk_transform_unref (transform);
+}
+
+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;
+ TransformData *transform_data;
+
+ 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);
+
+ transform_data = g_object_get_data (G_OBJECT (item), "transform-data");
+
+ transform_data->x = data->x;
+ transform_data->y = data->y;
+
+ apply_transform (item);
+
+ 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)
+{
+ if (gtk_drop_target_find_mimetype (dest) != NULL)
+ {
+ gdk_drop_status (drop, GDK_ACTION_COPY);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+angle_changed (GtkGestureRotate *gesture,
+ double angle,
+ double delta)
+{
+ GtkWidget *item = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
+ TransformData *data = g_object_get_data (G_OBJECT (item), "transform-data");
+
+ data->delta = angle / M_PI * 180.0;
+
+ apply_transform (item);
+}
+
+static void
+rotate_done (GtkGesture *gesture)
+{
+ GtkWidget *item = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
+ TransformData *data = g_object_get_data (G_OBJECT (item), "transform-data");
+
+ data->angle = data->angle + data->delta;
+ data->delta = 0;
+}
+
+static GtkWidget *
+canvas_item_new (int i,
+ double x,
+ double y,
+ double angle)
+{
+ GtkWidget *widget;
+ char *label;
+ char *id;
+ TransformData *transform_data;
+ GdkRGBA rgba;
+ GtkDropTarget *dest;
+ GdkContentFormats *formats;
+ GtkGesture *gesture;
+
+ 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);
+ transform_data = g_new0 (TransformData, 1);
+ transform_data->x = x;
+ transform_data->y = y;
+ transform_data->angle = angle;
+ g_object_set_data_full (G_OBJECT (widget), "transform-data", transform_data, g_free);
+
+ 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);
+
+ gesture = gtk_gesture_rotate_new ();
+ g_signal_connect (gesture, "angle-changed", G_CALLBACK (angle_changed), NULL);
+ g_signal_connect (gesture, "end", G_CALLBACK (rotate_done), NULL);
+ gtk_widget_add_controller (widget, GTK_EVENT_CONTROLLER (gesture));
+
+ 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", "cyan", "bisque", "gold", "maroon",
+ "navy", "orchid", "olive", "peru", "salmon", "silver", "wheat",
+ NULL
+ };
+ int i;
+ int x, y;
+
+ 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), 640, 480);
+
+ 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);
+
+ x = y = 40;
+ for (i = 0; i < 4; i++)
+ {
+ GtkWidget *item;
+
+ item = canvas_item_new (i, x, y, 0);
+ gtk_container_add (GTK_CONTAINER (canvas), item);
+ apply_transform (item);
+
+ x += 150;
+ y += 100;
+ }
+
+ 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]