vdk 2.4.0
gtkdatabox.h
1/* GtkDatabox - An extension to the gtk+ library
2 * Copyright (C) 1998 - 2002 Dr. Roland Bock
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation; either version 2.1
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18/* gtkdatabox.h */
19
20#ifndef __GTK_DATABOX_H__
21#define __GTK_DATABOX_H__
22
23
24#include <gdk/gdk.h>
25#include <gtk/gtkvbox.h> /* We need this to pack a table containing the data, */
26 /* scrollbars, rulers etc.*/
27
28
29#ifdef __cplusplus
30extern "C"
31{
32#endif /* __cplusplus */
33
34#define GTK_TYPE_DATABOX (gtk_databox_get_type ())
35#define GTK_DATABOX(obj) GTK_CHECK_CAST (obj, gtk_databox_get_type (), GtkDatabox)
36#define GTK_DATABOX_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_databox_get_type (), GtkDataboxClass)
37#define GTK_IS_DATABOX(obj) GTK_CHECK_TYPE (obj, gtk_databox_get_type ())
38#define GTK_IS_DATABOX_CLASS(klass) GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_DATABOX)
39#define GTK_DATABOX_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_DATABOX, GtkDataboxClass))
40
41
42 typedef struct _GtkDatabox GtkDatabox;
43 typedef struct _GtkDataboxClass GtkDataboxClass;
44
45 typedef enum /* Types of data display */
46 {
47 GTK_DATABOX_NOT_DISPLAYED = 0, /* hidden */
48 GTK_DATABOX_POINTS, /* Simple points or rectangles */
49 GTK_DATABOX_LINES, /* Lines connecting data points */
50 GTK_DATABOX_BARS, /* Vertical bars from X axis to data points */
51 GTK_DATABOX_CROSS_SIMPLE, /* X and Y axis */
52 GTK_DATABOX_GRID, /* Grid like in an oscilloscope */
53 } GtkDataboxDataType;
54
55 typedef struct
56 {
57 gint x;
58 gint y;
59 } GtkDataboxCoord; /* Pixel coordinates */
60
61 typedef struct
62 {
63 gfloat x;
64 gfloat y;
65 } GtkDataboxValue; /* Data coordinates */
66
67 struct _GtkDatabox
68 {
69 GtkVBox box;
70
71 /* This list contains the data sets that are to be drawn. */
72 GList *data;
73
74 /* Table containing the display, scrollbars and rulers */
75 GtkWidget *table;
76
77 /* This is where we display the data */
78 GtkWidget *draw;
79
80 /* The rulers */
81 GtkWidget *hrule;
82 GtkWidget *vrule;
83
84 /* The scrollbars and their adjustments */
85 GtkWidget *hscroll;
86 GtkWidget *vscroll;
87 GtkAdjustment *adjX;
88 GtkAdjustment *adjY;
89
90 /* The pixmap for double buffering */
91 GdkPixmap *pixmap;
92
93 /* A number of flags (zoom enabled/disabled, etc.) */
94 /* FIXME selection_flag should be included here */
95 gulong flags;
96
97 /* Is there an active selection? It is safe to let this untouched. */
98 gboolean selection_flag;
99
100 /* Number of values of the largest data set currently in the databox */
101 guint max_points;
102
103 /* An array of max_points points */
104 GdkPoint *points;
105
106 /* The selection box is drawn using this gc. You can manipulate it
107 * by using
108 * gtk_databox_show_selection_filled or
109 * gtk_databox_hide_selection_filled
110 */
111 GdkGC *select_gc;
112
113 /* Size (in pixel) of the display area */
114 GtkDataboxCoord size;
115
116 /* Position (pixel) of the last mouse click */
117 GtkDataboxCoord marked;
118
119 /* During creation of a selection box this is the second corner of
120 * the box, opposed to marked
121 */
122 GtkDataboxCoord select;
123
124 /* The extrema of the data values. These are calculated when
125 * gtkdatabox_rescale is called. You can set them directly via
126 * gtkdatabox_rescale_with_values.
127 */
128 GtkDataboxValue min;
129 GtkDataboxValue max;
130
131 /* The visible extrema in the top-left and bottom-right corner.
132 * These are influenced by zooming and scrolling.
133 */
134 GtkDataboxValue top_left;
135 GtkDataboxValue bottom_right;
136
137 /* Factor for translation of data values to screen coordinates
138 * and vice versa. This is influenced by zooming and the extrema of
139 * the data. You can use gtk_databox_rescale_with_values for
140 * manipulating the extrema.
141 */
142 GtkDataboxValue factor;
143
144 /* If we zoom to far into the data, we will get funny results, because
145 * of overflow effects. Therefore zooming has to be limited.
146 * The default zoom limit is 0.01, meaning that you can magnify your
147 * data by a factor of 100.
148 * Use gtk_set_zoom_limit to change this value.
149 */
150 gfloat zoom_limit;
151 };
152
153 struct _GtkDataboxClass
154 {
155 GtkVBoxClass parent_class;
156
157 void (*gtk_databox) (GtkDatabox * box);
158
159 /* Funktion pointers for signals, needed (mostly) for gtk-- wrapper */
160 /* For use of the signals, see "examples/signals.c" */
161 void (*gtk_databox_zoomed) (GtkDatabox * box,
162 GtkDataboxValue * top_left,
163 GtkDataboxValue * bottom_right);
164 void (*gtk_databox_marked) (GtkDatabox * box, GtkDataboxCoord * marked);
165 void (*gtk_databox_selection_started) (GtkDatabox * box,
166 GtkDataboxCoord * marked);
167 void (*gtk_databox_selection_changed) (GtkDatabox * box,
168 GtkDataboxCoord * marked,
169 GtkDataboxCoord * select);
170 void (*gtk_databox_selection_stopped) (GtkDatabox * box,
171 GtkDataboxCoord * marked,
172 GtkDataboxCoord * select);
173 void (*gtk_databox_selection_cancelled) (GtkDatabox * box);
174
175 };
176
177 guint gtk_databox_get_type (void);
178
179/* Before you can do much useful with the rest of the functions you will
180 need a GtkDatabox. The following function creates one for you :-) */
181 GtkWidget *gtk_databox_new (void);
182
183/* When you have added new data or changed "old" data, you have to tell
184 GtkDatabox to redraw the data, otherwise you will see no changes.
185 This might be the most often called function... */
186 void gtk_databox_redraw (GtkDatabox * box);
187
188/* The next few functions allow you to make your data known to
189 the GtkDatabox. After all, the GtkDatabox is nothing without
190 your data :-) */
191
192/* This function is used to add two arrays of float values to the
193 list of data of the GtkDatabox. One array contains the X values
194 the other contains the Y values of your data points.
195 GtkDatabox will not copy or backup the data. You have to make sure
196 that X and Y pointers will stay valid until you remove the data
197 from the GtkDatabox or until you destroy the GtkDatabox itself.
198
199 You also have to define the color, size/width and type of the data
200 for display. See the GtkDataboxDataType enumeration for the type options.
201 If you want to add a grid or coordinate system, choose the appropriate
202 type and use any float arrays you happen to have, because the data is
203 obsolete in thes cases. Configuration of the grid is done with
204 the gtk_databox_data_set_grid_config function.
205
206 After adding data you may need to rescale the GtkDatabox thus assuring
207 that your data will be visible on the screen. Use
208 gtk_databox_rescale and gtk_databox_rescale_with_values for this
209 purpose.
210
211 The return value is the internal index of the data.
212 */
213 gint gtk_databox_data_add_x_y (GtkDatabox * box, guint length, gfloat * X,
214 gfloat * Y, GdkColor color,
215 GtkDataboxDataType type, guint dot_size);
216
217/* This function is used for adding another set of data to your
218 GtkDatabox that has the same Y values as one of the added
219 data sets but has different X values.
220
221 See gtk_databox_data_add_x_y for additional information. */
222 gint gtk_databox_data_add_x (GtkDatabox * box, guint length, gfloat * X,
223 gint shared_Y_index, GdkColor color,
224 GtkDataboxDataType type, guint dot_size);
225
226/* This function is used for adding another set of data to your
227 GtkDatabox that has the same X values as one of the added
228 data sets but has different Y values.
229
230 See gtk_databox_data_add_x_y for additional information. */
231 gint gtk_databox_data_add_y (GtkDatabox * box, guint length, gfloat * Y,
232 gint shared_X_index, GdkColor color,
233 GtkDataboxDataType type, guint dot_size);
234
235/* The next two funtions are used to remove data sets from the
236 GtkDatabox. They remove the set with the given index or all sets.
237 When removing only one set, X or Y data that has been used for
238 several data sets will be taken care of. */
239 gint gtk_databox_data_remove (GtkDatabox * box, gint index);
240 gint gtk_databox_data_remove_all (GtkDatabox * box);
241
242/* In contrast to the two functions above the following functions not
243 only erase the data references from GtkDatabox's memory, the data
244 arrays are also freed. */
245 gint gtk_databox_data_destroy (GtkDatabox * box, gint index);
246 gint gtk_databox_data_destroy_all (GtkDatabox * box);
247
248/* The following two functions are used to adjust the GtkDatabox to
249 your data. By default, the GtkDatabox will display data in a range
250 of (-0.5, -0.5) to (1.5, 1.5). Typically you data will not fit well into
251 this range.
252
253 By calling gtk_databox_rescale the GtkDatabox will analyse
254 your data and make itself fit around the data, leaving a border of
255 a few pixels for optical reasons.
256
257 By calling gtk_databox_rescale_with_values you can define the
258 range of visible data yourself. This is helpful when your data
259 will be undergoing changes but you know the theoretical maximum
260 minimum values. In that case you can once rescale the GtkDatabox with
261 these extrema and your data will always fit in (that is, if your
262 theory is correct). Defining the extrema yourself is also useful
263 if your data contains a few "wrong" values that are far away from
264 the interesting parts.*/
265 void gtk_databox_rescale (GtkDatabox * box);
266 void gtk_databox_rescale_with_values (GtkDatabox * box,
267 GtkDataboxValue min,
268 GtkDataboxValue max);
269
270/* Use the following functions to get or set the color and type
271 of your displayed data. The index is the return value of
272 gtk_databox_data_add_x_y or similar function. */
273 gint gtk_databox_data_get_color (GtkDatabox * box, gint index,
274 GdkColor * color);
275 gint gtk_databox_data_set_color (GtkDatabox * box, gint index,
276 GdkColor color);
277 gint gtk_databox_data_get_type (GtkDatabox * box, gint index,
278 GtkDataboxDataType * type,
279 guint * dot_size);
280 gint gtk_databox_data_set_type (GtkDatabox * box, gint index,
281 GtkDataboxDataType type, guint dot_size);
282
283/* The next two functions do nothing useful unless the data type is GRID.
284 Adding data and using it as grid or coordinate cross afterwards looks
285 crazy at first, but it has a lot of benefits, like GC management (that
286 is one of my own benefits) or being able to make sure that you
287 have your grid below, between or on top of the rest of the data (that is
288 supposed to be your benefit...) */
289 gint gtk_databox_data_get_grid_config (GtkDatabox * box, gint index,
290 guint * hlines, guint * vlines);
291 gint gtk_databox_data_set_grid_config (GtkDatabox * box, gint index,
292 guint hlines, guint vlines);
293
294/* The following function calculates the "data coordinates" for
295 a given pair of pixel coordinates. The results of this
296 calculation depend on your current zoom/scroll status, and on
297 the last rescale action, see gtk_databox_rescale and
298 gtk_databox_rescale_with_values. */
299 void gtk_databox_data_get_value (GtkDatabox * box, GtkDataboxCoord coord,
300 GtkDataboxValue * value);
301
302/* Get the minimum X/Y and the maximum X/Y "data coordinates". These
303 are the coordinates of the bottom-left and top-right corners when
304 you zoom out completely (shift + button-3).
305 The result depends on the last call of gtk_databox_rescale or
306 gtk_databox_rescale_with_values */
307 void gtk_databox_data_get_extrema (GtkDatabox * box, GtkDataboxValue * min,
308 GtkDataboxValue * max);
309/* Get the "data coordinates" (not the pixel coordinates) of the
310 bottom-left and top-right corners of the visible data currently
311 shown in the GtkDatabox. When zoomed out completely
312 the result will be the same as for gtk_databox_data_get_extrema
313 The result depends on the last call of gtk_databox_rescale or
314 gtk_databox_rescale_with_values */
315 void gtk_databox_data_get_visible_extrema (GtkDatabox * box,
316 GtkDataboxValue * min,
317 GtkDataboxValue * max);
318
319
320/* Even you are happy with the default behaviour of the GtkDatabox
321 you should also take a look at the following functions.
322 They might even increase you satisfaction :-) */
323
324/* By default, the GtkDatabox will come with a pair of scrollbars and
325 rulers. Use the following functions to get rid of them or
326 get them back again */
327
328 void gtk_databox_show_rulers (GtkDatabox * box);
329 void gtk_databox_hide_rulers (GtkDatabox * box);
330 void gtk_databox_show_scrollbars (GtkDatabox * box);
331 void gtk_databox_hide_scrollbars (GtkDatabox * box);
332
333
334/* Decide whether the selection box is filled or not, the default
335 is not filled */
336 void gtk_databox_show_selection_filled (GtkDatabox * box);
337 void gtk_databox_hide_selection_filled (GtkDatabox * box);
338
339/* Selection is possible as default, but you may disable that feature */
340 void gtk_databox_enable_selection (GtkDatabox * box);
341 void gtk_databox_disable_selection (GtkDatabox * box);
342
343/* Zooming into the data and back is enabled as default, but you
344 can disable zooming if it makes you nervous*/
345 void gtk_databox_enable_zoom (GtkDatabox * box);
346 void gtk_databox_disable_zoom (GtkDatabox * box);
347
348/* When you zoom into the GtkDatabox, you might stumble over dubious
349 effects like lines or points that are not where you would expect them
350 to be. These are range overflow or limited precision problems.
351 These problems are avoided if you simply do not zoom into the data ever
352 deeped, but stop at some point. This point is the so-called
353 zoom limit. It is a value between 0 and 1 (use other values at
354 your own risk), the default is 0.01. It defines the smallest fraction
355 in X and Y dimension that can be zoomed to. Thus, the default allows
356 you to see everything enlarged by a maximum factor of 100.
357
358 If you think you need to play with that behaviour, use the following
359 two functions, to get and set the zoom limit.
360
361 Note: Zooming in very deep might make the GtkDatabox rather slow
362 when you are displaying your data as lines. */
363 void gtk_databox_set_zoom_limit (GtkDatabox * box,
364 gfloat zoom_limit);
365 gfloat gtk_databox_get_zoom_limit (GtkDatabox * box);
366
367#ifdef __cplusplus
368}
369#endif /* __cplusplus */
370
371#endif /* __GTK_DATABOX_H__ */