/** typednd.c **/ #include #include "minilogo.xpm" #define HEIGHT 300 #define WIDTH 200 #define TARGET_TYPE_TEXT 80 #define TARGET_TYPE_PIXMAP 81 typedef struct { GtkWidget *app; GnomeCanvasGroup *rootGroup; } tdContext; static GtkTargetEntry fromImage[] = { { "text/plain", 0, TARGET_TYPE_TEXT }, { "image/x-xpixmap", 0, TARGET_TYPE_PIXMAP } }; static GtkTargetEntry toButton = { "text/plain", 0, TARGET_TYPE_TEXT }; static GtkTargetEntry toCanvas = { "image/x-xpixmap", 0, TARGET_TYPE_PIXMAP }; gint eventDelete(GtkWidget *widget, GdkEvent *event,gpointer data); gint eventDestroy(GtkWidget *widget, GdkEvent *event,gpointer data); GtkWidget *makeLayout(tdContext *tdcontext); void addImage(tdContext *tdcontext,char **xpm, gint x,gint y); void sendCallback(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection,guint info,guint time); void receiveCallback(GtkWidget *widget, GdkDragContext *context, gint x,gint y,GtkSelectionData *selection, guint info,guint time,tdContext *tdcontext); int main(int argc,char *argv[]) { GtkWidget *layout; tdContext *tdcontext = g_malloc0(sizeof(tdContext)); gnome_init("typednd","1.0",argc,argv); tdcontext->app = gnome_app_new("typednd","Type DND"); gtk_signal_connect(GTK_OBJECT(tdcontext->app), "delete_event", GTK_SIGNAL_FUNC(eventDelete),NULL); gtk_signal_connect(GTK_OBJECT(tdcontext->app), "destroy", GTK_SIGNAL_FUNC(eventDestroy), NULL); gtk_widget_show_all(tdcontext->app); layout = makeLayout(tdcontext); gnome_app_set_contents(GNOME_APP(tdcontext->app), layout); gtk_widget_show_all(tdcontext->app); gtk_main(); exit(0); } GtkWidget *makeLayout(tdContext *tdcontext) { GtkWidget *box; GtkWidget *canvas; GtkWidget *button; box = gtk_vbox_new(FALSE,0); gtk_widget_show(box); canvas = gnome_canvas_new(); gtk_widget_set_usize(canvas,WIDTH,HEIGHT); gnome_canvas_set_scroll_region(GNOME_CANVAS(canvas), 0.0,0.0,WIDTH,HEIGHT); tdcontext->rootGroup = gnome_canvas_root(GNOME_CANVAS(canvas)); gtk_signal_connect(GTK_OBJECT(canvas), "drag_data_received", GTK_SIGNAL_FUNC(receiveCallback),tdcontext); gtk_drag_dest_set(canvas, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, &toCanvas,1, GDK_ACTION_COPY); gtk_box_pack_start(GTK_BOX(box),canvas,TRUE,FALSE,0); addImage(tdcontext,minilogo,WIDTH/2,HEIGHT/2); button = gtk_button_new_with_label("Text Target"); gtk_signal_connect(GTK_OBJECT(button), "drag_data_received", GTK_SIGNAL_FUNC(receiveCallback),tdcontext); gtk_drag_dest_set(button, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, &toButton,1, GDK_ACTION_COPY); gtk_box_pack_start(GTK_BOX(box),button,TRUE,FALSE,0); return(box); } void addImage(tdContext *tdcontext,char **xpm, gint x,gint y) { int width; int height; GtkStyle *style; GdkBitmap *mask; GdkPixmap *pixmap; GtkWidget *button; GtkWidget *pixmapWidget; GnomeCanvasItem *item; style = gtk_widget_get_style( GTK_WIDGET(tdcontext->app)); pixmap = gdk_pixmap_create_from_xpm_d( GTK_WIDGET(tdcontext->app)->window, &mask,&style->bg[GTK_STATE_NORMAL],xpm); pixmapWidget = gtk_pixmap_new(pixmap,mask); button = gtk_button_new(); gtk_container_add(GTK_CONTAINER(button),pixmapWidget); sscanf(xpm[0],"%d %d",&width,&height); item = gnome_canvas_item_new(tdcontext->rootGroup, gnome_canvas_widget_get_type(), "widget",button, "x",(double)x, "y",(double)y, "width",(double)width + 10, "height",(double)height + 10, "anchor",GTK_ANCHOR_CENTER, NULL); gtk_signal_connect(GTK_OBJECT(button),"drag_data_get", GTK_SIGNAL_FUNC(sendCallback),NULL); gtk_drag_source_set(GTK_WIDGET(button), GDK_BUTTON1_MASK, fromImage,2, GDK_ACTION_COPY); gtk_widget_show_all(button); } void sendCallback(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection,guint targetType, guint eventTime) { char str[80]; time_t now; switch(targetType) { case TARGET_TYPE_TEXT: time(&now); strcpy(str,ctime(&now)); str[24] = '\0'; gtk_selection_data_set(selection, selection->target,8, (guchar *)str,strlen(str)); break; case TARGET_TYPE_PIXMAP: gtk_selection_data_set(selection, selection->target,8, (guchar *)minilogo,sizeof(minilogo)); break; default: break; } } void receiveCallback(GtkWidget *widget, GdkDragContext *context, gint x,gint y,GtkSelectionData *selection, guint targetType,guint time,tdContext *tdcontext) { GtkWidget *label; switch(targetType) { case TARGET_TYPE_TEXT: label = GTK_BUTTON(widget)->child; gtk_label_set_text(GTK_LABEL(label), selection->data); break; case TARGET_TYPE_PIXMAP: addImage(tdcontext,(gchar **)selection->data,x,y); break; default: break; } } gint eventDelete(GtkWidget *widget, GdkEvent *event,gpointer data) { return(FALSE); } gint eventDestroy(GtkWidget *widget, GdkEvent *event,gpointer data) { gtk_main_quit(); return(0); }