Add a dnd testcase
This has tests for drag images, widgets, hotspots.
This commit is contained in:
@ -62,6 +62,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
|
||||
testcellrenderertext \
|
||||
testdialog \
|
||||
testdnd \
|
||||
testdnd2 \
|
||||
testellipsise \
|
||||
testemblems \
|
||||
testentrycompletion \
|
||||
@ -217,6 +218,7 @@ testcombo_DEPENDENCIES = $(TEST_DEPS)
|
||||
testcombochange_DEPENDENCIES = $(TEST_DEPS)
|
||||
testcellrenderertext_DEPENDENCIES = $(TEST_DEPS)
|
||||
testdnd_DEPENDENCIES = $(TEST_DEPS)
|
||||
testdnd2_DEPENDENCIES = $(TEST_DEPS)
|
||||
testellipsise_DEPENDENCIES = $(TEST_DEPS)
|
||||
testentrycompletion_DEPENDENCIES = $(TEST_DEPS)
|
||||
testentryicons_DEPENDENCIES = $(TEST_DEPS)
|
||||
|
||||
268
tests/testdnd2.c
Normal file
268
tests/testdnd2.c
Normal file
@ -0,0 +1,268 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GdkPixbuf *
|
||||
get_image_pixbuf (GtkImage *image)
|
||||
{
|
||||
const gchar *icon_name;
|
||||
GtkIconSize size;
|
||||
GtkIconTheme *icon_theme;
|
||||
int width;
|
||||
|
||||
switch (gtk_image_get_storage_type (image))
|
||||
{
|
||||
case GTK_IMAGE_PIXBUF:
|
||||
return g_object_ref (gtk_image_get_pixbuf (image));
|
||||
case GTK_IMAGE_ICON_NAME:
|
||||
gtk_image_get_icon_name (image, &icon_name, &size);
|
||||
icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (image)));
|
||||
gtk_icon_size_lookup (size, &width, NULL);
|
||||
return gtk_icon_theme_load_icon (icon_theme,
|
||||
icon_name,
|
||||
width,
|
||||
GTK_ICON_LOOKUP_GENERIC_FALLBACK,
|
||||
NULL);
|
||||
default:
|
||||
g_warning ("Image storage type %d not handled",
|
||||
gtk_image_get_storage_type (image));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
TARGET_IMAGE,
|
||||
TARGET_TEXT
|
||||
};
|
||||
|
||||
enum {
|
||||
TOP_LEFT,
|
||||
CENTER,
|
||||
BOTTOM_RIGHT
|
||||
};
|
||||
|
||||
static void
|
||||
image_drag_begin (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
gint hotspot;
|
||||
gint hot_x, hot_y;
|
||||
|
||||
pixbuf = get_image_pixbuf (GTK_IMAGE (data));
|
||||
hotspot = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (data), "hotspot"));
|
||||
switch (hotspot)
|
||||
{
|
||||
default:
|
||||
case TOP_LEFT:
|
||||
hot_x = 0;
|
||||
hot_y = 0;
|
||||
break;
|
||||
case CENTER:
|
||||
hot_x = gdk_pixbuf_get_width (pixbuf) / 2;
|
||||
hot_y = gdk_pixbuf_get_height (pixbuf) / 2;
|
||||
break;
|
||||
case BOTTOM_RIGHT:
|
||||
hot_x = gdk_pixbuf_get_width (pixbuf);
|
||||
hot_y = gdk_pixbuf_get_height (pixbuf);
|
||||
break;
|
||||
}
|
||||
gtk_drag_set_icon_pixbuf (context, pixbuf, hot_x, hot_y);
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
update_source_target_list (GtkWidget *ebox, GtkWidget *image)
|
||||
{
|
||||
GtkTargetList *target_list;
|
||||
|
||||
target_list = gtk_target_list_new (NULL, 0);
|
||||
|
||||
gtk_target_list_add_image_targets (target_list, TARGET_IMAGE, FALSE);
|
||||
if (gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_ICON_NAME)
|
||||
gtk_target_list_add_text_targets (target_list, TARGET_TEXT);
|
||||
|
||||
gtk_drag_source_set_target_list (ebox, target_list);
|
||||
|
||||
gtk_target_list_unref (target_list);
|
||||
}
|
||||
|
||||
static void
|
||||
update_dest_target_list (GtkWidget *ebox)
|
||||
{
|
||||
GtkTargetList *target_list;
|
||||
|
||||
target_list = gtk_target_list_new (NULL, 0);
|
||||
|
||||
gtk_target_list_add_image_targets (target_list, TARGET_IMAGE, FALSE);
|
||||
gtk_target_list_add_text_targets (target_list, TARGET_TEXT);
|
||||
|
||||
gtk_drag_dest_set_target_list (ebox, target_list);
|
||||
|
||||
gtk_target_list_unref (target_list);
|
||||
}
|
||||
|
||||
void
|
||||
image_drag_data_get (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
const gchar *name;
|
||||
|
||||
switch (info)
|
||||
{
|
||||
case TARGET_IMAGE:
|
||||
pixbuf = get_image_pixbuf (GTK_IMAGE (data));
|
||||
gtk_selection_data_set_pixbuf (selection_data, pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
break;
|
||||
case TARGET_TEXT:
|
||||
gtk_image_get_icon_name (GTK_IMAGE (data), &name, NULL);
|
||||
gtk_selection_data_set_text (selection_data, name, -1);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
image_drag_data_received (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x,
|
||||
gint y,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint32 time,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
gchar *text;
|
||||
|
||||
if (gtk_selection_data_get_length (selection_data) == 0)
|
||||
return;
|
||||
|
||||
switch (info)
|
||||
{
|
||||
case TARGET_IMAGE:
|
||||
pixbuf = gtk_selection_data_get_pixbuf (selection_data);
|
||||
gtk_image_set_from_pixbuf (GTK_IMAGE (data), pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
break;
|
||||
case TARGET_TEXT:
|
||||
text = (gchar *)gtk_selection_data_get_text (selection_data);
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (data), text, GTK_ICON_SIZE_DIALOG);
|
||||
g_free (text);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GtkWidget *
|
||||
make_image (const gchar *icon_name, int hotspot)
|
||||
{
|
||||
GtkWidget *image, *ebox;
|
||||
|
||||
image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_DIALOG);
|
||||
ebox = gtk_event_box_new ();
|
||||
|
||||
gtk_drag_source_set (ebox, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
|
||||
update_source_target_list (ebox, image);
|
||||
|
||||
g_object_set_data (G_OBJECT (image), "hotspot", GINT_TO_POINTER (hotspot));
|
||||
|
||||
g_signal_connect (ebox, "drag-begin", G_CALLBACK (image_drag_begin), image);
|
||||
g_signal_connect (ebox, "drag-data-get", G_CALLBACK (image_drag_data_get), image);
|
||||
|
||||
gtk_drag_dest_set (ebox, GTK_DEST_DEFAULT_ALL, NULL, 0, GDK_ACTION_COPY);
|
||||
g_signal_connect (ebox, "drag-data-received", G_CALLBACK (image_drag_data_received), image);
|
||||
update_dest_target_list (ebox);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (ebox), image);
|
||||
|
||||
return ebox;
|
||||
}
|
||||
|
||||
static void
|
||||
spinner_drag_begin (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWidget *spinner;
|
||||
|
||||
spinner = g_object_new (GTK_TYPE_SPINNER,
|
||||
"visible", TRUE,
|
||||
"active", TRUE,
|
||||
NULL);
|
||||
gtk_drag_set_icon_widget (context, spinner, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
spinner_drag_data_get (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time,
|
||||
gpointer data)
|
||||
{
|
||||
gtk_selection_data_set_text (selection_data, "ACTIVE", -1);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
make_spinner (void)
|
||||
{
|
||||
GtkWidget *spinner, *ebox;
|
||||
|
||||
spinner = gtk_spinner_new ();
|
||||
gtk_spinner_start (GTK_SPINNER (spinner));
|
||||
ebox = gtk_event_box_new ();
|
||||
|
||||
gtk_drag_source_set (ebox, GDK_BUTTON1_MASK, NULL, 0, GDK_ACTION_COPY);
|
||||
gtk_drag_source_add_text_targets (ebox);
|
||||
|
||||
g_signal_connect (ebox, "drag-begin", G_CALLBACK (spinner_drag_begin), spinner);
|
||||
g_signal_connect (ebox, "drag-data-get", G_CALLBACK (spinner_drag_data_get), spinner);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (ebox), spinner);
|
||||
|
||||
return ebox;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *Argv[])
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *grid;
|
||||
GtkWidget *entry;
|
||||
|
||||
gtk_init (NULL, NULL);
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Drag And Drop");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
g_object_set (grid,
|
||||
"margin", 20,
|
||||
"row-spacing", 20,
|
||||
"column-spacing", 20,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), grid);
|
||||
gtk_grid_attach (GTK_GRID (grid), make_image ("dialog-warning", TOP_LEFT), 0, 0, 1, 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), make_image ("process-stop", BOTTOM_RIGHT), 1, 0, 1, 1);
|
||||
|
||||
entry = gtk_entry_new ();
|
||||
gtk_grid_attach (GTK_GRID (grid), entry, 0, 1, 2, 1);
|
||||
|
||||
gtk_grid_attach (GTK_GRID (grid), make_spinner (), 0, 2, 1, 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), make_image ("weather-clear", CENTER), 1, 2, 1, 1);
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user