diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml
index 2998560b02..295c056f0b 100644
--- a/demos/gtk-demo/demo.gresource.xml
+++ b/demos/gtk-demo/demo.gresource.xml
@@ -454,6 +454,9 @@
icons/16x16/categories/applications-other.png
icons/48x48/status/starred.png
data/scalable/apps/org.gtk.Demo4.svg
+ portland-rose-thumbnail.png
+ large-image-thumbnail.png
+ large-image.png
help-overlay.ui
diff --git a/demos/gtk-demo/image_scaling.c b/demos/gtk-demo/image_scaling.c
index 65c344f8bf..7a541292b9 100644
--- a/demos/gtk-demo/image_scaling.c
+++ b/demos/gtk-demo/image_scaling.c
@@ -14,6 +14,103 @@
#include
#include "demo3widget.h"
+static GtkWidget *window = NULL;
+static GCancellable *cancellable = NULL;
+
+static void
+load_texture (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cable)
+{
+ GFile *file = task_data;
+ GdkTexture *texture;
+ GError *error = NULL;
+
+ texture = gdk_texture_new_from_file (file, &error);
+
+ if (texture)
+ g_task_return_pointer (task, texture, g_object_unref);
+ else
+ g_task_return_error (task, error);
+}
+
+static void
+set_wait_cursor (GtkWidget *widget)
+{
+ gtk_widget_set_cursor_from_name (GTK_WIDGET (gtk_widget_get_root (widget)), "wait");
+}
+
+static void
+unset_wait_cursor (GtkWidget *widget)
+{
+ gtk_widget_set_cursor (GTK_WIDGET (gtk_widget_get_root (widget)), NULL);
+}
+
+static void
+texture_loaded (GObject *source,
+ GAsyncResult *result,
+ gpointer data)
+{
+ GdkTexture *texture;
+ GError *error = NULL;
+
+ texture = g_task_propagate_pointer (G_TASK (result), &error);
+
+ if (!texture)
+ {
+ g_print ("%s\n", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (!window)
+ {
+ g_object_unref (texture);
+ return;
+ }
+
+ unset_wait_cursor (GTK_WIDGET (data));
+
+ g_object_set (G_OBJECT (data), "texture", texture, NULL);
+}
+
+static void
+open_file_async (GFile *file,
+ GtkWidget *demo)
+{
+ GTask *task;
+
+ set_wait_cursor (demo);
+
+ task = g_task_new (demo, cancellable, texture_loaded, demo);
+ g_task_set_task_data (task, g_object_ref (file), g_object_unref);
+ g_task_run_in_thread (task, load_texture);
+ g_object_unref (task);
+}
+
+static void
+open_portland_rose (GtkWidget *button,
+ GtkWidget *demo)
+{
+ GFile *file;
+
+ file = g_file_new_for_uri ("resource:///transparent/portland-rose.jpg");
+ open_file_async (file, demo);
+ g_object_unref (file);
+}
+
+static void
+open_large_image (GtkWidget *button,
+ GtkWidget *demo)
+{
+ GFile *file;
+
+ file = g_file_new_for_uri ("resource:///org/gtk/Demo4/large-image.png");
+ open_file_async (file, demo);
+ g_object_unref (file);
+}
+
static void
file_opened (GObject *source,
GAsyncResult *result,
@@ -21,7 +118,6 @@ file_opened (GObject *source,
{
GFile *file;
GError *error = NULL;
- GdkTexture *texture;
file = gtk_file_dialog_open_finish (GTK_FILE_DIALOG (source), result, &error);
@@ -32,17 +128,9 @@ file_opened (GObject *source,
return;
}
- texture = gdk_texture_new_from_file (file, &error);
- g_object_unref (file);
- if (!texture)
- {
- g_print ("%s\n", error->message);
- g_error_free (error);
- return;
- }
+ open_file_async (file, data);
- g_object_set (G_OBJECT (data), "texture", texture, NULL);
- g_object_unref (texture);
+ g_object_unref (file);
}
static void
@@ -116,11 +204,26 @@ transform_from (GBinding *binding,
return TRUE;
}
+static void
+free_cancellable (gpointer data)
+{
+ g_cancellable_cancel (cancellable);
+ g_clear_object (&cancellable);
+}
+
+static gboolean
+cancel_load (GtkWidget *widget,
+ GVariant *args,
+ gpointer data)
+{
+ unset_wait_cursor (widget);
+ g_cancellable_cancel (G_CANCELLABLE (data));
+ return TRUE;
+}
+
GtkWidget *
do_image_scaling (GtkWidget *do_widget)
{
- static GtkWidget *window = NULL;
-
if (!window)
{
GtkWidget *box;
@@ -130,6 +233,7 @@ do_image_scaling (GtkWidget *do_widget)
GtkWidget *scale;
GtkWidget *dropdown;
GtkWidget *button;
+ GtkEventController *controller;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Image Scaling");
@@ -138,6 +242,20 @@ do_image_scaling (GtkWidget *do_widget)
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
+ cancellable = g_cancellable_new ();
+ g_object_set_data_full (G_OBJECT (window), "cancellable",
+ cancellable, free_cancellable);
+
+ controller = gtk_shortcut_controller_new ();
+ gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller),
+ gtk_shortcut_new (
+ gtk_keyval_trigger_new (GDK_KEY_Escape, 0),
+ gtk_callback_action_new (cancel_load, cancellable, NULL)
+ ));
+ gtk_shortcut_controller_set_scope (GTK_SHORTCUT_CONTROLLER (controller),
+ GTK_SHORTCUT_SCOPE_GLOBAL);
+ gtk_widget_add_controller (window, controller);
+
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_window_set_child (GTK_WINDOW (window), box);
@@ -156,6 +274,22 @@ do_image_scaling (GtkWidget *do_widget)
g_signal_connect (button, "clicked", G_CALLBACK (open_file), widget);
gtk_box_append (GTK_BOX (box2), button);
+ button = gtk_button_new ();
+ gtk_button_set_child (GTK_BUTTON (button),
+ gtk_image_new_from_resource ("/org/gtk/Demo4/portland-rose-thumbnail.png"));
+ gtk_widget_add_css_class (button, "image-button");
+ gtk_widget_set_tooltip_text (button, "Portland Rose");
+ g_signal_connect (button, "clicked", G_CALLBACK (open_portland_rose), widget);
+ gtk_box_append (GTK_BOX (box2), button);
+
+ button = gtk_button_new ();
+ gtk_button_set_child (GTK_BUTTON (button),
+ gtk_image_new_from_resource ("/org/gtk/Demo4/large-image-thumbnail.png"));
+ gtk_widget_add_css_class (button, "image-button");
+ gtk_widget_set_tooltip_text (button, "Large image");
+ g_signal_connect (button, "clicked", G_CALLBACK (open_large_image), widget);
+ gtk_box_append (GTK_BOX (box2), button);
+
button = gtk_button_new_from_icon_name ("object-rotate-right-symbolic");
gtk_widget_set_tooltip_text (button, "Rotate");
g_signal_connect (button, "clicked", G_CALLBACK (rotate), widget);
@@ -191,7 +325,9 @@ do_image_scaling (GtkWidget *do_widget)
if (!gtk_widget_get_visible (window))
gtk_widget_set_visible (window, TRUE);
else
- gtk_window_destroy (GTK_WINDOW (window));
+ {
+ gtk_window_destroy (GTK_WINDOW (window));
+ }
return window;
}
diff --git a/demos/gtk-demo/large-image-thumbnail.png b/demos/gtk-demo/large-image-thumbnail.png
new file mode 100644
index 0000000000..d383d8bbf4
Binary files /dev/null and b/demos/gtk-demo/large-image-thumbnail.png differ
diff --git a/demos/gtk-demo/large-image.png b/demos/gtk-demo/large-image.png
new file mode 100644
index 0000000000..0ddeaef501
Binary files /dev/null and b/demos/gtk-demo/large-image.png differ
diff --git a/demos/gtk-demo/portland-rose-thumbnail.png b/demos/gtk-demo/portland-rose-thumbnail.png
new file mode 100644
index 0000000000..d3838ddb17
Binary files /dev/null and b/demos/gtk-demo/portland-rose-thumbnail.png differ