home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 24 / AACD 24.iso / AACD / Sound / LAME / WarpOS / src / frontend / gpkplotting.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-15  |  8.6 KB  |  325 lines

  1. /*
  2.  *    GTK plotting routines source file
  3.  *
  4.  *    Copyright (c) 1999 Mark Taylor
  5.  *
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Library General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the GNU
  14.  * Library General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Library General Public
  17.  * License along with this library; if not, write to the
  18.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19.  * Boston, MA 02111-1307, USA.
  20.  */
  21.  
  22. /* $Id: gpkplotting.c,v 1.8 2001/01/15 15:16:08 aleidinger Exp $ */
  23.  
  24. #ifdef HAVE_CONFIG_H
  25. # include <config.h>
  26. #endif
  27.  
  28. #include "gpkplotting.h"
  29.  
  30. #ifdef STDC_HEADERS
  31. # include <string.h>
  32. #else
  33. # ifndef HAVE_STRCHR
  34. #  define strchr index
  35. #  define strrchr rindex
  36. # endif
  37. char *strchr (), *strrchr ();
  38. # ifndef HAVE_MEMCPY
  39. #  define memcpy(d, s, n) bcopy ((s), (d), (n))
  40. #  define memmove(d, s, n) bcopy ((s), (d), (n))
  41. # endif
  42. #endif
  43.  
  44. #ifdef WITH_DMALLOC
  45. #include <dmalloc.h>
  46. #endif
  47.  
  48. static gint num_plotwindows = 0;
  49. static gint max_plotwindows = 10;
  50. static GdkPixmap *pixmaps[10];
  51. static GtkWidget *pixmapboxes[10];
  52.  
  53.  
  54.  
  55.  
  56. /* compute a gdkcolor */
  57. void setcolor(GtkWidget *widget, GdkColor *color, gint red,gint green,gint blue)
  58. {
  59.  
  60.   /* colors in GdkColor are taken from 0 to 65535, not 0 to 255.    */
  61.   color->red = red * (65535/255);
  62.   color->green = green * (65535/255);
  63.   color->blue = blue * (65535/255);
  64.   color->pixel = (gulong)(color->red*65536 + color->green*256 + color->blue);
  65.   /* find closest in colormap, if needed */
  66.   gdk_color_alloc(gtk_widget_get_colormap(widget),color);
  67. }
  68.  
  69.  
  70. void gpk_redraw(GdkPixmap *pixmap, GtkWidget *pixmapbox)
  71. {
  72.   /* redraw the entire pixmap */
  73.   gdk_draw_pixmap(pixmapbox->window,
  74.           pixmapbox->style->fg_gc[GTK_WIDGET_STATE (pixmapbox)],
  75.           pixmap,0,0,0,0,
  76.           pixmapbox->allocation.width,
  77.           pixmapbox->allocation.height);
  78. }
  79.  
  80.  
  81. static GdkPixmap **findpixmap(GtkWidget *widget)
  82. {
  83.   int i;
  84.   for (i=0; i<num_plotwindows  && widget != pixmapboxes[i] ; i++);
  85.   if (i>=num_plotwindows) {
  86.     g_print("findpixmap(): bad argument widget \n");
  87.     return NULL;
  88.   }
  89.   return &pixmaps[i];
  90. }
  91.  
  92. void gpk_graph_draw(GtkWidget *widget,               /* plot on this widged */
  93.            int n,                           /* number of data points */
  94.            gdouble *xcord, gdouble *ycord,  /* data */
  95.            gdouble xmn,gdouble ymn,         /* coordinates of corners */
  96.            gdouble xmx,gdouble ymx,
  97.                    int clear,                       /* clear old plot first */
  98.            char *title,                     /* add a title (only if clear=1) */
  99.                    GdkColor *color)            
  100. {
  101.   GdkPixmap **ppixmap;
  102.   GdkPoint *points;
  103.   int i;
  104.   gint16 width,height;
  105.   GdkFont *fixed_font;
  106.   GdkGC *gc;
  107.  
  108.   gc = gdk_gc_new(widget->window);
  109.   gdk_gc_set_foreground(gc, color);
  110.  
  111.  
  112.  
  113.   if ((ppixmap=findpixmap(widget))) {
  114.     width = widget->allocation.width;
  115.     height = widget->allocation.height;
  116.  
  117.  
  118.     if (clear) {
  119.       /* white background */
  120.       gdk_draw_rectangle (*ppixmap,
  121.               widget->style->white_gc,
  122.               TRUE,0, 0,width,height);
  123.       /* title */
  124. #ifdef _WIN32
  125.       fixed_font = gdk_font_load ("-misc-fixed-large-r-*-*-*-100-*-*-*-*-*-*");
  126. #else
  127.       fixed_font = gdk_font_load ("-misc-fixed-medium-r-*-*-*-100-*-*-*-*-iso8859-1");
  128. #endif
  129.  
  130.       gdk_draw_text (*ppixmap,fixed_font,
  131.              widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
  132.              0,10,title,strlen(title));
  133.     }
  134.       
  135.  
  136.     points = g_malloc(n*sizeof(GdkPoint));
  137.     for (i=0; i<n ; i++) {
  138.       points[i].x =.5+  ((xcord[i]-xmn)*(width-1)/(xmx-xmn));
  139.       points[i].y =.5+  ((ycord[i]-ymx)*(height-1)/(ymn-ymx));
  140.     }
  141.     gdk_draw_lines(*ppixmap,gc,points,n);
  142.     g_free(points);
  143.     gpk_redraw(*ppixmap,widget);
  144.   }
  145.   gdk_gc_destroy(gc);
  146. }
  147.  
  148.  
  149.  
  150. void gpk_rectangle_draw(GtkWidget *widget,              /* plot on this widged */
  151.             gdouble *xcord, gdouble *ycord, /* corners */
  152.             gdouble xmn,gdouble ymn,        /* coordinates of corners */
  153.             gdouble xmx,gdouble ymx,
  154.             GdkColor *color)
  155. {
  156.   GdkPixmap **ppixmap;
  157.   GdkPoint points[2];
  158.   int i;
  159.   gint16 width,height;
  160.   GdkGC *gc;
  161.  
  162.  
  163.   gc = gdk_gc_new(widget->window);
  164.   gdk_gc_set_foreground(gc, color);
  165.  
  166.  
  167.   if ((ppixmap=findpixmap(widget))) {
  168.     width = widget->allocation.width;
  169.     height = widget->allocation.height;
  170.  
  171.  
  172.     for (i=0; i<2 ; i++) {
  173.       points[i].x =.5+  ((xcord[i]-xmn)*(width-1)/(xmx-xmn));
  174.       points[i].y =.5+  ((ycord[i]-ymx)*(height-1)/(ymn-ymx));
  175.     }
  176.     width=points[1].x-points[0].x + 1;
  177.     height=points[1].y-points[0].y + 1;
  178.     gdk_draw_rectangle(*ppixmap,gc,TRUE,
  179.                points[0].x,points[0].y,width,height);
  180.     gpk_redraw(*ppixmap,widget);
  181.   }
  182.   gdk_gc_destroy(gc);
  183. }
  184.  
  185.  
  186.  
  187. void gpk_bargraph_draw(GtkWidget *widget,           /* plot on this widged */
  188.            int n,                           /* number of data points */
  189.            gdouble *xcord, gdouble *ycord,  /* data */
  190.            gdouble xmn,gdouble ymn,         /* coordinates of corners */
  191.            gdouble xmx,gdouble ymx,
  192.                    int clear,                       /* clear old plot first */
  193.            char *title,                     /* add a title (only if clear=1) */
  194.                    int barwidth,                    /* bar width. 0=compute based on window size */    
  195.                    GdkColor *color)            
  196. {
  197.   GdkPixmap **ppixmap;
  198.   GdkPoint points[2];
  199.   int i;
  200.   gint16 width,height,x,y,barheight;
  201.   GdkFont *fixed_font;
  202.   GdkGC *gc;
  203.  
  204.  
  205.   gc = gdk_gc_new(widget->window);
  206.   gdk_gc_set_foreground(gc, color);
  207.  
  208.  
  209.   if ((ppixmap=findpixmap(widget))) {
  210.     width = widget->allocation.width;
  211.     height = widget->allocation.height;
  212.  
  213.  
  214.     if (clear) {
  215.       /* white background */
  216.       gdk_draw_rectangle (*ppixmap,
  217.               widget->style->white_gc,
  218.               TRUE,0, 0,width,height);
  219.       /* title */
  220. #ifdef _WIN32
  221.       fixed_font = gdk_font_load ("-misc-fixed-large-r-*-*-*-100-*-*-*-*-*-*");
  222. #else
  223.       fixed_font = gdk_font_load ("-misc-fixed-medium-r-*-*-*-100-*-*-*-*-iso8859-1");
  224. #endif
  225.  
  226.       gdk_draw_text (*ppixmap,fixed_font,
  227.              widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
  228.              0,10,title,strlen(title));
  229.     }
  230.       
  231.  
  232.     for (i=0; i<n ; i++) {
  233.       points[1].x =.5+  ((xcord[i]-xmn)*(width-1)/(xmx-xmn));
  234.       points[1].y =.5+  ((ycord[i]-ymx)*(height-1)/(ymn-ymx));
  235.       points[0].x = points[1].x;
  236.       points[0].y = height-1;
  237.  
  238.       x = .5+  ((xcord[i]-xmn)*(width-1)/(xmx-xmn));
  239.       y = .5+((ycord[i]-ymx)*(height-1)/(ymn-ymx));
  240.       if (!barwidth) barwidth  = (width/(n+1))-1;
  241.       barwidth = barwidth > 5 ? 5 : barwidth;
  242.       barwidth = barwidth < 1 ? 1 : barwidth;
  243.       barheight = height-1 - y;
  244.       /* gdk_draw_lines(*ppixmap,gc,points,2); */
  245.       gdk_draw_rectangle(*ppixmap,gc,TRUE,x,y,barwidth,barheight);
  246.  
  247.     }
  248.     gpk_redraw(*ppixmap,widget);
  249.   }
  250.   gdk_gc_destroy(gc);
  251. }
  252.  
  253.  
  254.  
  255.  
  256.  
  257. /* Create a new backing pixmap of the appropriate size */
  258. static gint
  259. configure_event (GtkWidget *widget, GdkEventConfigure *event, gpointer data)
  260. {
  261.   GdkPixmap **ppixmap;
  262.   if ((ppixmap=findpixmap(widget))){
  263.     if (*ppixmap) gdk_pixmap_unref(*ppixmap);
  264.     *ppixmap = gdk_pixmap_new(widget->window,
  265.                 widget->allocation.width,
  266.                 widget->allocation.height,
  267.                 -1);
  268.     gdk_draw_rectangle (*ppixmap,
  269.             widget->style->white_gc,
  270.             TRUE,
  271.             0, 0,
  272.             widget->allocation.width,
  273.             widget->allocation.height);
  274.   }
  275.   return TRUE;
  276. }
  277.  
  278.  
  279.  
  280. /* Redraw the screen from the backing pixmap */
  281. static gint
  282. expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data)
  283. {
  284.   GdkPixmap **ppixmap;
  285.   if ((ppixmap=findpixmap(widget))){
  286.     gdk_draw_pixmap(widget->window,
  287.             widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
  288.             *ppixmap,
  289.             event->area.x, event->area.y,
  290.             event->area.x, event->area.y,
  291.             event->area.width, event->area.height);
  292.   }
  293.  
  294.   return FALSE;
  295. }
  296.  
  297.  
  298.  
  299.  
  300.  
  301. GtkWidget *gpk_plot_new(int width, int height)
  302. {
  303.   GtkWidget *pixmapbox;
  304.    
  305.   pixmapbox = gtk_drawing_area_new();
  306.   gtk_drawing_area_size(GTK_DRAWING_AREA(pixmapbox),width,height);
  307.   gtk_signal_connect (GTK_OBJECT (pixmapbox), "expose_event",
  308.               (GtkSignalFunc) expose_event, NULL);
  309.   gtk_signal_connect (GTK_OBJECT(pixmapbox),"configure_event",
  310.               (GtkSignalFunc) configure_event, NULL);
  311.   gtk_widget_set_events (pixmapbox, GDK_EXPOSURE_MASK);
  312.  
  313.   if (num_plotwindows < max_plotwindows) {
  314.     pixmapboxes[num_plotwindows] = pixmapbox;
  315.     pixmaps[num_plotwindows] = NULL;
  316.     num_plotwindows ++;
  317.   } else {
  318.     g_print("gtk_plotarea_new(): exceeded maximum of 10 plotarea windows\n");
  319.   }
  320.  
  321.   return pixmapbox;
  322. }
  323.  
  324.  
  325.