gtkdatabox.h

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__ */

Generated on Fri Jan 12 14:48:27 2007 for vdk 2.4.0 by  doxygen 1.5.1