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
30 extern "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__ */