#ifdef HAVEGTK #include "gpkplotting.h" #include "string.h" static gint num_plotwindows = 0; static gint max_plotwindows = 10; static GdkPixmap *pixmaps[10]; static GtkWidget *pixmapboxes[10]; /* compute a gdkcolor */ void setcolor(GtkWidget *widget, GdkColor *color, gint red,gint green,gint blue) { /* colors in GdkColor are taken from 0 to 65535, not 0 to 255. */ color->red = red * (65535/255); color->green = green * (65535/255); color->blue = blue * (65535/255); color->pixel = (gulong)(color->red*65536 + color->green*256 + color->blue); /* find closest in colormap, if needed */ gdk_color_alloc(gtk_widget_get_colormap(widget),color); } void gpk_redraw(GdkPixmap *pixmap, GtkWidget *pixmapbox) { /* redraw the entire pixmap */ gdk_draw_pixmap(pixmapbox->window, pixmapbox->style->fg_gc[GTK_WIDGET_STATE (pixmapbox)], pixmap,0,0,0,0, pixmapbox->allocation.width, pixmapbox->allocation.height); } static GdkPixmap **findpixmap(GtkWidget *widget) { int i; for (i=0; i=num_plotwindows) { g_print("findpixmap(): bad argument widget \n"); return NULL; } return &pixmaps[i]; } void gpk_graph_draw(GtkWidget *widget, /* plot on this widged */ int n, /* number of data points */ gdouble *xcord, gdouble *ycord, /* data */ gdouble xmn,gdouble ymn, /* coordinates of corners */ gdouble xmx,gdouble ymx, int clear, /* clear old plot first */ char *title, /* add a title (only if clear=1) */ GdkColor *color) { GdkPixmap **ppixmap; GdkPoint *points; int i; gint16 width,height; GdkFont *fixed_font; GdkGC *gc; gc = gdk_gc_new(widget->window); gdk_gc_set_foreground(gc, color); if ((ppixmap=findpixmap(widget))) { width = widget->allocation.width; height = widget->allocation.height; if (clear) { /* white background */ gdk_draw_rectangle (*ppixmap, widget->style->white_gc, TRUE,0, 0,width,height); /* title */ #ifndef _WIN32 fixed_font = gdk_font_load ("-misc-fixed-medium-r-*-*-*-100-*-*-*-*-*-*"); #else fixed_font = gdk_font_load ("-misc-fixed-large-r-*-*-*-100-*-*-*-*-*-*"); #endif gdk_draw_text (*ppixmap,fixed_font, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], 0,10,title,strlen(title)); } points = g_malloc(n*sizeof(GdkPoint)); for (i=0; iwindow); gdk_gc_set_foreground(gc, color); if ((ppixmap=findpixmap(widget))) { width = widget->allocation.width; height = widget->allocation.height; for (i=0; i<2 ; i++) { points[i].x =.5+ ((xcord[i]-xmn)*(width-1)/(xmx-xmn)); points[i].y =.5+ ((ycord[i]-ymx)*(height-1)/(ymn-ymx)); } width=points[1].x-points[0].x + 1; height=points[1].y-points[0].y + 1; gdk_draw_rectangle(*ppixmap,gc,TRUE, points[0].x,points[0].y,width,height); gpk_redraw(*ppixmap,widget); } gdk_gc_destroy(gc); } void gpk_bargraph_draw(GtkWidget *widget, /* plot on this widged */ int n, /* number of data points */ gdouble *xcord, gdouble *ycord, /* data */ gdouble xmn,gdouble ymn, /* coordinates of corners */ gdouble xmx,gdouble ymx, int clear, /* clear old plot first */ char *title, /* add a title (only if clear=1) */ int barwidth, /* bar width. 0=compute based on window size */ GdkColor *color) { GdkPixmap **ppixmap; GdkPoint points[2]; int i; gint16 width,height,x,y,barheight; GdkFont *fixed_font; GdkGC *gc; gc = gdk_gc_new(widget->window); gdk_gc_set_foreground(gc, color); if ((ppixmap=findpixmap(widget))) { width = widget->allocation.width; height = widget->allocation.height; if (clear) { /* white background */ gdk_draw_rectangle (*ppixmap, widget->style->white_gc, TRUE,0, 0,width,height); /* title */ #ifndef _WIN32 fixed_font = gdk_font_load ("-misc-fixed-medium-r-*-*-*-100-*-*-*-*-*-*"); #else fixed_font = gdk_font_load ("-misc-fixed-large-r-*-*-*-100-*-*-*-*-*-*"); #endif gdk_draw_text (*ppixmap,fixed_font, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], 0,10,title,strlen(title)); } for (i=0; i 5 ? 5 : barwidth; barwidth = barwidth < 1 ? 1 : barwidth; barheight = height-1 - y; /* gdk_draw_lines(*ppixmap,gc,points,2); */ gdk_draw_rectangle(*ppixmap,gc,TRUE,x,y,barwidth,barheight); } gpk_redraw(*ppixmap,widget); } gdk_gc_destroy(gc); } /* Create a new backing pixmap of the appropriate size */ static gint configure_event (GtkWidget *widget, GdkEventConfigure *event, gpointer data) { GdkPixmap **ppixmap; if ((ppixmap=findpixmap(widget))){ if (*ppixmap) gdk_pixmap_unref(*ppixmap); *ppixmap = gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1); gdk_draw_rectangle (*ppixmap, widget->style->white_gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height); } return TRUE; } /* Redraw the screen from the backing pixmap */ static gint expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data) { GdkPixmap **ppixmap; if ((ppixmap=findpixmap(widget))){ gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], *ppixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); } return FALSE; } GtkWidget *gpk_plot_new(int width, int height) { GtkWidget *pixmapbox; pixmapbox = gtk_drawing_area_new(); gtk_drawing_area_size(GTK_DRAWING_AREA(pixmapbox),width,height); gtk_signal_connect (GTK_OBJECT (pixmapbox), "expose_event", (GtkSignalFunc) expose_event, NULL); gtk_signal_connect (GTK_OBJECT(pixmapbox),"configure_event", (GtkSignalFunc) configure_event, NULL); gtk_widget_set_events (pixmapbox, GDK_EXPOSURE_MASK); if (num_plotwindows < max_plotwindows) { pixmapboxes[num_plotwindows] = pixmapbox; pixmaps[num_plotwindows] = NULL; num_plotwindows ++; } else { g_print("gtk_plotarea_new(): exceeded maximum of 10 plotarea windows\n"); } return pixmapbox; } #endif