1 /* $Id: gtkdatabox_points.c 4 2008-06-22 09:19:11Z rbock $ */
2 /* GtkDatabox - An extension to the gtk+ library
3  * Copyright (C) 1998 - 2008  Dr. Roland Bock
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public License
7  * as published by the Free Software Foundation; either version 2.1
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 #include <gtkdatabox_points.h>
21 
22 G_DEFINE_TYPE(GtkDataboxPoints, gtk_databox_points,
23 	GTK_DATABOX_TYPE_XYC_GRAPH)
24 
25 static void gtk_databox_points_real_draw (GtkDataboxGraph * points,
26 					  GtkDatabox * box);
27 
28 /**
29  * GtkDataboxPointsPrivate
30  *
31  * A private data structure used by the #GtkDataboxPoints. It shields all internal things
32  * from developers who are just using the object.
33  *
34  **/
35 typedef struct _GtkDataboxPointsPrivate GtkDataboxPointsPrivate;
36 
37 struct _GtkDataboxPointsPrivate
38 {
39    gint16 *xpixels;
40    gint16 *ypixels;
41    guint pixelsalloc;
42 };
43 
44 static void
points_finalize(GObject * object)45 points_finalize (GObject * object)
46 {
47    //GtkDataboxPoints *points = GTK_DATABOX_POINTS (object);
48 
49    g_free (GTK_DATABOX_POINTS_GET_PRIVATE(object)->xpixels);
50    g_free (GTK_DATABOX_POINTS_GET_PRIVATE(object)->ypixels);
51 
52    /* Chain up to the parent class */
53    G_OBJECT_CLASS (gtk_databox_points_parent_class)->finalize (object);
54 }
55 
56 static void
gtk_databox_points_class_init(GtkDataboxPointsClass * klass)57 gtk_databox_points_class_init (GtkDataboxPointsClass *klass)
58 {
59    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
60    GtkDataboxGraphClass *graph_class = GTK_DATABOX_GRAPH_CLASS (klass);
61 
62    gobject_class->finalize = points_finalize;
63 
64    graph_class->draw = gtk_databox_points_real_draw;
65 
66    g_type_class_add_private (klass, sizeof (GtkDataboxPointsPrivate));
67 }
68 
69 static void
gtk_databox_points_complete(GtkDataboxPoints * points)70 gtk_databox_points_complete (GtkDataboxPoints * points)
71 {
72    GTK_DATABOX_POINTS_GET_PRIVATE(points)->xpixels = NULL;
73    GTK_DATABOX_POINTS_GET_PRIVATE(points)->ypixels = NULL;
74    GTK_DATABOX_POINTS_GET_PRIVATE(points)->pixelsalloc = 0;
75 }
76 
77 static void
gtk_databox_points_init(GtkDataboxPoints * points)78 gtk_databox_points_init (GtkDataboxPoints *points)
79 {
80    g_signal_connect (points, "notify::length",
81 		     G_CALLBACK (gtk_databox_points_complete), NULL);
82 }
83 
84 /**
85  * gtk_databox_points_new:
86  * @len: length of @X and @Y
87  * @X: array of horizontal position values of markers
88  * @Y: array of vertical position values of markers
89  * @color: color of the markers
90  * @size: marker size or line width (depending on the @type)
91  *
92  * Creates a new #GtkDataboxPoints object which can be added to a #GtkDatabox widget.
93  *
94  * Return value: A new #GtkDataboxPoints object
95  **/
96 GtkDataboxGraph *
gtk_databox_points_new(guint len,gfloat * X,gfloat * Y,GdkRGBA * color,gint size)97 gtk_databox_points_new (guint len, gfloat * X, gfloat * Y,
98 			GdkRGBA * color, gint size)
99 {
100    GtkDataboxPoints *points;
101    g_return_val_if_fail (X, NULL);
102    g_return_val_if_fail (Y, NULL);
103    g_return_val_if_fail ((len > 0), NULL);
104 
105    points = g_object_new (GTK_DATABOX_TYPE_POINTS,
106 			  "X-Values", X,
107 			  "Y-Values", Y,
108 			  "xstart", 0,
109 			  "ystart", 0,
110 			  "xstride", 1,
111 			  "ystride", 1,
112 			  "xtype", G_TYPE_FLOAT,
113 			  "ytype", G_TYPE_FLOAT,
114 			  "length", len,
115 			  "maxlen", len,
116 			  "color", color, "size", size, NULL);
117 
118    return GTK_DATABOX_GRAPH (points);
119 }
120 
121 /**
122  * gtk_databox_points_new_full:
123  * @maxlen: maximum length of @X and @Y
124  * @len: actual number of @X and @Y values to plot
125  * @X: array of horizontal position values of markers
126  * @Y: array of vertical position values of markers
127  * @xstart: the first element in the X array to plot (usually 0)
128  * @ystart: the first element in the Y array to plot (usually 0)
129  * @xstride: successive elements in the X array are separated by this much (1 if array, ncols if matrix)
130  * @ystride: successive elements in the Y array are separated by this much (1 if array, ncols if matrix)
131  * @xtype: the GType of the X array elements.  G_TYPE_FLOAT, G_TYPE_DOUBLE, etc.
132  * @ytype: the GType of the Y array elements.  G_TYPE_FLOAT, G_TYPE_DOUBLE, etc.
133  * @color: color of the markers
134  * @size: marker size or line width (depending on the @type)
135  *
136  * Creates a new #GtkDataboxPoints object which can be added to a #GtkDatabox widget.
137  *
138  * Return value: A new #GtkDataboxPoints object
139  **/
140 GtkDataboxGraph *
gtk_databox_points_new_full(guint maxlen,guint len,void * X,guint xstart,guint xstride,GType xtype,void * Y,guint ystart,guint ystride,GType ytype,GdkRGBA * color,gint size)141 gtk_databox_points_new_full (guint maxlen, guint len,
142 			void * X, guint xstart, guint xstride, GType xtype,
143 			void * Y, guint ystart, guint ystride, GType ytype,
144 			GdkRGBA * color, gint size)
145 {
146    GtkDataboxPoints *points;
147    g_return_val_if_fail (X, NULL);
148    g_return_val_if_fail (Y, NULL);
149    g_return_val_if_fail ((len > 0), NULL);
150 
151    points = g_object_new (GTK_DATABOX_TYPE_POINTS,
152 			  "X-Values", X,
153 			  "Y-Values", Y,
154 			  "xstart", xstart,
155 			  "ystart", ystart,
156 			  "xstride", xstride,
157 			  "ystride", ystride,
158 			  "xtype", xtype,
159 			  "ytype", ytype,
160 			  "length", len,
161 			  "maxlen", maxlen,
162 			  "color", color, "size", size, NULL);
163 
164    return GTK_DATABOX_GRAPH (points);
165 }
166 
167 static void
gtk_databox_points_real_draw(GtkDataboxGraph * graph,GtkDatabox * box)168 gtk_databox_points_real_draw (GtkDataboxGraph * graph,
169 			      GtkDatabox* box)
170 {
171    GtkDataboxPoints *points = GTK_DATABOX_POINTS (graph);
172    GtkDataboxPointsPrivate *priv=GTK_DATABOX_POINTS_GET_PRIVATE(points);
173    guint i = 0;
174    void *X;
175    void *Y;
176    guint len, maxlen;
177    gint pointsize = 0;
178    cairo_t *cr;
179    gint16 *xpixels, *ypixels;
180    guint xstart, xstride, ystart, ystride;
181    GType xtype, ytype;
182 
183    g_return_if_fail (GTK_DATABOX_IS_POINTS (points));
184    g_return_if_fail (GTK_IS_DATABOX (box));
185 
186    cr = gtk_databox_graph_create_gc (graph, box);
187 
188    len = gtk_databox_xyc_graph_get_length (GTK_DATABOX_XYC_GRAPH (graph));
189    maxlen = gtk_databox_xyc_graph_get_maxlen (GTK_DATABOX_XYC_GRAPH (graph));
190 
191    if (priv->pixelsalloc < len)
192    {
193    	priv->pixelsalloc = len;
194 	priv->xpixels = (gint16 *)g_realloc(priv->xpixels, len * sizeof(gint16));
195 	priv->ypixels = (gint16 *)g_realloc(priv->ypixels, len * sizeof(gint16));
196    }
197 
198    xpixels = priv->xpixels;
199    ypixels = priv->ypixels;
200 
201    X = gtk_databox_xyc_graph_get_X (GTK_DATABOX_XYC_GRAPH (graph));
202    xstart = gtk_databox_xyc_graph_get_xstart (GTK_DATABOX_XYC_GRAPH (graph));
203    xstride = gtk_databox_xyc_graph_get_xstride (GTK_DATABOX_XYC_GRAPH (graph));
204    xtype = gtk_databox_xyc_graph_get_xtype (GTK_DATABOX_XYC_GRAPH (graph));
205    gtk_databox_values_to_xpixels(box, xpixels, X, xtype, maxlen, xstart, xstride, len);
206 
207    Y = gtk_databox_xyc_graph_get_Y (GTK_DATABOX_XYC_GRAPH (graph));
208    ystart = gtk_databox_xyc_graph_get_ystart (GTK_DATABOX_XYC_GRAPH (graph));
209    ystride = gtk_databox_xyc_graph_get_ystride (GTK_DATABOX_XYC_GRAPH (graph));
210    ytype = gtk_databox_xyc_graph_get_ytype (GTK_DATABOX_XYC_GRAPH (graph));
211    gtk_databox_values_to_ypixels(box, ypixels, Y, ytype, maxlen, ystart, ystride, len);
212 
213    pointsize = gtk_databox_graph_get_size (graph);
214 
215    for (i = 0; i < len; i++, xpixels++, ypixels++)
216       cairo_rectangle(cr, *xpixels - pointsize / 2, *ypixels - pointsize / 2, pointsize, pointsize);
217 
218    cairo_fill(cr);
219    cairo_destroy(cr);
220    return;
221 }
222