[gtk/clipboard-demo-improvements: 2/2] gtk-demo: Add dnd back to the clipboard demo
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/clipboard-demo-improvements: 2/2] gtk-demo: Add dnd back to the clipboard demo
- Date: Sun, 12 Dec 2021 21:27:58 +0000 (UTC)
commit 787111a145849bdfaafb5ed4156fe748b140e372
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Dec 12 16:25:07 2021 -0500
gtk-demo: Add dnd back to the clipboard demo
demos/gtk-demo/clipboard.c | 162 ++++++++++++++++++++++++++++++--------------
demos/gtk-demo/clipboard.ui | 30 +++++++-
2 files changed, 142 insertions(+), 50 deletions(-)
---
diff --git a/demos/gtk-demo/clipboard.c b/demos/gtk-demo/clipboard.c
index 4b3dbcb9c2..9a9be6d9e5 100644
--- a/demos/gtk-demo/clipboard.c
+++ b/demos/gtk-demo/clipboard.c
@@ -2,6 +2,9 @@
*
* GdkClipboard is used for clipboard handling. This demo shows how to
* copy and paste text, images, colors or files to and from the clipboard.
+ *
+ * You can also use Drag-And-Drop to copy the data from the source to the
+ * target.
*/
#include <glib/gi18n.h>
@@ -62,6 +65,52 @@ copy_button_clicked (GtkStack *source_stack,
}
}
+static void
+present_value (GtkStack *dest_stack,
+ const GValue *value)
+{
+ GtkWidget *child;
+
+ if (G_VALUE_HOLDS (value, G_TYPE_FILE))
+ {
+ GFile *file;
+
+ gtk_stack_set_visible_child_name (dest_stack, "File");
+ child = gtk_stack_get_visible_child (dest_stack);
+
+ file = g_value_get_object (value);
+ g_object_set (child, "label", g_file_peek_path (file), NULL);
+ }
+ else if (G_VALUE_HOLDS (value, GDK_TYPE_RGBA))
+ {
+ GdkRGBA *color;
+
+ gtk_stack_set_visible_child_name (dest_stack, "Color");
+ child = gtk_widget_get_first_child (gtk_stack_get_visible_child (dest_stack));
+
+ color = g_value_get_boxed (value);
+ g_object_set (child, "rgba", color, NULL);
+ }
+ else if (G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE) ||
+ G_VALUE_HOLDS (value, GDK_TYPE_PAINTABLE))
+ {
+ GdkPaintable *paintable;
+
+ gtk_stack_set_visible_child_name (dest_stack, "Image");
+ child = gtk_stack_get_visible_child (dest_stack);
+
+ paintable = g_value_get_object (value);
+ g_object_set (child, "paintable", paintable, NULL);
+ }
+ else if (G_VALUE_HOLDS (value, G_TYPE_STRING))
+ {
+ gtk_stack_set_visible_child_name (dest_stack, "Text");
+ child = gtk_stack_get_visible_child (dest_stack);
+
+ gtk_label_set_label (GTK_LABEL (child), g_value_get_string (value));
+ }
+}
+
static void
paste_received (GObject *source_object,
GAsyncResult *result,
@@ -71,51 +120,13 @@ paste_received (GObject *source_object,
GdkClipboard *clipboard;
const GValue *value;
GError *error = NULL;
- GtkWidget *child;
clipboard = GDK_CLIPBOARD (source_object);
value = gdk_clipboard_read_value_finish (clipboard, result, &error);
if (value)
{
- if (G_VALUE_HOLDS (value, G_TYPE_FILE))
- {
- GFile *file;
-
- gtk_stack_set_visible_child_name (dest_stack, "File");
- child = gtk_stack_get_visible_child (dest_stack);
-
- file = g_value_get_object (value);
- g_object_set (child, "label", g_file_peek_path (file), NULL);
- }
- else if (G_VALUE_HOLDS (value, GDK_TYPE_RGBA))
- {
- GdkRGBA *color;
-
- gtk_stack_set_visible_child_name (dest_stack, "Color");
- child = gtk_widget_get_first_child (gtk_stack_get_visible_child (dest_stack));
-
- color = g_value_get_boxed (value);
- g_object_set (child, "rgba", color, NULL);
- }
- else if (G_VALUE_HOLDS (value, GDK_TYPE_TEXTURE) ||
- G_VALUE_HOLDS (value, GDK_TYPE_PAINTABLE))
- {
- GdkPaintable *paintable;
-
- gtk_stack_set_visible_child_name (dest_stack, "Image");
- child = gtk_stack_get_visible_child (dest_stack);
-
- paintable = g_value_get_object (value);
- g_object_set (child, "paintable", paintable, NULL);
- }
- else if (G_VALUE_HOLDS (value, G_TYPE_STRING))
- {
- gtk_stack_set_visible_child_name (dest_stack, "Text");
- child = gtk_stack_get_visible_child (dest_stack);
-
- gtk_label_set_label (GTK_LABEL (child), g_value_get_string (value));
- }
+ present_value (dest_stack, value);
}
else
{
@@ -264,6 +275,60 @@ unset_clipboard_handler (gpointer data)
g_signal_handlers_disconnect_by_func (clipboard, update_paste_button_sensitivity, data);
}
+static gboolean
+on_drop (GtkStack *dest_stack,
+ const GValue *value,
+ double x,
+ double y,
+ gpointer data)
+{
+ present_value (dest_stack, value);
+ return TRUE;
+}
+
+static GdkContentProvider *
+drag_prepare (GtkDragSource *drag_source,
+ double x,
+ double y,
+ gpointer data)
+{
+ GtkWidget *button;
+ GValue value = G_VALUE_INIT;
+
+ button = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (drag_source));
+
+ if (GTK_IS_TOGGLE_BUTTON (button))
+ {
+ GtkWidget *image = gtk_widget_get_first_child (button);
+ GdkPaintable *paintable = gtk_image_get_paintable (GTK_IMAGE (image));
+
+ if (GDK_IS_TEXTURE (paintable))
+ {
+ g_value_init (&value, GDK_TYPE_TEXTURE);
+ g_value_set_object (&value, paintable);
+ }
+ else
+ {
+ g_value_init (&value, GDK_TYPE_PAINTABLE);
+ g_value_set_object (&value, paintable);
+ }
+ }
+ else
+ {
+ GFile *file = g_object_get_data (G_OBJECT (button), "file");
+
+ if (file)
+ {
+ g_value_init (&value, G_TYPE_FILE);
+ g_value_set_object (&value, file);
+ }
+ else
+ return NULL;
+ }
+
+ return gdk_content_provider_new_for_value (&value);
+}
+
GtkWidget *
do_clipboard (GtkWidget *do_widget)
{
@@ -273,9 +338,7 @@ do_clipboard (GtkWidget *do_widget)
{
GtkBuilderScope *scope;
GtkBuilder *builder;
- GObject *copy_button;
- GObject *source_stack;
- GtkWidget *paste_button;
+ GtkWidget *button;
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
@@ -284,6 +347,8 @@ do_clipboard (GtkWidget *do_widget)
"source_changed_cb", G_CALLBACK (source_changed_cb),
"text_changed_cb", G_CALLBACK (text_changed_cb),
"open_file_cb", G_CALLBACK (open_file_cb),
+ "on_drop", G_CALLBACK (on_drop),
+ "drag_prepare", G_CALLBACK (drag_prepare),
NULL);
builder = gtk_builder_new ();
@@ -294,14 +359,13 @@ do_clipboard (GtkWidget *do_widget)
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
- copy_button = gtk_builder_get_object (builder, "copy_button");
- source_stack = gtk_builder_get_object (builder, "source_stack");
- g_object_set_data (source_stack, "copy-button", copy_button);
+ button = GTK_WIDGET (gtk_builder_get_object (builder, "copy_button"));
+ g_object_set_data (gtk_builder_get_object (builder, "source_stack"), "copy-button", button);
- paste_button = GTK_WIDGET (gtk_builder_get_object (builder, "paste_button"));
- g_signal_connect (gtk_widget_get_clipboard (paste_button), "changed",
- G_CALLBACK (update_paste_button_sensitivity), paste_button);
- g_object_set_data_full (G_OBJECT (paste_button), "clipboard-handler", paste_button,
unset_clipboard_handler);
+ button = GTK_WIDGET (gtk_builder_get_object (builder, "paste_button"));
+ g_signal_connect (gtk_widget_get_clipboard (button), "changed",
+ G_CALLBACK (update_paste_button_sensitivity), button);
+ g_object_set_data_full (G_OBJECT (button), "clipboard-handler", button, unset_clipboard_handler);
g_object_unref (builder);
g_object_unref (scope);
diff --git a/demos/gtk-demo/clipboard.ui b/demos/gtk-demo/clipboard.ui
index 1930fb4fda..ef83cd4ba7 100644
--- a/demos/gtk-demo/clipboard.ui
+++ b/demos/gtk-demo/clipboard.ui
@@ -14,7 +14,7 @@
<property name="spacing">12</property>
<child>
<object class="GtkLabel">
- <property name="label">“Copy” will copy the selected data the clipboard, “Paste” will present
the current clipboard contents</property>
+ <property name="label">“Copy” will copy the selected data the clipboard, “Paste” will show the
current clipboard contents. You can also drag the data to the bottom.</property>
<property name="wrap">1</property>
<property name="max-width-chars">40</property>
</object>
@@ -83,6 +83,11 @@
<child>
<object class="GtkToggleButton" id="image_rose">
<property name="active">1</property>
+ <child>
+ <object class="GtkDragSource">
+ <signal name="prepare" handler="drag_prepare"/>
+ </object>
+ </child>
<child>
<object class="GtkImage">
<style>
@@ -96,6 +101,11 @@
<child>
<object class="GtkToggleButton" id="image_floppy">
<property name="group">image_rose</property>
+ <child>
+ <object class="GtkDragSource">
+ <signal name="prepare" handler="drag_prepare"/>
+ </object>
+ </child>
<child>
<object class="GtkImage">
<style>
@@ -109,6 +119,11 @@
<child>
<object class="GtkToggleButton" id="image_logo">
<property name="group">image_floppy</property>
+ <child>
+ <object class="GtkDragSource">
+ <signal name="prepare" handler="drag_prepare"/>
+ </object>
+ </child>
<child>
<object class="GtkImage">
<style>
@@ -128,6 +143,12 @@
<property name="name">File</property>
<property name="child">
<object class="GtkButton" id="source_file">
+ <child>
+ <object class="GtkDragSource">
+ <property name="propagation-phase">capture</property>
+ <signal name="prepare" handler="drag_prepare"/>
+ </object>
+ </child>
<property name="valign">center</property>
<property name="child">
<object class="GtkLabel">
@@ -160,6 +181,13 @@
<child>
<object class="GtkBox">
<property name="spacing">12</property>
+ <child>
+ <object class="GtkDropTarget">
+ <property name="actions">copy</property>
+ <property name="formats">GdkTexture GdkPaintable GFile GdkRGBA gchararray</property>
+ <signal name="drop" handler="on_drop" object="dest_stack"/>
+ </object>
+ </child>
<child>
<object class="GtkButton" id="paste_button">
<property name="label" translatable="yes">_Paste</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]