diff options
author | Matthias Clasen <mclasen@redhat.com> | 2005-05-25 15:22:43 +0000 |
---|---|---|
committer | Matthias Clasen <matthiasc@src.gnome.org> | 2005-05-25 15:22:43 +0000 |
commit | 844ab25ea4a64234358b8cf6724c65354b8256de (patch) | |
tree | d69636d42bc1d3bab89775ac4f45ecd32263e362 /demos/gtk-demo | |
parent | 7b8e0b8bc82595191cb1e5c5312c1e0c2622944f (diff) | |
download | gtk+-844ab25ea4a64234358b8cf6724c65354b8256de.tar.gz |
Demonstrate image copy-and-paste and DND, and clipboard persistency.
2005-05-25 Matthias Clasen <mclasen@redhat.com>
* demos/gtk-demo/clipboard.c: Demonstrate image copy-and-paste
and DND, and clipboard persistency.
Diffstat (limited to 'demos/gtk-demo')
-rw-r--r-- | demos/gtk-demo/clipboard.c | 218 |
1 files changed, 208 insertions, 10 deletions
diff --git a/demos/gtk-demo/clipboard.c b/demos/gtk-demo/clipboard.c index 251b165a1e..96a993db5a 100644 --- a/demos/gtk-demo/clipboard.c +++ b/demos/gtk-demo/clipboard.c @@ -1,7 +1,12 @@ /* Clipboard * * GtkClipboard is used for clipboard handling. This demo shows how to - * copy and paste text to and from the clipboard. + * copy and paste text to and from the clipboard. + * + * It also shows how to transfer images via the clipboard or via + * drag-and-drop, and how to make clipboard contents persist after + * the application exits. Clipboard persistence requires a clipboard + * manager to run. */ #include <gtk/gtk.h> @@ -11,7 +16,7 @@ static GtkWidget *window = NULL; void copy_button_clicked (GtkWidget *button, - gpointer user_data) + gpointer user_data) { GtkWidget *entry; GtkClipboard *clipboard; @@ -20,7 +25,7 @@ copy_button_clicked (GtkWidget *button, /* Get the clipboard object */ clipboard = gtk_widget_get_clipboard (entry, - GDK_SELECTION_CLIPBOARD); + GDK_SELECTION_CLIPBOARD); /* Set clipboard text */ gtk_clipboard_set_text (clipboard, gtk_entry_get_text (GTK_ENTRY (entry)), -1); @@ -28,8 +33,8 @@ copy_button_clicked (GtkWidget *button, void paste_received (GtkClipboard *clipboard, - const gchar *text, - gpointer user_data) + const gchar *text, + gpointer user_data) { GtkWidget *entry; @@ -41,7 +46,7 @@ paste_received (GtkClipboard *clipboard, void paste_button_clicked (GtkWidget *button, - gpointer user_data) + gpointer user_data) { GtkWidget *entry; GtkClipboard *clipboard; @@ -50,13 +55,139 @@ paste_button_clicked (GtkWidget *button, /* Get the clipboard object */ clipboard = gtk_widget_get_clipboard (entry, - GDK_SELECTION_CLIPBOARD); + GDK_SELECTION_CLIPBOARD); /* Request the contents of the clipboard, contents_received will be called when we do get the contents. */ gtk_clipboard_request_text (clipboard, - paste_received, entry); + paste_received, entry); +} + +static GdkPixbuf * +get_image_pixbuf (GtkImage *image) +{ + gchar *stock_id; + GtkIconSize size; + + switch (gtk_image_get_storage_type (image)) + { + case GTK_IMAGE_PIXBUF: + return g_object_ref (gtk_image_get_pixbuf (image)); + case GTK_IMAGE_STOCK: + gtk_image_get_stock (image, &stock_id, &size); + return gtk_widget_render_icon (GTK_WIDGET (image), + stock_id, size, NULL); + default: + g_warning ("Image storage type %d not handled", + gtk_image_get_storage_type (image)); + return NULL; + } +} + +static void +drag_begin (GtkWidget *widget, + GdkDragContext *context, + gpointer data) +{ + GdkPixbuf *pixbuf; + + pixbuf = get_image_pixbuf (GTK_IMAGE (data)); + gtk_drag_set_icon_pixbuf (context, pixbuf, -2, -2); + g_object_unref (pixbuf); +} + +void +drag_data_get (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time, + gpointer data) +{ + GdkPixbuf *pixbuf; + + pixbuf = get_image_pixbuf (GTK_IMAGE (data)); + gtk_selection_data_set_pixbuf (selection_data, pixbuf); + g_object_unref (pixbuf); +} + +static void +drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint32 time, + gpointer data) +{ + GdkPixbuf *pixbuf; + + if (selection_data->length > 0) + { + pixbuf = gtk_selection_data_get_pixbuf (selection_data); + gtk_image_set_from_pixbuf (GTK_IMAGE (data), pixbuf); + g_object_unref (pixbuf); + } +} + +static void +copy_image (GtkMenuItem *item, + gpointer data) +{ + GtkClipboard *clipboard; + GdkPixbuf *pixbuf; + + clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); + pixbuf = get_image_pixbuf (GTK_IMAGE (data)); + + gtk_clipboard_set_image (clipboard, pixbuf); + g_object_unref (pixbuf); +} + +static void +paste_image (GtkMenuItem *item, + gpointer data) +{ + GtkClipboard *clipboard; + GdkPixbuf *pixbuf; + + clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); + pixbuf = gtk_clipboard_wait_for_image (clipboard); + + if (pixbuf) + { + gtk_image_set_from_pixbuf (GTK_IMAGE (data), pixbuf); + g_object_unref (pixbuf); + } +} + +static gboolean +button_press (GtkWidget *widget, + GdkEventButton *button, + gpointer data) +{ + GtkWidget *menu; + GtkWidget *item; + + if (button->button != 3) + return FALSE; + + menu = gtk_menu_new (); + + item = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, NULL); + g_signal_connect (item, "activate", G_CALLBACK (copy_image), data); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + item = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, NULL); + g_signal_connect (item, "activate", G_CALLBACK (paste_image), data); + gtk_widget_show (item); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 3, button->time); + return TRUE; } GtkWidget * @@ -67,8 +198,13 @@ do_clipboard (GtkWidget *do_widget) GtkWidget *vbox, *hbox; GtkWidget *label; GtkWidget *entry, *button; + GtkWidget *ebox, *image; + GtkClipboard *clipboard; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + g_signal_connect (window, "destroy", + G_CALLBACK (gtk_widget_destroyed), &window); + vbox = gtk_vbox_new (FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (vbox), 8); @@ -90,7 +226,7 @@ do_clipboard (GtkWidget *do_widget) button = gtk_button_new_from_stock (GTK_STOCK_COPY); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); g_signal_connect (button, "clicked", - G_CALLBACK (copy_button_clicked), entry); + G_CALLBACK (copy_button_clicked), entry); label = gtk_label_new ("\"Paste\" will paste the text from the clipboard to the entry"); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); @@ -107,8 +243,70 @@ do_clipboard (GtkWidget *do_widget) button = gtk_button_new_from_stock (GTK_STOCK_PASTE); gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); g_signal_connect (button, "clicked", - G_CALLBACK (paste_button_clicked), entry); + G_CALLBACK (paste_button_clicked), entry); + + label = gtk_label_new ("Images can be transferred via the clipboard, too"); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + + hbox = gtk_hbox_new (FALSE, 4); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 8); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + /* Create the first image */ + image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, + GTK_ICON_SIZE_BUTTON); + ebox = gtk_event_box_new (); + gtk_container_add (GTK_CONTAINER (ebox), image); + gtk_container_add (GTK_CONTAINER (hbox), ebox); + + /* make ebox a drag source */ + gtk_drag_source_set (ebox, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY); + gtk_drag_source_add_image_targets (ebox); + g_signal_connect (ebox, "drag_begin", + G_CALLBACK (drag_begin), image); + g_signal_connect (ebox, "drag_data_get", + G_CALLBACK (drag_data_get), image); + + /* accept drops on ebox */ + gtk_drag_dest_set (ebox, GTK_DEST_DEFAULT_ALL, + NULL, 0, GDK_ACTION_COPY); + gtk_drag_dest_add_image_targets (ebox); + g_signal_connect (ebox, "drag_data_received", + G_CALLBACK (drag_data_received), image); + + /* context menu on ebox */ + g_signal_connect (ebox, "button_press_event", + G_CALLBACK (button_press), image); + + /* Create the second image */ + image = gtk_image_new_from_stock (GTK_STOCK_STOP, + GTK_ICON_SIZE_BUTTON); + ebox = gtk_event_box_new (); + gtk_container_add (GTK_CONTAINER (ebox), image); + gtk_container_add (GTK_CONTAINER (hbox), ebox); + + /* make ebox a drag source */ + gtk_drag_source_set (ebox, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY); + gtk_drag_source_add_image_targets (ebox); + g_signal_connect (ebox, "drag_begin", + G_CALLBACK (drag_begin), image); + g_signal_connect (ebox, "drag_data_get", + G_CALLBACK (drag_data_get), image); + + /* accept drops on ebox */ + gtk_drag_dest_set (ebox, GTK_DEST_DEFAULT_ALL, + NULL, 0, GDK_ACTION_COPY); + gtk_drag_dest_add_image_targets (ebox); + g_signal_connect (ebox, "drag_data_received", + G_CALLBACK (drag_data_received), image); + + /* context menu on ebox */ + g_signal_connect (ebox, "button_press_event", + G_CALLBACK (button_press), image); + /* tell the clipboard manager to make the data persistent */ + clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_can_store (clipboard, NULL, 0); } if (!GTK_WIDGET_VISIBLE (window)) |