colorswatch: Port to GtkDropTarget

This commit is contained in:
Matthias Clasen 2020-01-01 15:19:04 -05:00
parent 70cdd4e951
commit 025eee112c

View File

@ -67,6 +67,7 @@ typedef struct
GtkWidget *overlay_widget;
GtkWidget *popover;
GtkDropTarget *dest;
} GtkColorSwatchPrivate;
enum
@ -74,7 +75,8 @@ enum
PROP_ZERO,
PROP_RGBA,
PROP_SELECTABLE,
PROP_HAS_MENU
PROP_HAS_MENU,
PROP_CAN_DROP
};
G_DEFINE_TYPE_WITH_PRIVATE (GtkColorSwatch, gtk_color_swatch, GTK_TYPE_WIDGET)
@ -132,36 +134,39 @@ gtk_color_swatch_drag_begin (GtkDragSource *source,
}
static void
swatch_drag_data_received (GtkWidget *widget,
GdkDrop *drop,
GtkSelectionData *selection_data)
got_color (GObject *source,
GAsyncResult *result,
gpointer data)
{
gint length;
guint16 *vals;
GdkRGBA color;
GdkDrop *drop = GDK_DROP (source);
const GValue *value;
length = gtk_selection_data_get_length (selection_data);
if (length < 0)
return;
/* We accept drops with the wrong format, since the KDE color
* chooser incorrectly drops application/x-color with format 8.
*/
if (length != 8)
value = gdk_drop_read_value_finish (drop, result, NULL);
if (value)
{
g_warning ("Received invalid color data");
return;
GdkRGBA *color = g_value_get_boxed (value);
gtk_color_swatch_set_rgba (GTK_COLOR_SWATCH (data), color);
gdk_drop_finish (drop, GDK_ACTION_COPY);
}
else
gdk_drop_finish (drop, 0);
}
static gboolean
swatch_drag_drop (GtkDropTarget *dest,
int x,
int y,
GtkColorSwatch *swatch)
{
GdkDrop *drop = gtk_drop_target_get_drop (dest);
if (gdk_drop_has_value (drop, GDK_TYPE_RGBA))
{
gdk_drop_read_value_async (drop, GDK_TYPE_RGBA, G_PRIORITY_DEFAULT, NULL, got_color, swatch);
return TRUE;
}
vals = (guint16 *) gtk_selection_data_get_data (selection_data);
color.red = (gdouble)vals[0] / 0xffff;
color.green = (gdouble)vals[1] / 0xffff;
color.blue = (gdouble)vals[2] / 0xffff;
color.alpha = (gdouble)vals[3] / 0xffff;
gtk_color_swatch_set_rgba (GTK_COLOR_SWATCH (widget), &color);
return FALSE;
}
static void
@ -423,6 +428,9 @@ swatch_get_property (GObject *object,
case PROP_HAS_MENU:
g_value_set_boolean (value, priv->has_menu);
break;
case PROP_CAN_DROP:
g_value_set_boolean (value, priv->dest != NULL);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -449,6 +457,9 @@ swatch_set_property (GObject *object,
case PROP_HAS_MENU:
priv->has_menu = g_value_get_boolean (value);
break;
case PROP_CAN_DROP:
gtk_color_swatch_set_can_drop (swatch, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -463,7 +474,8 @@ swatch_finalize (GObject *object)
g_free (priv->icon);
gtk_widget_unparent (priv->overlay_widget);
g_clear_pointer (&priv->dest, gtk_drop_target_detach);
G_OBJECT_CLASS (gtk_color_swatch_parent_class)->finalize (object);
}
@ -491,7 +503,6 @@ gtk_color_swatch_class_init (GtkColorSwatchClass *class)
widget_class->measure = gtk_color_swatch_measure;
widget_class->snapshot = swatch_snapshot;
widget_class->drag_data_received = swatch_drag_data_received;
widget_class->popup_menu = swatch_popup_menu;
widget_class->size_allocate = swatch_size_allocate;
widget_class->state_flags_changed = swatch_state_flags_changed;
@ -505,6 +516,9 @@ gtk_color_swatch_class_init (GtkColorSwatchClass *class)
g_object_class_install_property (object_class, PROP_HAS_MENU,
g_param_spec_boolean ("has-menu", P_("Has Menu"), P_("Whether the swatch should offer customization"),
TRUE, GTK_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_CAN_DROP,
g_param_spec_boolean ("can-drop", P_("Can Drop"), P_("Whether the swatch should accept drops"),
FALSE, GTK_PARAM_READWRITE));
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_COLOR_SWATCH_ACCESSIBLE);
gtk_widget_class_set_css_name (widget_class, I_("colorswatch"));
@ -653,21 +667,27 @@ void
gtk_color_swatch_set_can_drop (GtkColorSwatch *swatch,
gboolean can_drop)
{
if (can_drop)
GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (swatch);
if (can_drop == (priv->dest != NULL))
return;
if (can_drop && !priv->dest)
{
GdkContentFormats *targets = gdk_content_formats_new (dnd_targets, G_N_ELEMENTS (dnd_targets));
gtk_drag_dest_set (GTK_WIDGET (swatch),
GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_DROP,
targets,
GDK_ACTION_COPY);
GdkContentFormats *targets;
targets = gdk_content_formats_new (dnd_targets, G_N_ELEMENTS (dnd_targets));
priv->dest = gtk_drop_target_new (GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT, targets, GDK_ACTION_COPY);
g_signal_connect (priv->dest, "drag-drop", G_CALLBACK (swatch_drag_drop), swatch);
gtk_drop_target_attach (priv->dest, GTK_WIDGET (swatch));
gdk_content_formats_unref (targets);
}
else
if (!can_drop && priv->dest)
{
gtk_drag_dest_unset (GTK_WIDGET (swatch));
g_clear_pointer (&priv->dest, gtk_drop_target_detach);
}
g_object_notify (G_OBJECT (swatch), "can-drop");
}
void