"Fossies" - the Fresh Open Source Software Archive 
Member "gtkdatabox-1.0.0/gtk/gtkdatabox_xyyc_graph.c" (31 Mar 2021, 29218 Bytes) of package /linux/privat/gtkdatabox-1.0.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "gtkdatabox_xyyc_graph.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
0.9.3.1_vs_1.0.0.
1 /* $Id: gtkdatabox_xyyc_graph.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 * Copyright (C) 2012 Dr. Matt Flax <flatmax@>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
10 *
11 * This program 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
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <gtkdatabox_xyyc_graph.h>
22
23 static gint gtk_databox_xyyc_graph_real_calculate_extrema (GtkDataboxGraph *
24 xyyc_graph,
25 gfloat * min_x,
26 gfloat * max_x,
27 gfloat * min_y,
28 gfloat * max_y);
29
30 /* IDs of properties */
31 enum
32 {
33 PROP_X = 1,
34 PROP_Y1,
35 PROP_Y2,
36 PROP_LEN,
37 PROP_SIZE,
38 PROP_XSTART,
39 PROP_Y1START,
40 PROP_Y2START,
41 PROP_XSTRIDE,
42 PROP_Y1STRIDE,
43 PROP_Y2STRIDE,
44 PROP_XTYPE,
45 PROP_YTYPE
46 };
47
48 /**
49 * GtkDataboxXYYCGraphPrivate
50 *
51 * A private data structure used by the #GtkDataboxXYYCGraph. It shields all internal things
52 * from developers who are just using the object.
53 *
54 **/
55 typedef struct _GtkDataboxXYYCGraphPrivate GtkDataboxXYYCGraphPrivate;
56
57 struct _GtkDataboxXYYCGraphPrivate
58 {
59 gfloat *X;
60 gfloat *Y1;
61 gfloat *Y2;
62 guint len;
63 guint maxlen;
64 guint xstart;
65 guint y1start;
66 guint y2start;
67 guint xstride;
68 guint y1stride;
69 guint y2stride;
70 GType xtype;
71 GType ytype;
72 };
73
74 G_DEFINE_TYPE_WITH_PRIVATE(GtkDataboxXYYCGraph, gtk_databox_xyyc_graph,
75 GTK_DATABOX_TYPE_GRAPH)
76
77 static void
78 gtk_databox_xyyc_graph_set_X (GtkDataboxXYYCGraph * xyyc_graph, gfloat * X)
79 {
80 g_return_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph));
81 g_return_if_fail (X);
82 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
83 priv->X = X;
84
85 g_object_notify (G_OBJECT (xyyc_graph), "X-Values");
86 }
87
88 static void
89 gtk_databox_xyyc_graph_set_Y1 (GtkDataboxXYYCGraph * xyyc_graph, gfloat * Y1)
90 {
91 g_return_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph));
92 g_return_if_fail (Y1);
93 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
94 priv->Y1 = Y1;
95
96 g_object_notify (G_OBJECT (xyyc_graph), "Y1-Values");
97 }
98
99 static void
100 gtk_databox_xyyc_graph_set_Y2 (GtkDataboxXYYCGraph * xyyc_graph, gfloat * Y2)
101 {
102 g_return_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph));
103 g_return_if_fail (Y2);
104 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
105 priv->Y2 = Y2;
106
107 g_object_notify (G_OBJECT (xyyc_graph), "Y2-Values");
108 }
109
110 static void
111 gtk_databox_xyyc_graph_set_length (GtkDataboxXYYCGraph * xyyc_graph, guint len)
112 {
113 g_return_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph));
114 g_return_if_fail (len > 0);
115 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
116 priv->len = len;
117
118 g_object_notify (G_OBJECT (xyyc_graph), "length");
119 }
120
121 static void
122 gtk_databox_xyyc_graph_set_maxlen (GtkDataboxXYYCGraph * xyyc_graph, guint maxlen)
123 {
124 g_return_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph));
125 g_return_if_fail (maxlen > 0);
126 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
127 priv->maxlen = maxlen;
128
129 g_object_notify (G_OBJECT (xyyc_graph), "maxlen");
130 }
131
132 static void
133 gtk_databox_xyyc_graph_set_xstart (GtkDataboxXYYCGraph * xyyc_graph, guint xstart)
134 {
135 g_return_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph));
136 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
137 priv->xstart = xstart;
138
139 g_object_notify (G_OBJECT (xyyc_graph), "X-Values");
140 }
141
142 static void
143 gtk_databox_xyyc_graph_set_y1start (GtkDataboxXYYCGraph * xyyc_graph, guint y1start)
144 {
145 g_return_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph));
146 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
147 priv->y1start = y1start;
148
149 g_object_notify (G_OBJECT (xyyc_graph), "Y1-Values");
150 }
151
152 static void
153 gtk_databox_xyyc_graph_set_y2start (GtkDataboxXYYCGraph * xyyc_graph, guint y2start)
154 {
155 g_return_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph));
156 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
157 priv->y2start = y2start;
158
159 g_object_notify (G_OBJECT (xyyc_graph), "Y2-Values");
160 }
161
162 static void
163 gtk_databox_xyyc_graph_set_xstride (GtkDataboxXYYCGraph * xyyc_graph, guint xstride)
164 {
165 g_return_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph));
166 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
167 priv->xstride = xstride;
168
169 g_object_notify (G_OBJECT (xyyc_graph), "X-Values");
170 }
171
172 static void
173 gtk_databox_xyyc_graph_set_y1stride (GtkDataboxXYYCGraph * xyyc_graph, guint y1stride)
174 {
175 g_return_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph));
176 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
177 priv->y1stride = y1stride;
178
179 g_object_notify (G_OBJECT (xyyc_graph), "Y1-Values");
180 }
181
182 static void
183 gtk_databox_xyyc_graph_set_y2stride (GtkDataboxXYYCGraph * xyyc_graph, guint y2stride)
184 {
185 g_return_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph));
186 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
187 priv->y2stride = y2stride;
188
189 g_object_notify (G_OBJECT (xyyc_graph), "Y2-Values");
190 }
191
192 static void
193 gtk_databox_xyyc_graph_set_xtype (GtkDataboxXYYCGraph * xyyc_graph, GType xtype)
194 {
195 g_return_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph));
196 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
197 priv->xtype = xtype;
198
199 g_object_notify (G_OBJECT (xyyc_graph), "X-Values");
200 }
201
202 static void
203 gtk_databox_xyyc_graph_set_ytype (GtkDataboxXYYCGraph * xyyc_graph, GType ytype)
204 {
205 g_return_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph));
206 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
207 priv->ytype = ytype;
208
209 g_object_notify (G_OBJECT (xyyc_graph), "Y1-Values");
210 g_object_notify (G_OBJECT (xyyc_graph), "Y2-Values");
211 }
212
213 static void
214 gtk_databox_xyyc_graph_set_property (GObject * object,
215 guint property_id,
216 const GValue * value, GParamSpec * pspec)
217 {
218 GtkDataboxXYYCGraph *xyyc_graph = GTK_DATABOX_XYYC_GRAPH (object);
219
220 switch (property_id)
221 {
222 case PROP_X:
223 gtk_databox_xyyc_graph_set_X (xyyc_graph, (gfloat *) g_value_get_pointer (value));
224 break;
225 case PROP_Y1:
226 gtk_databox_xyyc_graph_set_Y1 (xyyc_graph, (gfloat *) g_value_get_pointer (value));
227 break;
228 case PROP_Y2:
229 gtk_databox_xyyc_graph_set_Y2 (xyyc_graph, (gfloat *) g_value_get_pointer (value));
230 break;
231 case PROP_LEN:
232 gtk_databox_xyyc_graph_set_length (xyyc_graph, g_value_get_int (value));
233 break;
234 case PROP_SIZE:
235 gtk_databox_xyyc_graph_set_maxlen (xyyc_graph, g_value_get_int (value));
236 break;
237 case PROP_XSTART:
238 gtk_databox_xyyc_graph_set_xstart (xyyc_graph, g_value_get_int (value));
239 break;
240 case PROP_Y1START:
241 gtk_databox_xyyc_graph_set_y1start (xyyc_graph, g_value_get_int (value));
242 break;
243 case PROP_Y2START:
244 gtk_databox_xyyc_graph_set_y2start (xyyc_graph, g_value_get_int (value));
245 break;
246 case PROP_XSTRIDE:
247 gtk_databox_xyyc_graph_set_xstride (xyyc_graph, g_value_get_int (value));
248 break;
249 case PROP_Y1STRIDE:
250 gtk_databox_xyyc_graph_set_y1stride (xyyc_graph, g_value_get_int (value));
251 break;
252 case PROP_Y2STRIDE:
253 gtk_databox_xyyc_graph_set_y2stride (xyyc_graph, g_value_get_int (value));
254 break;
255 case PROP_XTYPE:
256 gtk_databox_xyyc_graph_set_xtype (xyyc_graph, g_value_get_gtype (value));
257 break;
258 case PROP_YTYPE:
259 gtk_databox_xyyc_graph_set_ytype (xyyc_graph, g_value_get_gtype (value));
260 break;
261 default:
262 /* We don't have any other property... */
263 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
264 break;
265 }
266 }
267
268 /**
269 * gtk_databox_xyyc_graph_get_X:
270 * @xyyc_graph: A #GtkDataboxXYYCGraph object
271 *
272 * Gets the X values of the @xzc_graph.
273 *
274 * Return value: Pointer to X values
275 */
276 gfloat *
277 gtk_databox_xyyc_graph_get_X (GtkDataboxXYYCGraph * xyyc_graph)
278 {
279 g_return_val_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph), NULL);
280 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
281 return priv->X;
282 }
283
284 /**
285 * gtk_databox_xyyc_graph_get_Y1:
286 * @xyyc_graph: A #GtkDataboxXYYCGraph object
287 *
288 * Gets the Y1 values of the @xzc_graph.
289 *
290 * Return value: Pointer to Y1 values
291 */
292 gfloat *
293 gtk_databox_xyyc_graph_get_Y1 (GtkDataboxXYYCGraph * xyyc_graph)
294 {
295 g_return_val_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph), NULL);
296 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
297 return priv->Y1;
298 }
299
300 /**
301 * gtk_databox_xyyc_graph_get_Y2:
302 * @xyyc_graph: A #GtkDataboxXYYCGraph object
303 *
304 * Gets the Y2 values of the @xzc_graph.
305 *
306 * Return value: Pointer to Y2 values
307 */
308 gfloat *
309 gtk_databox_xyyc_graph_get_Y2 (GtkDataboxXYYCGraph * xyyc_graph)
310 {
311 g_return_val_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph), NULL);
312 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
313 return priv->Y2;
314 }
315
316 /**
317 * gtk_databox_xyyc_graph_get_length:
318 * @xyyc_graph: A #GtkDataboxXYYCGraph object
319 *
320 * Gets the the length of the X and Y values arrays.
321 *
322 * Return value: Length of X/Y arrays.
323 */
324 guint
325 gtk_databox_xyyc_graph_get_length (GtkDataboxXYYCGraph * xyyc_graph)
326 {
327 g_return_val_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph), 0);
328 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
329 return priv->len;
330 }
331
332 /**
333 * gtk_databox_xyyc_graph_get_maxlen:
334 * @xyyc_graph: A #GtkDataboxXYYCGraph object
335 *
336 * Gets the the maxlen of the X and Y values arrays.
337 *
338 * Return value: Size of X/Y arrays (size of the allocated storage).
339 */
340 guint
341 gtk_databox_xyyc_graph_get_maxlen (GtkDataboxXYYCGraph * xyyc_graph)
342 {
343 g_return_val_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph), 0);
344 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
345 return priv->maxlen;
346 }
347
348 /**
349 * gtk_databox_xyyc_graph_get_xstart:
350 * @xyyc_graph: A #GtkDataboxXYYCGraph object
351 *
352 * Gets the the start offset of the X values array. This is the element in the array pointed to by X that will be the first element plotted.
353 * If X is a pointer to a gfloat array, and xstart is 5, then x[5] will be the first data element. If Xstride is 1, then x[6] will be the
354 * second element. x[5 + len - 1] will be last element.
355 * Usually, xstart will be 0. It can be nonzero to allow for interleaved X/Y samples, or if the data is stored as a matrix, then X can point
356 * to the start of the matrix, xstart can be the column number, and xstride the number of columns.
357 *
358 * Return value: The xstart value.
359 */
360 guint
361 gtk_databox_xyyc_graph_get_xstart (GtkDataboxXYYCGraph * xyyc_graph)
362 {
363 g_return_val_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph), 0);
364 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
365 return priv->xstart;
366 }
367
368 /**
369 * gtk_databox_xyyc_graph_get_y1start:
370 * @xyyc_graph: A #GtkDataboxXYYCGraph object
371 *
372 * Gets the the start offset of the Y1 values array. This is the element in the array pointed to by Y that will be the first element plotted.
373 * If Y1 is a pointer to a gfloat array, and y1start is 5, then y1[5] will be the first data element. If y1stride is 1, then y1[6] will be the
374 * second element. y1[5 + len - 1] will be last element.
375 * Usually, y1start will be 0. It can be nonzero to allow for interleaved X/Y1/Y2 samples, or if the data is stored as a matrix, then Y1 can point
376 * to the start of the matrix, y1start can be the column number, and y1stride the number of columns.
377 *
378 * Return value: The y1start value.
379 */
380 guint
381 gtk_databox_xyyc_graph_get_y1start (GtkDataboxXYYCGraph * xyyc_graph)
382 {
383 g_return_val_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph), 0);
384 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
385 return priv->y1start;
386 }
387
388 /**
389 * gtk_databox_xyyc_graph_get_y2start:
390 * @xyyc_graph: A #GtkDataboxXYYCGraph object
391 *
392 * Gets the the start offset of the Y2 values array. This is the element in the array pointed to by Y that will be the first element plotted.
393 * If Y2 is a pointer to a gfloat array, and y2start is 5, then y2[5] will be the first data element. If y2stride is 1, then y2[6] will be the
394 * second element. y2[5 + len - 1] will be last element.
395 * Usually, y2start will be 0. It can be nonzero to allow for interleaved X/Y1/Y2 samples, or if the data is stored as a matrix, then Y2 can point
396 * to the start of the matrix, y2start can be the column number, and y2stride the number of columns.
397 *
398 * Return value: The y2start value.
399 */
400 guint
401 gtk_databox_xyyc_graph_get_y2start (GtkDataboxXYYCGraph * xyyc_graph)
402 {
403 g_return_val_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph), 0);
404 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
405 return priv->y2start;
406 }
407
408 /**
409 * gtk_databox_xyyc_graph_get_xstride:
410 * @xyyc_graph: A #GtkDataboxXYYCGraph object
411 *
412 * Gets the the stride offset of the X values array. This is the element in the array pointed to by X that will be the first element plotted.
413 * If X is a pointer to a gfloat array, and xstart is 5, then x[5] will be the first data element. If Xstride is 1, then x[6] will be the
414 * second element. x[5 + len - 1] will be last element.
415 * Usually, xstride will be 1. It can be nonzero to allow for interleaved X/Y samples, or if the data is stored as a matrix, then X can point
416 * to the start of the matrix, xstart can be the column number, and xstride the number of columns.
417 *
418 * Return value: The xstride value.
419 */
420 guint
421 gtk_databox_xyyc_graph_get_xstride (GtkDataboxXYYCGraph * xyyc_graph)
422 {
423 g_return_val_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph), 0);
424 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
425 return priv->xstride;
426 }
427
428 /**
429 * gtk_databox_xyyc_graph_get_y1stride:
430 * @xyyc_graph: A #GtkDataboxXYYCGraph object
431 *
432 * Gets the the stride offset of the Y1 values array. This is the element in the array pointed to by Y1 that will be the first element plotted.
433 * If Y1 is a pointer to a gfloat array, and y1start is 5, then y1[5] will be the first data element. If y1stride is 1, then y1[6] will be the
434 * second element. y1[5 + len - 1] will be last element.
435 * Usually, y1stride will be 1. It can be nonzero to allow for interleaved X/Y1/Y2 samples, or if the data is stored as a matrix, then Y1 can point
436 * to the start of the matrix, y1start can be the column number, and y1stride the number of columns.
437 *
438 * Return value: The y1stride value.
439 */
440 guint
441 gtk_databox_xyyc_graph_get_y1stride (GtkDataboxXYYCGraph * xyyc_graph)
442 {
443 g_return_val_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph), 0);
444 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
445 return priv->y1stride;
446 }
447
448 /**
449 * gtk_databox_xyyc_graph_get_y2stride:
450 * @xyyc_graph: A #GtkDataboxXYYCGraph object
451 *
452 * Gets the the stride offset of the Y2 values array. This is the element in the array pointed to by Y2 that will be the first element plotted.
453 * If Y2 is a pointer to a gfloat array, and y2start is 5, then y2[5] will be the first data element. If y2stride is 1, then y2[6] will be the
454 * second element. y2[5 + len - 1] will be last element.
455 * Usually, y2stride will be 1. It can be nonzero to allow for interleaved X/Y1/Y2 samples, or if the data is stored as a matrix, then Y2 can point
456 * to the start of the matrix, y2start can be the column number, and y2stride the number of columns.
457 *
458 * Return value: The y2stride value.
459 */
460 guint
461 gtk_databox_xyyc_graph_get_y2stride (GtkDataboxXYYCGraph * xyyc_graph)
462 {
463 g_return_val_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph), 0);
464 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
465 return priv->y2stride;
466 }
467
468 /**
469 * gtk_databox_xyyc_graph_get_xtype:
470 * @xyyc_graph: A #GtkDataboxXYYCGraph object
471 *
472 * Gets the the GType of the X array elements. This may be G_TYPE_FLOAT, G_TYPE_DOUBLE, or similar.
473 *
474 * Return value: A GType, usually this is G_TYPE_FLOAT.
475 */
476 GType
477 gtk_databox_xyyc_graph_get_xtype (GtkDataboxXYYCGraph * xyyc_graph)
478 {
479 g_return_val_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph), 0);
480 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
481 return priv->xtype;
482 }
483
484 /**
485 * gtk_databox_xyyc_graph_get_ytype:
486 * @xyyc_graph: A #GtkDataboxXYYCGraph object
487 *
488 * Gets the the GType of the Y1/Y2 array elements. This may be G_TYPE_FLOAT, G_TYPE_DOUBLE, or similar.
489 *
490 * Return value: A GType, usually this is G_TYPE_FLOAT.
491 */
492 GType
493 gtk_databox_xyyc_graph_get_ytype (GtkDataboxXYYCGraph * xyyc_graph)
494 {
495 g_return_val_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph), 0);
496 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
497 return priv->ytype;
498 }
499
500 static void
501 gtk_databox_xyyc_graph_get_property (GObject * object,
502 guint property_id,
503 GValue * value, GParamSpec * pspec)
504 {
505 GtkDataboxXYYCGraph *xyyc_graph = GTK_DATABOX_XYYC_GRAPH (object);
506
507 switch (property_id)
508 {
509 case PROP_X:
510 g_value_set_pointer (value, gtk_databox_xyyc_graph_get_X (xyyc_graph));
511 break;
512 case PROP_Y1:
513 g_value_set_pointer (value, gtk_databox_xyyc_graph_get_Y1 (xyyc_graph));
514 break;
515 case PROP_Y2:
516 g_value_set_pointer (value, gtk_databox_xyyc_graph_get_Y2 (xyyc_graph));
517 break;
518 case PROP_LEN:
519 g_value_set_int (value, gtk_databox_xyyc_graph_get_length (xyyc_graph));
520 break;
521 case PROP_SIZE:
522 g_value_set_int (value, gtk_databox_xyyc_graph_get_maxlen (xyyc_graph));
523 break;
524 case PROP_XSTART:
525 g_value_set_int (value, gtk_databox_xyyc_graph_get_xstart (xyyc_graph));
526 break;
527 case PROP_Y1START:
528 g_value_set_int (value, gtk_databox_xyyc_graph_get_y1start (xyyc_graph));
529 break;
530 case PROP_Y2START:
531 g_value_set_int (value, gtk_databox_xyyc_graph_get_y2start (xyyc_graph));
532 break;
533 case PROP_XSTRIDE:
534 g_value_set_int (value, gtk_databox_xyyc_graph_get_xstride (xyyc_graph));
535 break;
536 case PROP_Y1STRIDE:
537 g_value_set_int (value, gtk_databox_xyyc_graph_get_y1stride (xyyc_graph));
538 break;
539 case PROP_Y2STRIDE:
540 g_value_set_int (value, gtk_databox_xyyc_graph_get_y2stride (xyyc_graph));
541 break;
542 case PROP_XTYPE:
543 g_value_set_gtype (value, gtk_databox_xyyc_graph_get_xtype (xyyc_graph));
544 break;
545 case PROP_YTYPE:
546 g_value_set_gtype (value, gtk_databox_xyyc_graph_get_ytype (xyyc_graph));
547 break;
548 default:
549 /* We don't have any other property... */
550 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
551 break;
552 }
553 }
554
555 static void
556 gtk_databox_xyyc_graph_class_init (GtkDataboxXYYCGraphClass *klass)
557 {
558 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
559 GtkDataboxGraphClass *graph_class = GTK_DATABOX_GRAPH_CLASS (klass);
560 GParamSpec *xyyc_graph_param_spec;
561
562 gobject_class->set_property = gtk_databox_xyyc_graph_set_property;
563 gobject_class->get_property = gtk_databox_xyyc_graph_get_property;
564
565 xyyc_graph_param_spec = g_param_spec_pointer ("X-Values",
566 "X coordinates",
567 "X values of data",
568 G_PARAM_CONSTRUCT_ONLY |
569 G_PARAM_READWRITE);
570
571 g_object_class_install_property (gobject_class,
572 PROP_X, xyyc_graph_param_spec);
573
574 xyyc_graph_param_spec = g_param_spec_pointer ("Y1-Values",
575 "Y1 coordinates",
576 "Y1 values of data",
577 G_PARAM_CONSTRUCT_ONLY |
578 G_PARAM_READWRITE);
579
580 g_object_class_install_property (gobject_class,
581 PROP_Y1, xyyc_graph_param_spec);
582
583 xyyc_graph_param_spec = g_param_spec_pointer ("Y2-Values",
584 "Y2 coordinates",
585 "Y2 values of data",
586 G_PARAM_CONSTRUCT_ONLY |
587 G_PARAM_READWRITE);
588
589 g_object_class_install_property (gobject_class,
590 PROP_Y2, xyyc_graph_param_spec);
591
592 xyyc_graph_param_spec = g_param_spec_int ("length", "length of X, Y1 and Y2", "number of data points", G_MININT, G_MAXINT, 0, /* default value */
593 G_PARAM_CONSTRUCT_ONLY |
594 G_PARAM_READWRITE);
595
596 g_object_class_install_property (gobject_class,
597 PROP_LEN, xyyc_graph_param_spec);
598
599 xyyc_graph_param_spec = g_param_spec_int ("maxlen", "maxlen of X and Y", "maximal number of data points", G_MININT, G_MAXINT, 0, /* default value */
600 G_PARAM_CONSTRUCT_ONLY |
601 G_PARAM_READWRITE);
602 g_object_class_install_property (gobject_class,
603 PROP_SIZE, xyyc_graph_param_spec);
604
605 xyyc_graph_param_spec = g_param_spec_int ("xstart", "array index of first X", "array index of first X", G_MININT, G_MAXINT, 0, /* default value */
606 G_PARAM_CONSTRUCT_ONLY |
607 G_PARAM_READWRITE);
608 g_object_class_install_property (gobject_class,
609 PROP_XSTART, xyyc_graph_param_spec);
610
611 xyyc_graph_param_spec = g_param_spec_int ("y1start", "array index of first Y1", "array index of first Y1", G_MININT, G_MAXINT, 0, /* default value */
612 G_PARAM_CONSTRUCT_ONLY |
613 G_PARAM_READWRITE);
614 g_object_class_install_property (gobject_class,
615 PROP_Y1START, xyyc_graph_param_spec);
616
617 xyyc_graph_param_spec = g_param_spec_int ("y2start", "array index of first Y2", "array index of first Y2", G_MININT, G_MAXINT, 0, /* default value */
618 G_PARAM_CONSTRUCT_ONLY |
619 G_PARAM_READWRITE);
620 g_object_class_install_property (gobject_class,
621 PROP_Y2START, xyyc_graph_param_spec);
622
623 xyyc_graph_param_spec = g_param_spec_int ("xstride", "stride of X values", "stride of X values", G_MININT, G_MAXINT, 1, /* default value */
624 G_PARAM_CONSTRUCT_ONLY |
625 G_PARAM_READWRITE);
626 g_object_class_install_property (gobject_class,
627 PROP_XSTRIDE, xyyc_graph_param_spec);
628
629 xyyc_graph_param_spec = g_param_spec_int ("y1stride", "stride of Y1 values", "stride of Y1 values", G_MININT, G_MAXINT, 1, /* default value */
630 G_PARAM_CONSTRUCT_ONLY |
631 G_PARAM_READWRITE);
632 g_object_class_install_property (gobject_class,
633 PROP_Y1STRIDE, xyyc_graph_param_spec);
634
635 xyyc_graph_param_spec = g_param_spec_int ("y2stride", "stride of Y2 values", "stride of Y2 values", G_MININT, G_MAXINT, 1, /* default value */
636 G_PARAM_CONSTRUCT_ONLY |
637 G_PARAM_READWRITE);
638 g_object_class_install_property (gobject_class,
639 PROP_Y2STRIDE, xyyc_graph_param_spec);
640
641 xyyc_graph_param_spec = g_param_spec_gtype ("xtype", "GType of X elements", "GType of X elements", G_TYPE_NONE,
642 G_PARAM_CONSTRUCT_ONLY |
643 G_PARAM_READWRITE);
644 g_object_class_install_property (gobject_class,
645 PROP_XTYPE, xyyc_graph_param_spec);
646
647 xyyc_graph_param_spec = g_param_spec_gtype ("ytype", "GType of Y1/Y2 elements", "GType of Y1/Y2 elements", G_TYPE_NONE,
648 G_PARAM_CONSTRUCT_ONLY |
649 G_PARAM_READWRITE);
650 g_object_class_install_property (gobject_class,
651 PROP_YTYPE, xyyc_graph_param_spec);
652
653 graph_class->calculate_extrema =
654 gtk_databox_xyyc_graph_real_calculate_extrema;
655 }
656
657 static void
658 gtk_databox_xyyc_graph_init (GtkDataboxXYYCGraph * xyyc_graph)
659 {
660 if (xyyc_graph == NULL) g_warning ("xyyc_graph_init with NULL");
661 }
662
663 static gint
664 gtk_databox_xyyc_graph_real_calculate_extrema (GtkDataboxGraph * graph,
665 gfloat * min_x, gfloat * max_x,
666 gfloat * min_y, gfloat * max_y)
667 {
668 GtkDataboxXYYCGraph *xyyc_graph = GTK_DATABOX_XYYC_GRAPH (graph);
669 GtkDataboxXYYCGraphPrivate *priv = gtk_databox_xyyc_graph_get_instance_private (xyyc_graph);
670 guint i, indx, len, maxlen, start, stride;
671 void *values;
672 GType vtype;
673 gfloat fval = 0.0, minval = 0.0, maxval = 0.0;
674
675 g_return_val_if_fail (GTK_DATABOX_IS_XYYC_GRAPH (xyyc_graph), -1);
676 g_return_val_if_fail (min_x, -1);
677 g_return_val_if_fail (max_x, -1);
678 g_return_val_if_fail (min_y, -1);
679 g_return_val_if_fail (max_y, -1);
680 g_return_val_if_fail (priv->len, -1);
681
682 len = priv->len;
683 maxlen = priv->maxlen;
684 values = priv->X;
685 vtype = priv->xtype;
686 start = priv->xstart;
687 stride = priv->xstride;
688
689 indx = start * stride;
690 i = 0;
691 do {
692 if (vtype == G_TYPE_FLOAT)
693 fval = ((gfloat *)values)[indx];
694 else if (vtype == G_TYPE_DOUBLE)
695 fval = ((gdouble *)values)[indx];
696 else if (vtype == G_TYPE_INT)
697 fval = ((gint *)values)[indx];
698 else if (vtype == G_TYPE_UINT)
699 fval = ((guint *)values)[indx];
700 else if (vtype == G_TYPE_LONG)
701 fval = ((glong *)values)[indx];
702 else if (vtype == G_TYPE_ULONG)
703 fval = ((gulong *)values)[indx];
704 else if (vtype == G_TYPE_INT64)
705 fval = ((gint64 *)values)[indx];
706 else if (vtype == G_TYPE_UINT64)
707 fval = ((guint64 *)values)[indx];
708 else if (vtype == G_TYPE_CHAR)
709 fval = ((gchar *)values)[indx];
710 else if (vtype == G_TYPE_UCHAR)
711 fval = ((guchar *)values)[indx];
712
713 if (i==0)
714 {
715 minval = maxval = fval;
716 }
717 else
718 {
719 if (fval < minval) minval = fval;
720 if (fval > maxval) maxval = fval;
721 }
722
723 /* handle the wrap-around (ring buffer) issue using modulus. for efficiency, don't do this for non-wraparound cases. */
724 /* note this allows multiple wrap-arounds. One could hold a single cycle of a sine wave, and plot a continuous wave */
725 /* This can be optimized using pointers later */
726 if (i + start > maxlen)
727 indx = ((i + start) % maxlen) * stride;
728 else
729 indx += stride;
730 } while (++i < len);
731
732 *min_x = minval;
733 *max_x = maxval;
734
735 values = priv->Y1;
736 vtype = priv->ytype;
737 start = priv->y1start;
738 stride = priv->y1stride;
739
740 indx = start * stride;
741 i = 0;
742 do {
743 if (vtype == G_TYPE_FLOAT)
744 fval = ((gfloat *)values)[indx];
745 else if (vtype == G_TYPE_DOUBLE)
746 fval = ((gdouble *)values)[indx];
747 else if (vtype == G_TYPE_INT)
748 fval = ((gint *)values)[indx];
749 else if (vtype == G_TYPE_UINT)
750 fval = ((guint *)values)[indx];
751 else if (vtype == G_TYPE_LONG)
752 fval = ((glong *)values)[indx];
753 else if (vtype == G_TYPE_ULONG)
754 fval = ((gulong *)values)[indx];
755 else if (vtype == G_TYPE_INT64)
756 fval = ((gint64 *)values)[indx];
757 else if (vtype == G_TYPE_UINT64)
758 fval = ((guint64 *)values)[indx];
759 else if (vtype == G_TYPE_CHAR)
760 fval = ((gchar *)values)[indx];
761 else if (vtype == G_TYPE_UCHAR)
762 fval = ((guchar *)values)[indx];
763
764 if (i==0) /* yes putting this check inside the loop is inefficient, but it makes the code simpler */
765 {
766 minval = maxval = fval;
767 }
768 else
769 {
770 if (fval < minval) minval = fval;
771 if (fval > maxval) maxval = fval;
772 }
773
774 /* handle the wrap-around (ring buffer) issue using modulus. for efficiency, don't do this for non-wraparound cases. */
775 /* note this allows multiple wrap-arounds. One could hold a single cycle of a sine wave, and plot a continuous wave */
776 /* This can be optimized using pointers later */
777 if (i + start > maxlen)
778 indx = ((i + start) % maxlen) * stride;
779 else
780 indx += stride;
781 } while (++i < len);
782
783 values = priv->Y2;
784 start = priv->y2start;
785 stride = priv->y2stride;
786
787 indx = start * stride;
788 i = 0;
789 do {
790 if (vtype == G_TYPE_FLOAT)
791 fval = ((gfloat *)values)[indx];
792 else if (vtype == G_TYPE_DOUBLE)
793 fval = ((gdouble *)values)[indx];
794 else if (vtype == G_TYPE_INT)
795 fval = ((gint *)values)[indx];
796 else if (vtype == G_TYPE_UINT)
797 fval = ((guint *)values)[indx];
798 else if (vtype == G_TYPE_LONG)
799 fval = ((glong *)values)[indx];
800 else if (vtype == G_TYPE_ULONG)
801 fval = ((gulong *)values)[indx];
802 else if (vtype == G_TYPE_INT64)
803 fval = ((gint64 *)values)[indx];
804 else if (vtype == G_TYPE_UINT64)
805 fval = ((guint64 *)values)[indx];
806 else if (vtype == G_TYPE_CHAR)
807 fval = ((gchar *)values)[indx];
808 else if (vtype == G_TYPE_UCHAR)
809 fval = ((guchar *)values)[indx];
810
811 /* Note that this is different from where we checked Y1 */
812 if (fval < minval) minval = fval;
813 if (fval > maxval) maxval = fval;
814
815 /* handle the wrap-around (ring buffer) issue using modulus. for efficiency, don't do this for non-wraparound cases. */
816 /* note this allows multiple wrap-arounds. One could hold a single cycle of a sine wave, and plot a continuous wave */
817 /* This can be optimized using pointers later */
818 if (i + start > maxlen)
819 indx = ((i + start) % maxlen) * stride;
820 else
821 indx += stride;
822 } while (++i < len);
823
824 *min_y = minval;
825 *max_y = maxval;
826
827 return 0;
828 }