vdk 2.4.0
|
00001 /* GtkDatabox - An extension to the gtk+ library 00002 * Copyright (C) 1998 - 2002 Dr. Roland Bock 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public License 00006 * as published by the Free Software Foundation; either version 2.1 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 */ 00018 /* gtkdatabox.h */ 00019 00020 #ifndef __GTK_DATABOX_H__ 00021 #define __GTK_DATABOX_H__ 00022 00023 00024 #include <gdk/gdk.h> 00025 #include <gtk/gtkvbox.h> /* We need this to pack a table containing the data, */ 00026 /* scrollbars, rulers etc.*/ 00027 00028 00029 #ifdef __cplusplus 00030 extern "C" 00031 { 00032 #endif /* __cplusplus */ 00033 00034 #define GTK_TYPE_DATABOX (gtk_databox_get_type ()) 00035 #define GTK_DATABOX(obj) GTK_CHECK_CAST (obj, gtk_databox_get_type (), GtkDatabox) 00036 #define GTK_DATABOX_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_databox_get_type (), GtkDataboxClass) 00037 #define GTK_IS_DATABOX(obj) GTK_CHECK_TYPE (obj, gtk_databox_get_type ()) 00038 #define GTK_IS_DATABOX_CLASS(klass) GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_DATABOX) 00039 #define GTK_DATABOX_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_DATABOX, GtkDataboxClass)) 00040 00041 00042 typedef struct _GtkDatabox GtkDatabox; 00043 typedef struct _GtkDataboxClass GtkDataboxClass; 00044 00045 typedef enum /* Types of data display */ 00046 { 00047 GTK_DATABOX_NOT_DISPLAYED = 0, /* hidden */ 00048 GTK_DATABOX_POINTS, /* Simple points or rectangles */ 00049 GTK_DATABOX_LINES, /* Lines connecting data points */ 00050 GTK_DATABOX_BARS, /* Vertical bars from X axis to data points */ 00051 GTK_DATABOX_CROSS_SIMPLE, /* X and Y axis */ 00052 GTK_DATABOX_GRID, /* Grid like in an oscilloscope */ 00053 } GtkDataboxDataType; 00054 00055 typedef struct 00056 { 00057 gint x; 00058 gint y; 00059 } GtkDataboxCoord; /* Pixel coordinates */ 00060 00061 typedef struct 00062 { 00063 gfloat x; 00064 gfloat y; 00065 } GtkDataboxValue; /* Data coordinates */ 00066 00067 struct _GtkDatabox 00068 { 00069 GtkVBox box; 00070 00071 /* This list contains the data sets that are to be drawn. */ 00072 GList *data; 00073 00074 /* Table containing the display, scrollbars and rulers */ 00075 GtkWidget *table; 00076 00077 /* This is where we display the data */ 00078 GtkWidget *draw; 00079 00080 /* The rulers */ 00081 GtkWidget *hrule; 00082 GtkWidget *vrule; 00083 00084 /* The scrollbars and their adjustments */ 00085 GtkWidget *hscroll; 00086 GtkWidget *vscroll; 00087 GtkAdjustment *adjX; 00088 GtkAdjustment *adjY; 00089 00090 /* The pixmap for double buffering */ 00091 GdkPixmap *pixmap; 00092 00093 /* A number of flags (zoom enabled/disabled, etc.) */ 00094 /* FIXME selection_flag should be included here */ 00095 gulong flags; 00096 00097 /* Is there an active selection? It is safe to let this untouched. */ 00098 gboolean selection_flag; 00099 00100 /* Number of values of the largest data set currently in the databox */ 00101 guint max_points; 00102 00103 /* An array of max_points points */ 00104 GdkPoint *points; 00105 00106 /* The selection box is drawn using this gc. You can manipulate it 00107 * by using 00108 * gtk_databox_show_selection_filled or 00109 * gtk_databox_hide_selection_filled 00110 */ 00111 GdkGC *select_gc; 00112 00113 /* Size (in pixel) of the display area */ 00114 GtkDataboxCoord size; 00115 00116 /* Position (pixel) of the last mouse click */ 00117 GtkDataboxCoord marked; 00118 00119 /* During creation of a selection box this is the second corner of 00120 * the box, opposed to marked 00121 */ 00122 GtkDataboxCoord select; 00123 00124 /* The extrema of the data values. These are calculated when 00125 * gtkdatabox_rescale is called. You can set them directly via 00126 * gtkdatabox_rescale_with_values. 00127 */ 00128 GtkDataboxValue min; 00129 GtkDataboxValue max; 00130 00131 /* The visible extrema in the top-left and bottom-right corner. 00132 * These are influenced by zooming and scrolling. 00133 */ 00134 GtkDataboxValue top_left; 00135 GtkDataboxValue bottom_right; 00136 00137 /* Factor for translation of data values to screen coordinates 00138 * and vice versa. This is influenced by zooming and the extrema of 00139 * the data. You can use gtk_databox_rescale_with_values for 00140 * manipulating the extrema. 00141 */ 00142 GtkDataboxValue factor; 00143 00144 /* If we zoom to far into the data, we will get funny results, because 00145 * of overflow effects. Therefore zooming has to be limited. 00146 * The default zoom limit is 0.01, meaning that you can magnify your 00147 * data by a factor of 100. 00148 * Use gtk_set_zoom_limit to change this value. 00149 */ 00150 gfloat zoom_limit; 00151 }; 00152 00153 struct _GtkDataboxClass 00154 { 00155 GtkVBoxClass parent_class; 00156 00157 void (*gtk_databox) (GtkDatabox * box); 00158 00159 /* Funktion pointers for signals, needed (mostly) for gtk-- wrapper */ 00160 /* For use of the signals, see "examples/signals.c" */ 00161 void (*gtk_databox_zoomed) (GtkDatabox * box, 00162 GtkDataboxValue * top_left, 00163 GtkDataboxValue * bottom_right); 00164 void (*gtk_databox_marked) (GtkDatabox * box, GtkDataboxCoord * marked); 00165 void (*gtk_databox_selection_started) (GtkDatabox * box, 00166 GtkDataboxCoord * marked); 00167 void (*gtk_databox_selection_changed) (GtkDatabox * box, 00168 GtkDataboxCoord * marked, 00169 GtkDataboxCoord * select); 00170 void (*gtk_databox_selection_stopped) (GtkDatabox * box, 00171 GtkDataboxCoord * marked, 00172 GtkDataboxCoord * select); 00173 void (*gtk_databox_selection_cancelled) (GtkDatabox * box); 00174 00175 }; 00176 00177 guint gtk_databox_get_type (void); 00178 00179 /* Before you can do much useful with the rest of the functions you will 00180 need a GtkDatabox. The following function creates one for you :-) */ 00181 GtkWidget *gtk_databox_new (void); 00182 00183 /* When you have added new data or changed "old" data, you have to tell 00184 GtkDatabox to redraw the data, otherwise you will see no changes. 00185 This might be the most often called function... */ 00186 void gtk_databox_redraw (GtkDatabox * box); 00187 00188 /* The next few functions allow you to make your data known to 00189 the GtkDatabox. After all, the GtkDatabox is nothing without 00190 your data :-) */ 00191 00192 /* This function is used to add two arrays of float values to the 00193 list of data of the GtkDatabox. One array contains the X values 00194 the other contains the Y values of your data points. 00195 GtkDatabox will not copy or backup the data. You have to make sure 00196 that X and Y pointers will stay valid until you remove the data 00197 from the GtkDatabox or until you destroy the GtkDatabox itself. 00198 00199 You also have to define the color, size/width and type of the data 00200 for display. See the GtkDataboxDataType enumeration for the type options. 00201 If you want to add a grid or coordinate system, choose the appropriate 00202 type and use any float arrays you happen to have, because the data is 00203 obsolete in thes cases. Configuration of the grid is done with 00204 the gtk_databox_data_set_grid_config function. 00205 00206 After adding data you may need to rescale the GtkDatabox thus assuring 00207 that your data will be visible on the screen. Use 00208 gtk_databox_rescale and gtk_databox_rescale_with_values for this 00209 purpose. 00210 00211 The return value is the internal index of the data. 00212 */ 00213 gint gtk_databox_data_add_x_y (GtkDatabox * box, guint length, gfloat * X, 00214 gfloat * Y, GdkColor color, 00215 GtkDataboxDataType type, guint dot_size); 00216 00217 /* This function is used for adding another set of data to your 00218 GtkDatabox that has the same Y values as one of the added 00219 data sets but has different X values. 00220 00221 See gtk_databox_data_add_x_y for additional information. */ 00222 gint gtk_databox_data_add_x (GtkDatabox * box, guint length, gfloat * X, 00223 gint shared_Y_index, GdkColor color, 00224 GtkDataboxDataType type, guint dot_size); 00225 00226 /* This function is used for adding another set of data to your 00227 GtkDatabox that has the same X values as one of the added 00228 data sets but has different Y values. 00229 00230 See gtk_databox_data_add_x_y for additional information. */ 00231 gint gtk_databox_data_add_y (GtkDatabox * box, guint length, gfloat * Y, 00232 gint shared_X_index, GdkColor color, 00233 GtkDataboxDataType type, guint dot_size); 00234 00235 /* The next two funtions are used to remove data sets from the 00236 GtkDatabox. They remove the set with the given index or all sets. 00237 When removing only one set, X or Y data that has been used for 00238 several data sets will be taken care of. */ 00239 gint gtk_databox_data_remove (GtkDatabox * box, gint index); 00240 gint gtk_databox_data_remove_all (GtkDatabox * box); 00241 00242 /* In contrast to the two functions above the following functions not 00243 only erase the data references from GtkDatabox's memory, the data 00244 arrays are also freed. */ 00245 gint gtk_databox_data_destroy (GtkDatabox * box, gint index); 00246 gint gtk_databox_data_destroy_all (GtkDatabox * box); 00247 00248 /* The following two functions are used to adjust the GtkDatabox to 00249 your data. By default, the GtkDatabox will display data in a range 00250 of (-0.5, -0.5) to (1.5, 1.5). Typically you data will not fit well into 00251 this range. 00252 00253 By calling gtk_databox_rescale the GtkDatabox will analyse 00254 your data and make itself fit around the data, leaving a border of 00255 a few pixels for optical reasons. 00256 00257 By calling gtk_databox_rescale_with_values you can define the 00258 range of visible data yourself. This is helpful when your data 00259 will be undergoing changes but you know the theoretical maximum 00260 minimum values. In that case you can once rescale the GtkDatabox with 00261 these extrema and your data will always fit in (that is, if your 00262 theory is correct). Defining the extrema yourself is also useful 00263 if your data contains a few "wrong" values that are far away from 00264 the interesting parts.*/ 00265 void gtk_databox_rescale (GtkDatabox * box); 00266 void gtk_databox_rescale_with_values (GtkDatabox * box, 00267 GtkDataboxValue min, 00268 GtkDataboxValue max); 00269 00270 /* Use the following functions to get or set the color and type 00271 of your displayed data. The index is the return value of 00272 gtk_databox_data_add_x_y or similar function. */ 00273 gint gtk_databox_data_get_color (GtkDatabox * box, gint index, 00274 GdkColor * color); 00275 gint gtk_databox_data_set_color (GtkDatabox * box, gint index, 00276 GdkColor color); 00277 gint gtk_databox_data_get_type (GtkDatabox * box, gint index, 00278 GtkDataboxDataType * type, 00279 guint * dot_size); 00280 gint gtk_databox_data_set_type (GtkDatabox * box, gint index, 00281 GtkDataboxDataType type, guint dot_size); 00282 00283 /* The next two functions do nothing useful unless the data type is GRID. 00284 Adding data and using it as grid or coordinate cross afterwards looks 00285 crazy at first, but it has a lot of benefits, like GC management (that 00286 is one of my own benefits) or being able to make sure that you 00287 have your grid below, between or on top of the rest of the data (that is 00288 supposed to be your benefit...) */ 00289 gint gtk_databox_data_get_grid_config (GtkDatabox * box, gint index, 00290 guint * hlines, guint * vlines); 00291 gint gtk_databox_data_set_grid_config (GtkDatabox * box, gint index, 00292 guint hlines, guint vlines); 00293 00294 /* The following function calculates the "data coordinates" for 00295 a given pair of pixel coordinates. The results of this 00296 calculation depend on your current zoom/scroll status, and on 00297 the last rescale action, see gtk_databox_rescale and 00298 gtk_databox_rescale_with_values. */ 00299 void gtk_databox_data_get_value (GtkDatabox * box, GtkDataboxCoord coord, 00300 GtkDataboxValue * value); 00301 00302 /* Get the minimum X/Y and the maximum X/Y "data coordinates". These 00303 are the coordinates of the bottom-left and top-right corners when 00304 you zoom out completely (shift + button-3). 00305 The result depends on the last call of gtk_databox_rescale or 00306 gtk_databox_rescale_with_values */ 00307 void gtk_databox_data_get_extrema (GtkDatabox * box, GtkDataboxValue * min, 00308 GtkDataboxValue * max); 00309 /* Get the "data coordinates" (not the pixel coordinates) of the 00310 bottom-left and top-right corners of the visible data currently 00311 shown in the GtkDatabox. When zoomed out completely 00312 the result will be the same as for gtk_databox_data_get_extrema 00313 The result depends on the last call of gtk_databox_rescale or 00314 gtk_databox_rescale_with_values */ 00315 void gtk_databox_data_get_visible_extrema (GtkDatabox * box, 00316 GtkDataboxValue * min, 00317 GtkDataboxValue * max); 00318 00319 00320 /* Even you are happy with the default behaviour of the GtkDatabox 00321 you should also take a look at the following functions. 00322 They might even increase you satisfaction :-) */ 00323 00324 /* By default, the GtkDatabox will come with a pair of scrollbars and 00325 rulers. Use the following functions to get rid of them or 00326 get them back again */ 00327 00328 void gtk_databox_show_rulers (GtkDatabox * box); 00329 void gtk_databox_hide_rulers (GtkDatabox * box); 00330 void gtk_databox_show_scrollbars (GtkDatabox * box); 00331 void gtk_databox_hide_scrollbars (GtkDatabox * box); 00332 00333 00334 /* Decide whether the selection box is filled or not, the default 00335 is not filled */ 00336 void gtk_databox_show_selection_filled (GtkDatabox * box); 00337 void gtk_databox_hide_selection_filled (GtkDatabox * box); 00338 00339 /* Selection is possible as default, but you may disable that feature */ 00340 void gtk_databox_enable_selection (GtkDatabox * box); 00341 void gtk_databox_disable_selection (GtkDatabox * box); 00342 00343 /* Zooming into the data and back is enabled as default, but you 00344 can disable zooming if it makes you nervous*/ 00345 void gtk_databox_enable_zoom (GtkDatabox * box); 00346 void gtk_databox_disable_zoom (GtkDatabox * box); 00347 00348 /* When you zoom into the GtkDatabox, you might stumble over dubious 00349 effects like lines or points that are not where you would expect them 00350 to be. These are range overflow or limited precision problems. 00351 These problems are avoided if you simply do not zoom into the data ever 00352 deeped, but stop at some point. This point is the so-called 00353 zoom limit. It is a value between 0 and 1 (use other values at 00354 your own risk), the default is 0.01. It defines the smallest fraction 00355 in X and Y dimension that can be zoomed to. Thus, the default allows 00356 you to see everything enlarged by a maximum factor of 100. 00357 00358 If you think you need to play with that behaviour, use the following 00359 two functions, to get and set the zoom limit. 00360 00361 Note: Zooming in very deep might make the GtkDatabox rather slow 00362 when you are displaying your data as lines. */ 00363 void gtk_databox_set_zoom_limit (GtkDatabox * box, 00364 gfloat zoom_limit); 00365 gfloat gtk_databox_get_zoom_limit (GtkDatabox * box); 00366 00367 #ifdef __cplusplus 00368 } 00369 #endif /* __cplusplus */ 00370 00371 #endif /* __GTK_DATABOX_H__ */