summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2023-03-06 20:59:14 -0500
committerMatthias Clasen <mclasen@redhat.com>2023-03-07 07:21:32 -0500
commite5e08cc0d77c298bcc0af2ec2f91b1c46c5aeca6 (patch)
tree25ffea67d11b9cd4cad988e012ea9def0b28baff
parenteb828a5d7627d9d4d702ff86fd7a8fa127a3962d (diff)
downloadgtk+-e5e08cc0d77c298bcc0af2ec2f91b1c46c5aeca6.tar.gz
wip: Add a drag surface resize demo
Make the one of the image sources in the clipboard demo have a throbbing drag icon.
-rw-r--r--demos/gtk-demo/clipboard.c22
-rw-r--r--demos/gtk-demo/clipboard.ui1
-rw-r--r--demos/gtk-demo/gtkthrobber.c174
-rw-r--r--demos/gtk-demo/gtkthrobber.h36
-rw-r--r--demos/gtk-demo/meson.build1
5 files changed, 234 insertions, 0 deletions
diff --git a/demos/gtk-demo/clipboard.c b/demos/gtk-demo/clipboard.c
index 672a51ac44..07466069ec 100644
--- a/demos/gtk-demo/clipboard.c
+++ b/demos/gtk-demo/clipboard.c
@@ -12,6 +12,7 @@
#include <gtk/gtk.h>
#include <string.h>
#include "demoimage.h"
+#include "gtkthrobber.h"
static void
copy_button_clicked (GtkStack *source_stack,
@@ -364,6 +365,26 @@ drag_prepare (GtkDragSource *drag_source,
return gdk_content_provider_new_for_value (&value);
}
+static void
+drag_begin (GtkDragSource *drag_source,
+ GdkDrag *drag,
+ gpointer user_data)
+{
+ GtkWidget *button;
+ GdkFrameClock *clock;
+ GdkPaintable *paintable;
+
+ button = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (drag_source));
+ clock = gtk_widget_get_frame_clock (button);
+ paintable = gtk_throbber_new (clock,
+ "/transparent/portland-rose.jpg",
+ 0.02, 0.1,
+ drag);
+
+ gtk_drag_source_set_icon (drag_source, paintable, 10, 10);
+ g_object_unref (paintable);
+}
+
GtkWidget *
do_clipboard (GtkWidget *do_widget)
{
@@ -384,6 +405,7 @@ do_clipboard (GtkWidget *do_widget)
gtk_builder_cscope_add_callback (scope, open_folder_cb);
gtk_builder_cscope_add_callback (scope, on_drop);
gtk_builder_cscope_add_callback (scope, drag_prepare);
+ gtk_builder_cscope_add_callback (scope, drag_begin);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
gtk_builder_add_from_resource (builder, "/clipboard/clipboard.ui", NULL);
diff --git a/demos/gtk-demo/clipboard.ui b/demos/gtk-demo/clipboard.ui
index a373537f6b..6f4cf287a9 100644
--- a/demos/gtk-demo/clipboard.ui
+++ b/demos/gtk-demo/clipboard.ui
@@ -91,6 +91,7 @@
<child>
<object class="GtkDragSource">
<signal name="prepare" handler="drag_prepare"/>
+ <signal name="drag-begin" handler="drag_begin"/>
</object>
</child>
<child>
diff --git a/demos/gtk-demo/gtkthrobber.c b/demos/gtk-demo/gtkthrobber.c
new file mode 100644
index 0000000000..c12df51b62
--- /dev/null
+++ b/demos/gtk-demo/gtkthrobber.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright © 2018 Benjamin Otte
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#include "gtkthrobber.h"
+
+#include "gtk.h"
+
+struct _GtkThrobber
+{
+ GObject parent_instance;
+
+ GdkFrameClock *clock;
+ GdkTexture *texture;
+ guint clock_tick_id;
+
+ float min, max, scale, delta;
+ float delta2, hot;
+
+ GdkDrag *drag;
+};
+
+struct _GtkThrobberClass
+{
+ GObjectClass parent_class;
+};
+
+static void
+gtk_throbber_paintable_snapshot (GdkPaintable *paintable,
+ GdkSnapshot *snapshot,
+ double width,
+ double height)
+{
+ GtkThrobber *self = GTK_THROBBER (paintable);
+
+ gtk_snapshot_append_texture (snapshot, self->texture, &GRAPHENE_RECT_INIT (0, 0, width, height));
+}
+
+static int
+gtk_throbber_paintable_get_intrinsic_width (GdkPaintable *paintable)
+{
+ GtkThrobber *self = GTK_THROBBER (paintable);
+
+ return gdk_texture_get_width (self->texture) * self->scale;
+}
+
+static int
+gtk_throbber_paintable_get_intrinsic_height (GdkPaintable *paintable)
+{
+ GtkThrobber *self = GTK_THROBBER (paintable);
+
+ return gdk_texture_get_height (self->texture) * self->scale;
+}
+
+static void
+gtk_throbber_paintable_init (GdkPaintableInterface *iface)
+{
+ iface->snapshot = gtk_throbber_paintable_snapshot;
+ iface->get_intrinsic_width = gtk_throbber_paintable_get_intrinsic_width;
+ iface->get_intrinsic_height = gtk_throbber_paintable_get_intrinsic_height;
+}
+
+G_DEFINE_TYPE_EXTENDED (GtkThrobber, gtk_throbber, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
+ gtk_throbber_paintable_init))
+
+static void
+gtk_throbber_dispose (GObject *object)
+{
+ GtkThrobber *self = GTK_THROBBER (object);
+
+ gdk_frame_clock_end_updating (self->clock);
+ g_signal_handler_disconnect (self->clock, self->clock_tick_id);
+ self->clock_tick_id = 0;
+
+ g_clear_object (&self->clock);
+ g_clear_object (&self->texture);
+ g_clear_object (&self->drag);
+
+ G_OBJECT_CLASS (gtk_throbber_parent_class)->dispose (object);
+}
+
+static void
+gtk_throbber_class_init (GtkThrobberClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->dispose = gtk_throbber_dispose;
+}
+
+static void
+gtk_throbber_init (GtkThrobber *self)
+{
+}
+
+static void
+on_frame_clock_update (GdkFrameClock *clock,
+ GtkThrobber *self)
+{
+ self->scale += self->delta;
+ if (self->scale >= self->max)
+ {
+ self->scale = self->max;
+ self->delta = - self->delta;
+ }
+ else if (self->scale <= self->min)
+ {
+ self->scale = self->min;
+ self->delta = - self->delta;
+ }
+
+ self->hot += self->delta2;
+ if (self->hot >= 1.)
+ {
+ self->hot = 1.;
+ self->delta2 = - self->delta2;
+ }
+ else if (self->hot <= 0.)
+ {
+ self->hot = 0.;
+ self->delta2 = - self->delta2;
+ }
+
+ gdk_paintable_invalidate_size (GDK_PAINTABLE (self));
+
+ gdk_drag_set_hotspot (self->drag,
+ gdk_texture_get_width (self->texture) * self->scale * self->hot,
+ gdk_texture_get_height (self->texture) * self->scale * self->hot);
+}
+
+
+GdkPaintable *
+gtk_throbber_new (GdkFrameClock *clock,
+ const char *resource_path,
+ float min,
+ float max,
+ GdkDrag *drag)
+{
+ GtkThrobber *self;
+
+ self = g_object_new (GTK_TYPE_THROBBER, NULL);
+
+ self->clock = g_object_ref (clock);
+ self->texture = gdk_texture_new_from_resource (resource_path);
+ self->drag = g_object_ref (drag);
+ self->min = min;
+ self->max = max;
+ self->scale = min;
+ self->delta = (max - min) / (15 * 16);
+ self->delta2 = 1. / (10 * 16);
+ self->hot = 0.;
+
+ self->clock_tick_id = g_signal_connect (self->clock, "update",
+ G_CALLBACK (on_frame_clock_update), self);
+
+ gdk_frame_clock_begin_updating (self->clock);
+
+ return GDK_PAINTABLE (self);
+}
diff --git a/demos/gtk-demo/gtkthrobber.h b/demos/gtk-demo/gtkthrobber.h
new file mode 100644
index 0000000000..6011c63742
--- /dev/null
+++ b/demos/gtk-demo/gtkthrobber.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2023 Matthias Clasen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte@gnome.org>
+ */
+
+#pragma once
+
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_THROBBER (gtk_throbber_get_type ())
+
+G_DECLARE_FINAL_TYPE (GtkThrobber, gtk_throbber, GTK, THROBBER, GObject)
+
+GdkPaintable * gtk_throbber_new (GdkFrameClock *clock,
+ const char *resource_path,
+ float min,
+ float max,
+ GdkDrag *drag);
+
+G_END_DECLS
diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build
index b1c21a9f9b..a0be24e73c 100644
--- a/demos/gtk-demo/meson.build
+++ b/demos/gtk-demo/meson.build
@@ -134,6 +134,7 @@ extra_demo_sources = files([
'unicode-names.c',
'suggestionentry.c',
'language-names.c',
+ 'gtkthrobber.c',
])
if os_unix