mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-09 18:30:08 +00:00
dnd: Remove gdk_content_provider_new_with_callback()
Content providers are meant to be immutable, apart from very special cases, but in those cases they need to emit gdk_content_provider_content_changed(). Having a constructor that just uses a get_func invites abuse of this by not making developers aware of those requirments. In fact, all users in GTK failed to do this. Instead, code should use the GtkDragSource::prepare signal to create content providers when needed. The same problem exists with gdk_content_provider_new_with_formats(), but this commit doesn't touch that.
This commit is contained in:
parent
dbad440468
commit
da83457a60
@ -138,23 +138,18 @@ drag_begin (GtkDragSource *source,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_texture (GValue *value,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (data));
|
||||
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
g_value_set_object (value, paintable);
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
prepare_drag (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *image)
|
||||
{
|
||||
return gdk_content_provider_new_with_callback (GDK_TYPE_TEXTURE, get_texture, image, NULL);
|
||||
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 void
|
||||
|
@ -406,47 +406,53 @@ drag_begin (GtkDragSource *source,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_texture (GValue *value,
|
||||
gpointer data)
|
||||
static GdkContentProvider *
|
||||
drag_prepare_texture (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (data));
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
g_value_set_object (value, paintable);
|
||||
if (!GDK_IS_TEXTURE (paintable))
|
||||
return NULL;
|
||||
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, paintable);
|
||||
}
|
||||
|
||||
static void
|
||||
get_file (GValue *value,
|
||||
gpointer data)
|
||||
static GdkContentProvider *
|
||||
drag_prepare_file (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GdkContentProvider *content;
|
||||
GtkIconTheme *icon_theme;
|
||||
const char *name;
|
||||
GtkIconPaintable *info;
|
||||
|
||||
name = gtk_image_get_icon_name (GTK_IMAGE (data));
|
||||
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (GTK_WIDGET (data)));
|
||||
name = gtk_image_get_icon_name (GTK_IMAGE (widget));
|
||||
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
|
||||
|
||||
info = gtk_icon_theme_lookup_icon (icon_theme,
|
||||
name,
|
||||
NULL,
|
||||
32, 1,
|
||||
gtk_widget_get_direction (GTK_WIDGET (data)),
|
||||
gtk_widget_get_direction (widget),
|
||||
0);
|
||||
g_value_take_object (value, gtk_icon_paintable_get_file (info));
|
||||
content = gdk_content_provider_new_typed (G_TYPE_FILE, gtk_icon_paintable_get_file (info));
|
||||
g_object_unref (info);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_image_dnd (GtkWidget *image)
|
||||
{
|
||||
GdkContentProvider *content;
|
||||
GtkDragSource *source;
|
||||
|
||||
source = gtk_drag_source_new ();
|
||||
content = gdk_content_provider_new_with_callback (GDK_TYPE_TEXTURE, get_texture, image, NULL);
|
||||
gtk_drag_source_set_content (source, content);
|
||||
g_object_unref (content);
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (drag_prepare_texture), image);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
}
|
||||
@ -454,14 +460,10 @@ setup_image_dnd (GtkWidget *image)
|
||||
static void
|
||||
setup_scalable_image_dnd (GtkWidget *image)
|
||||
{
|
||||
GdkContentProvider *content;
|
||||
GtkDragSource *source;
|
||||
|
||||
source = gtk_drag_source_new ();
|
||||
content = gdk_content_provider_new_with_callback (G_TYPE_FILE, get_file, image, NULL);
|
||||
gtk_drag_source_set_content (source, content);
|
||||
g_object_unref (content);
|
||||
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (drag_prepare_file), image);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
}
|
||||
|
@ -322,118 +322,6 @@ gdk_content_provider_new_for_bytes (const char *mime_type,
|
||||
return GDK_CONTENT_PROVIDER (content);
|
||||
}
|
||||
|
||||
#define GDK_TYPE_CONTENT_PROVIDER_CALLBACK (gdk_content_provider_callback_get_type ())
|
||||
#define GDK_CONTENT_PROVIDER_CALLBACK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CONTENT_PROVIDER_CALLBACK, GdkContentProviderCallback))
|
||||
|
||||
typedef struct _GdkContentProviderCallback GdkContentProviderCallback;
|
||||
typedef struct _GdkContentProviderCallbackClass GdkContentProviderCallbackClass;
|
||||
|
||||
struct _GdkContentProviderCallback
|
||||
{
|
||||
GdkContentProvider parent;
|
||||
|
||||
GType type;
|
||||
GdkContentProviderGetValueFunc func;
|
||||
gpointer data;
|
||||
GDestroyNotify notify;
|
||||
};
|
||||
|
||||
struct _GdkContentProviderCallbackClass
|
||||
{
|
||||
GdkContentProviderClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_content_provider_callback_get_type (void) G_GNUC_CONST;
|
||||
|
||||
G_DEFINE_TYPE (GdkContentProviderCallback, gdk_content_provider_callback, GDK_TYPE_CONTENT_PROVIDER)
|
||||
|
||||
static GdkContentFormats *
|
||||
gdk_content_provider_callback_ref_formats (GdkContentProvider *provider)
|
||||
{
|
||||
GdkContentProviderCallback *callback = GDK_CONTENT_PROVIDER_CALLBACK (provider);
|
||||
|
||||
return gdk_content_formats_new_for_gtype (callback->type);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_content_provider_callback_get_value (GdkContentProvider *provider,
|
||||
GValue *value,
|
||||
GError **error)
|
||||
{
|
||||
GdkContentProviderCallback *callback = GDK_CONTENT_PROVIDER_CALLBACK (provider);
|
||||
|
||||
if (G_VALUE_HOLDS (value, callback->type) && callback->func != NULL)
|
||||
{
|
||||
callback->func (value, callback->data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return GDK_CONTENT_PROVIDER_CLASS (gdk_content_provider_callback_parent_class)->get_value (provider, value, error);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_content_provider_callback_dispose (GObject *gobject)
|
||||
{
|
||||
GdkContentProviderCallback *self = GDK_CONTENT_PROVIDER_CALLBACK (gobject);
|
||||
|
||||
if (self->notify != NULL)
|
||||
self->notify (self->data);
|
||||
|
||||
self->func = NULL;
|
||||
self->data = NULL;
|
||||
self->notify = NULL;
|
||||
|
||||
G_OBJECT_CLASS (gdk_content_provider_callback_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_content_provider_callback_class_init (GdkContentProviderCallbackClass *class)
|
||||
{
|
||||
GdkContentProviderClass *provider_class = GDK_CONTENT_PROVIDER_CLASS (class);
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
|
||||
|
||||
gobject_class->dispose = gdk_content_provider_callback_dispose;
|
||||
|
||||
provider_class->ref_formats = gdk_content_provider_callback_ref_formats;
|
||||
provider_class->get_value = gdk_content_provider_callback_get_value;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_content_provider_callback_init (GdkContentProviderCallback *content)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_content_provider_new_for_callback: (constructor)
|
||||
* @type: the type that the callback provides
|
||||
* @func: (not nullable): callback to populate a #GValue
|
||||
* @data: (closure): data that gets passed to @func
|
||||
* @notify: a function to be called to free @data when the content provider
|
||||
* goes away
|
||||
*
|
||||
* Create a content provider that provides data that is provided via a callback.
|
||||
*
|
||||
* Returns: a new #GdkContentProvider
|
||||
**/
|
||||
GdkContentProvider *
|
||||
gdk_content_provider_new_with_callback (GType type,
|
||||
GdkContentProviderGetValueFunc func,
|
||||
gpointer data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
GdkContentProviderCallback *content;
|
||||
|
||||
g_return_val_if_fail (func != NULL, NULL);
|
||||
|
||||
content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_CALLBACK, NULL);
|
||||
content->type = type;
|
||||
content->func = func;
|
||||
content->data = data;
|
||||
content->notify = notify;
|
||||
|
||||
return GDK_CONTENT_PROVIDER (content);
|
||||
}
|
||||
|
||||
#define GDK_TYPE_CONTENT_PROVIDER_CALLBACK2 (gdk_content_provider_callback2_get_type ())
|
||||
#define GDK_CONTENT_PROVIDER_CALLBACK2(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CONTENT_PROVIDER_CALLBACK2, GdkContentProviderCallback2))
|
||||
|
||||
|
@ -38,15 +38,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
GdkContentProvider * gdk_content_provider_new_for_bytes (const char *mime_type,
|
||||
GBytes *bytes);
|
||||
|
||||
typedef void (*GdkContentProviderGetValueFunc) (GValue *value,
|
||||
gpointer data);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkContentProvider * gdk_content_provider_new_with_callback (GType type,
|
||||
GdkContentProviderGetValueFunc func,
|
||||
gpointer data,
|
||||
GDestroyNotify notify);
|
||||
|
||||
typedef GBytes * (*GdkContentProviderGetBytesFunc) (const char *mime_type,
|
||||
gpointer data);
|
||||
|
||||
|
@ -285,12 +285,15 @@ gtk_color_button_drag_begin (GtkDragSource *source,
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
|
||||
static void
|
||||
get_rgba_value (GValue *value,
|
||||
gpointer data)
|
||||
static GdkContentProvider *
|
||||
gtk_color_button_drag_prepare (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
GtkColorButton *button)
|
||||
{
|
||||
GtkColorButtonPrivate *priv = gtk_color_button_get_instance_private (GTK_COLOR_BUTTON (data));
|
||||
g_value_set_boxed (value, &priv->rgba);
|
||||
GtkColorButtonPrivate *priv = gtk_color_button_get_instance_private (button);
|
||||
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_RGBA, &priv->rgba);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -300,7 +303,6 @@ gtk_color_button_init (GtkColorButton *button)
|
||||
PangoLayout *layout;
|
||||
PangoRectangle rect;
|
||||
GdkContentFormats *targets;
|
||||
GdkContentProvider *content;
|
||||
GtkDragSource *source;
|
||||
GtkDropTarget *dest;
|
||||
|
||||
@ -333,9 +335,7 @@ gtk_color_button_init (GtkColorButton *button)
|
||||
gdk_content_formats_unref (targets);
|
||||
|
||||
source = gtk_drag_source_new ();
|
||||
content = gdk_content_provider_new_with_callback (GDK_TYPE_RGBA, get_rgba_value, button, NULL);
|
||||
gtk_drag_source_set_content (source, content);
|
||||
g_object_unref (content);
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (gtk_color_button_drag_prepare), button);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (gtk_color_button_drag_begin), button);
|
||||
gtk_widget_add_controller (priv->button, GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
|
@ -578,12 +578,15 @@ static const char *dnd_targets[] = {
|
||||
"application/x-color"
|
||||
};
|
||||
|
||||
static void
|
||||
get_rgba_value (GValue *value,
|
||||
gpointer data)
|
||||
static GdkContentProvider *
|
||||
gtk_color_swatch_drag_prepare (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
GtkColorSwatch *swatch)
|
||||
{
|
||||
GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (GTK_COLOR_SWATCH (data));
|
||||
g_value_set_boxed (value, &priv->color);
|
||||
GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (swatch);
|
||||
|
||||
return gdk_content_provider_new_typed (GDK_TYPE_RGBA, &priv->color);
|
||||
}
|
||||
|
||||
void
|
||||
@ -594,13 +597,10 @@ gtk_color_swatch_set_rgba (GtkColorSwatch *swatch,
|
||||
|
||||
if (!priv->has_color)
|
||||
{
|
||||
GdkContentProvider *content;
|
||||
GtkDragSource *source;
|
||||
|
||||
source = gtk_drag_source_new ();
|
||||
content = gdk_content_provider_new_with_callback (GDK_TYPE_RGBA, get_rgba_value, swatch, NULL);
|
||||
gtk_drag_source_set_content (source, content);
|
||||
g_object_unref (content);
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (gtk_color_swatch_drag_prepare), swatch);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (gtk_color_swatch_drag_begin), swatch);
|
||||
|
||||
gtk_widget_add_controller (GTK_WIDGET (swatch), GTK_EVENT_CONTROLLER (source));
|
||||
|
Loading…
Reference in New Issue
Block a user