wip: Add a drag surface resize demo

Make the one of the image sources in the clipboard
demo have a throbbing drag icon.
This commit is contained in:
Matthias Clasen
2023-03-06 20:59:14 -05:00
parent eb828a5d76
commit e5e08cc0d7
5 changed files with 234 additions and 0 deletions

View File

@@ -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);

View File

@@ -91,6 +91,7 @@
<child>
<object class="GtkDragSource">
<signal name="prepare" handler="drag_prepare"/>
<signal name="drag-begin" handler="drag_begin"/>
</object>
</child>
<child>

View File

@@ -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);
}

View File

@@ -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

View File

@@ -134,6 +134,7 @@ extra_demo_sources = files([
'unicode-names.c',
'suggestionentry.c',
'language-names.c',
'gtkthrobber.c',
])
if os_unix