blob: 0bd1b4699b52af02f9750227f7e882b897ca8404 [file] [log] [blame]
#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