| #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 && widget != pixmapboxes[i] ; i++); |
| if (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; i<n ; i++) { |
| points[i].x =.5+ ((xcord[i]-xmn)*(width-1)/(xmx-xmn)); |
| points[i].y =.5+ ((ycord[i]-ymx)*(height-1)/(ymn-ymx)); |
| } |
| gdk_draw_lines(*ppixmap,gc,points,n); |
| g_free(points); |
| gpk_redraw(*ppixmap,widget); |
| } |
| gdk_gc_destroy(gc); |
| } |
| |
| |
| |
| void gpk_rectangle_draw(GtkWidget *widget, /* plot on this widged */ |
| gdouble *xcord, gdouble *ycord, /* corners */ |
| gdouble xmn,gdouble ymn, /* coordinates of corners */ |
| gdouble xmx,gdouble ymx, |
| GdkColor *color) |
| { |
| GdkPixmap **ppixmap; |
| GdkPoint points[2]; |
| int i; |
| gint16 width,height; |
| 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; |
| |
| |
| 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<n ; i++) { |
| points[1].x =.5+ ((xcord[i]-xmn)*(width-1)/(xmx-xmn)); |
| points[1].y =.5+ ((ycord[i]-ymx)*(height-1)/(ymn-ymx)); |
| points[0].x = points[1].x; |
| points[0].y = height-1; |
| |
| x = .5+ ((xcord[i]-xmn)*(width-1)/(xmx-xmn)); |
| y = .5+((ycord[i]-ymx)*(height-1)/(ymn-ymx)); |
| if (!barwidth) barwidth = (width/(n+1))-1; |
| barwidth = barwidth > 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 |