[gtk/clipboard-demo-fixes: 2/2] gtk-demo: Polish the clipboard demo
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/clipboard-demo-fixes: 2/2] gtk-demo: Polish the clipboard demo
- Date: Sun, 26 Apr 2020 01:31:53 +0000 (UTC)
commit f8f391ceb9a5178f0ffe55f059721a7747567020
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Apr 25 21:16:02 2020 -0400
gtk-demo: Polish the clipboard demo
The DND part of this demo was broken by recent
icon theme changes. Make it work again.
And make the demo nicer by breaking out a
DemoImage widget.
demos/gtk-demo/clipboard.c | 206 +-----------------------------
demos/gtk-demo/demo.gresource.xml | 4 +
demos/gtk-demo/demoimage.c | 259 ++++++++++++++++++++++++++++++++++++++
demos/gtk-demo/demoimage.h | 13 ++
demos/gtk-demo/meson.build | 1 +
5 files changed, 283 insertions(+), 200 deletions(-)
---
diff --git a/demos/gtk-demo/clipboard.c b/demos/gtk-demo/clipboard.c
index 8fc6bb7cf54..ca8ca076700 100644
--- a/demos/gtk-demo/clipboard.c
+++ b/demos/gtk-demo/clipboard.c
@@ -12,6 +12,7 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <string.h>
+#include "demoimage.h"
static GtkWidget *window = NULL;
@@ -93,147 +94,6 @@ paste_button_clicked (GtkWidget *button,
gdk_clipboard_read_text_async (clipboard, NULL, paste_received, entry);
}
-static GdkPaintable *
-get_image_paintable (GtkImage *image)
-{
- const gchar *icon_name;
- GtkIconTheme *icon_theme;
- GtkIconPaintable *icon;
-
- 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);
- icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image)));
- icon = gtk_icon_theme_lookup_icon (icon_theme,
- icon_name,
- NULL,
- 48, 1,
- gtk_widget_get_direction (GTK_WIDGET (image)),
- 0);
- if (icon == NULL)
- return NULL;
- return GDK_PAINTABLE (icon);
-
- case GTK_IMAGE_EMPTY:
- case GTK_IMAGE_GICON:
- default:
- g_warning ("Image storage type %d not handled",
- gtk_image_get_storage_type (image));
- return NULL;
- }
-}
-
-static void
-drag_begin (GtkDragSource *source,
- GdkDrag *drag,
- GtkWidget *widget)
-{
- GdkPaintable *paintable;
-
- paintable = get_image_paintable (GTK_IMAGE (widget));
- if (paintable)
- {
- gtk_drag_source_set_icon (source, paintable, -2, -2);
- g_object_unref (paintable);
- }
-}
-
-static GdkContentProvider *
-prepare_drag (GtkDragSource *source,
- double x,
- double y,
- GtkWidget *image)
-{
- GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (image));
-
- if (!GDK_IS_TEXTURE (paintable))
- return NULL;
-
- return gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, paintable);
-}
-
-static gboolean
-drag_drop (GtkDropTarget *dest,
- const GValue *value,
- double x,
- double y,
- GtkImage *image)
-{
- GdkTexture *texture = g_value_get_object (value);
- gtk_image_set_from_paintable (GTK_IMAGE (image), GDK_PAINTABLE (texture));
-
- return TRUE;
-}
-
-static void
-copy_image (GSimpleAction *action,
- GVariant *value,
- gpointer data)
-{
- GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
- GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (data));
-
- if (GDK_IS_TEXTURE (paintable))
- gdk_clipboard_set_texture (clipboard, GDK_TEXTURE (paintable));
-
- if (paintable)
- g_object_unref (paintable);
-}
-
-static void
-paste_image_received (GObject *source,
- GAsyncResult *result,
- gpointer data)
-{
- GdkTexture *texture;
-
- texture = gdk_clipboard_read_texture_finish (GDK_CLIPBOARD (source), result, NULL);
- if (texture == NULL)
- return;
-
- gtk_image_set_from_paintable (GTK_IMAGE (data), GDK_PAINTABLE (texture));
- g_object_unref (texture);
-}
-
-static void
-paste_image (GSimpleAction *action,
- GVariant *value,
- gpointer data)
-{
- GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
- gdk_clipboard_read_texture_async (clipboard, NULL, paste_image_received, data);
-}
-
-static void
-pressed_cb (GtkGesture *gesture,
- int n_press,
- double x,
- double y,
- GtkWidget *image)
-{
- GtkWidget *popover;
- GMenu *menu;
- GMenuItem *item;
-
- menu = g_menu_new ();
- item = g_menu_item_new (_("_Copy"), "clipboard.copy");
- g_menu_append_item (menu, item);
-
- item = g_menu_item_new (_("_Paste"), "clipboard.paste");
- g_menu_append_item (menu, item);
-
- popover = gtk_popover_menu_new_from_model (G_MENU_MODEL (menu));
- gtk_widget_set_parent (popover, image);
-
- gtk_popover_set_pointing_to (GTK_POPOVER (popover), &(GdkRectangle) { x, y, 1, 1});
- gtk_popover_popup (GTK_POPOVER (popover));
-
- g_object_unref (menu);
-}
-
GtkWidget *
do_clipboard (GtkWidget *do_widget)
{
@@ -243,14 +103,6 @@ do_clipboard (GtkWidget *do_widget)
GtkWidget *label;
GtkWidget *entry, *button;
GtkWidget *image;
- GtkGesture *gesture;
- GActionEntry entries[] = {
- { "copy", copy_image, NULL, NULL, NULL },
- { "paste", paste_image, NULL, NULL, NULL },
- };
- GActionGroup *actions;
- GtkDragSource *source;
- GtkDropTarget *dest;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
@@ -320,62 +172,16 @@ do_clipboard (GtkWidget *do_widget)
gtk_container_add (GTK_CONTAINER (vbox), hbox);
/* Create the first image */
- image = gtk_image_new_from_icon_name ("dialog-warning");
- gtk_image_set_pixel_size (GTK_IMAGE (image), 48);
+ image = demo_image_new ("dialog-warning");
gtk_container_add (GTK_CONTAINER (hbox), image);
- /* make image a drag source */
- source = gtk_drag_source_new ();
- g_signal_connect (source, "prepare", G_CALLBACK (prepare_drag), NULL);
- g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
- gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
-
- /* accept drops on image */
- dest = gtk_drop_target_new (GDK_TYPE_TEXTURE, GDK_ACTION_COPY);
- g_signal_connect (dest, "drop", G_CALLBACK (drag_drop), image);
- gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (dest));
-
- /* context menu on image */
- gesture = gtk_gesture_click_new ();
- gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
- g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
- gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
-
- actions = G_ACTION_GROUP (g_simple_action_group_new ());
- g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), image);
-
- gtk_widget_insert_action_group (image, "clipboard", actions);
-
- g_object_unref (actions);
-
/* Create the second image */
- image = gtk_image_new_from_icon_name ("process-stop");
- gtk_image_set_pixel_size (GTK_IMAGE (image), 48);
+ image = demo_image_new ("process-stop");
gtk_container_add (GTK_CONTAINER (hbox), image);
- /* make image a drag source */
- source = gtk_drag_source_new ();
- g_signal_connect (source, "prepare", G_CALLBACK (prepare_drag), NULL);
- g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
- gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
-
- /* accept drops on image */
- dest = gtk_drop_target_new (GDK_TYPE_TEXTURE, GDK_ACTION_COPY);
- g_signal_connect (dest, "drop", G_CALLBACK (drag_drop), image);
- gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (dest));
-
- /* context menu on image */
- gesture = gtk_gesture_click_new ();
- gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
- g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
- gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
-
- actions = G_ACTION_GROUP (g_simple_action_group_new ());
- g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), image);
-
- gtk_widget_insert_action_group (image, "clipboard", actions);
-
- g_object_unref (actions);
+ /* Create the third image */
+ image = demo_image_new ("weather-clear");
+ gtk_container_add (GTK_CONTAINER (hbox), image);
}
if (!gtk_widget_get_visible (window))
diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml
index 3afc75c7dbf..6df9f252a19 100644
--- a/demos/gtk-demo/demo.gresource.xml
+++ b/demos/gtk-demo/demo.gresource.xml
@@ -12,6 +12,10 @@
<gresource prefix="/builder">
<file>demo.ui</file>
</gresource>
+ <gresource prefix="/clipboard">
+ <file>demoimage.c</file>
+ <file>demoimage.h</file>
+ </gresource>
<gresource prefix="/css_accordion">
<file>css_accordion.css</file>
<file>reset.css</file>
diff --git a/demos/gtk-demo/demoimage.c b/demos/gtk-demo/demoimage.c
new file mode 100644
index 00000000000..37c0acd6846
--- /dev/null
+++ b/demos/gtk-demo/demoimage.c
@@ -0,0 +1,259 @@
+#include "demoimage.h"
+#include <glib/gi18n.h>
+
+struct _DemoImage {
+ GtkWidget parent_instance;
+
+ GtkWidget *image;
+ GtkWidget *popover;
+};
+
+enum {
+ PROP_ICON_NAME = 1
+};
+
+G_DEFINE_TYPE(DemoImage, demo_image, GTK_TYPE_WIDGET)
+
+static GdkPaintable *
+get_image_paintable (GtkImage *image)
+{
+ const gchar *icon_name;
+ GtkIconTheme *icon_theme;
+ GtkIconPaintable *icon;
+
+ 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);
+ icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (image)));
+ icon = gtk_icon_theme_lookup_icon (icon_theme,
+ icon_name,
+ NULL,
+ 48, 1,
+ gtk_widget_get_direction (GTK_WIDGET (image)),
+ 0);
+ if (icon == NULL)
+ return NULL;
+ return GDK_PAINTABLE (icon);
+
+ case GTK_IMAGE_EMPTY:
+ case GTK_IMAGE_GICON:
+ default:
+ g_warning ("Image storage type %d not handled",
+ gtk_image_get_storage_type (image));
+ return NULL;
+ }
+}
+
+static void
+drag_begin (GtkDragSource *source,
+ GdkDrag *drag,
+ gpointer data)
+{
+ GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
+ DemoImage *demo = DEMO_IMAGE (widget);
+ GdkPaintable *paintable;
+
+ paintable = get_image_paintable (GTK_IMAGE (demo->image));
+ if (paintable)
+ {
+ gtk_drag_icon_set_from_paintable (drag, paintable, -2, -2);
+ g_object_unref (paintable);
+ }
+}
+
+static GdkContentProvider *
+prepare_drag (GtkDragSource *source,
+ double x,
+ double y,
+ gpointer data)
+{
+ GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (source));
+ DemoImage *demo = DEMO_IMAGE (widget);
+ GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (demo->image));
+
+ return gdk_content_provider_new_typed (GDK_TYPE_PAINTABLE, paintable);
+}
+
+static gboolean
+drag_drop (GtkDropTarget *dest,
+ const GValue *value,
+ double x,
+ double y,
+ gpointer data)
+{
+ GtkWidget *widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (dest));
+ DemoImage *demo = DEMO_IMAGE (widget);
+ GdkPaintable *paintable = g_value_get_object (value);
+
+ gtk_image_set_from_paintable (GTK_IMAGE (demo->image), paintable);
+
+ return TRUE;
+}
+
+static void
+copy_image (GtkWidget *widget,
+ const char *action_name,
+ GVariant *parameter)
+{
+ GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
+ DemoImage *demo = DEMO_IMAGE (widget);
+ GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (demo->image));
+ GValue value = G_VALUE_INIT;
+
+ g_value_init (&value, GDK_TYPE_PAINTABLE);
+ g_value_set_object (&value, paintable);
+ gdk_clipboard_set_value (clipboard, &value);
+ g_value_unset (&value);
+
+ if (paintable)
+ g_object_unref (paintable);
+}
+
+static void
+paste_image (GtkWidget *widget,
+ const char *action_name,
+ GVariant *parameter)
+{
+ GdkClipboard *clipboard = gtk_widget_get_clipboard (widget);
+ DemoImage *demo = DEMO_IMAGE (widget);
+ GdkContentProvider *content = gdk_clipboard_get_content (clipboard);
+ GValue value = G_VALUE_INIT;
+ GdkPaintable *paintable;
+
+ g_value_init (&value, GDK_TYPE_PAINTABLE);
+ if (!gdk_content_provider_get_value (content, &value, NULL))
+ return;
+
+ paintable = GDK_PAINTABLE (g_value_get_object (&value));
+ gtk_image_set_from_paintable (GTK_IMAGE (demo->image), paintable);
+ g_value_unset (&value);
+}
+
+static void
+pressed_cb (GtkGesture *gesture,
+ int n_press,
+ double x,
+ double y,
+ gpointer data)
+{
+ DemoImage *demo = DEMO_IMAGE (gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture)));
+
+ gtk_popover_popup (GTK_POPOVER (demo->popover));
+}
+
+static void
+demo_image_init (DemoImage *demo)
+{
+ GMenu *menu;
+ GMenuItem *item;
+ GtkDragSource *source;
+ GtkDropTarget *dest;
+ GtkGesture *gesture;
+
+ demo->image = gtk_image_new ();
+ gtk_image_set_pixel_size (GTK_IMAGE (demo->image), 48);
+ gtk_widget_set_parent (demo->image, GTK_WIDGET (demo));
+
+ menu = g_menu_new ();
+ item = g_menu_item_new (_("_Copy"), "clipboard.copy");
+ g_menu_append_item (menu, item);
+
+ item = g_menu_item_new (_("_Paste"), "clipboard.paste");
+ g_menu_append_item (menu, item);
+
+ demo->popover = gtk_popover_menu_new_from_model (G_MENU_MODEL (menu));
+ gtk_widget_set_parent (demo->popover, GTK_WIDGET (demo));
+
+ source = gtk_drag_source_new ();
+ g_signal_connect (source, "prepare", G_CALLBACK (prepare_drag), NULL);
+ g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), NULL);
+ gtk_widget_add_controller (GTK_WIDGET (demo), GTK_EVENT_CONTROLLER (source));
+
+ dest = gtk_drop_target_new (GDK_TYPE_PAINTABLE, GDK_ACTION_COPY);
+ g_signal_connect (dest, "drop", G_CALLBACK (drag_drop), NULL);
+ gtk_widget_add_controller (GTK_WIDGET (demo), GTK_EVENT_CONTROLLER (dest));
+
+ gesture = gtk_gesture_click_new ();
+ gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
+ g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), NULL);
+ gtk_widget_add_controller (GTK_WIDGET (demo), GTK_EVENT_CONTROLLER (gesture));
+}
+
+static void
+demo_image_dispose (GObject *object)
+{
+ DemoImage *demo = DEMO_IMAGE (object);
+
+ g_clear_pointer (&demo->image, gtk_widget_unparent);
+ g_clear_pointer (&demo->popover, gtk_widget_unparent);
+
+ G_OBJECT_CLASS (demo_image_parent_class)->dispose (object);
+}
+
+static void
+demo_image_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ DemoImage *demo = DEMO_IMAGE (object);
+
+ switch (prop_id)
+ {
+ case PROP_ICON_NAME:
+ g_value_set_string (value, gtk_image_get_icon_name (GTK_IMAGE (demo->image)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+demo_image_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ DemoImage *demo = DEMO_IMAGE (object);
+
+ switch (prop_id)
+ {
+ case PROP_ICON_NAME:
+ gtk_image_set_from_icon_name (GTK_IMAGE (demo->image),
+ g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+demo_image_class_init (DemoImageClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+ object_class->dispose = demo_image_dispose;
+ object_class->get_property = demo_image_get_property;
+ object_class->set_property = demo_image_set_property;
+
+ g_object_class_install_property (object_class, PROP_ICON_NAME,
+ g_param_spec_string ("icon-name", "Icon name", "Icon name",
+ NULL, G_PARAM_READWRITE));
+
+ gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
+
+ gtk_widget_class_install_action (widget_class, "clipboard.copy", NULL, copy_image);
+ gtk_widget_class_install_action (widget_class, "clipboard.paste", NULL, paste_image);
+}
+
+GtkWidget *
+demo_image_new (const char *icon_name)
+{
+ return g_object_new (DEMO_TYPE_IMAGE, "icon-name", icon_name, NULL);
+}
diff --git a/demos/gtk-demo/demoimage.h b/demos/gtk-demo/demoimage.h
new file mode 100644
index 00000000000..bd8e160a731
--- /dev/null
+++ b/demos/gtk-demo/demoimage.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define DEMO_TYPE_IMAGE (demo_image_get_type ())
+
+G_DECLARE_FINAL_TYPE(DemoImage, demo_image, DEMO, IMAGE, GtkWidget)
+
+GtkWidget * demo_image_new (const char *icon_name);
+
+G_END_DECLS
diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build
index 8a4ad34d6e9..a2750049b73 100644
--- a/demos/gtk-demo/meson.build
+++ b/demos/gtk-demo/meson.build
@@ -90,6 +90,7 @@ extra_demo_sources = files(['main.c',
'gtkgears.c',
'puzzlepiece.c',
'bluroverlay.c',
+ 'demoimage.c',
'demotaggedentry.c'])
if harfbuzz_dep.found() and pangoft_dep.found()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]