• Main Page
  • Related Pages
  • Modules
  • Classes
  • Files
  • File List
  • File Members

Fl_Table.H

00001 //
00002 // "$Id$"
00003 //
00004 // Fl_Table -- A table widget
00005 //
00006 // Copyright 2002 by Greg Ercolano.
00007 // Copyright (c) 2004 O'ksi'D
00008 //
00009 // This library is free software. Distribution and use rights are outlined in
00010 // the file "COPYING" which should have been included with this file.  If this
00011 // file is missing or damaged, see the license at:
00012 //
00013 //     http://www.fltk.org/COPYING.php
00014 //
00015 // Please report all bugs and problems on the following page:
00016 //
00017 //     http://www.fltk.org/str.php
00018 //
00019 
00020 #ifndef _FL_TABLE_H
00021 #define _FL_TABLE_H
00022 
00023 #include <sys/types.h>
00024 #include <string.h>             // memcpy
00025 #ifdef WIN32
00026 #include <malloc.h>             // WINDOWS: malloc/realloc
00027 #else /*WIN32*/
00028 #include <stdlib.h>             // UNIX: malloc/realloc
00029 #endif /*WIN32*/
00030 
00031 #include <FL/Fl.H>
00032 #include <FL/Fl_Group.H>
00033 #include <FL/Fl_Scroll.H>
00034 #include <FL/Fl_Box.H>
00035 #include <FL/Fl_Scrollbar.H>
00036 
00170 class FL_EXPORT Fl_Table : public Fl_Group {
00171 public:
00177   enum TableContext {
00178     CONTEXT_NONE       = 0,     
00179     CONTEXT_STARTPAGE  = 0x01,  
00180     CONTEXT_ENDPAGE    = 0x02,  
00181     CONTEXT_ROW_HEADER = 0x04,  
00182     CONTEXT_COL_HEADER = 0x08,  
00183     CONTEXT_CELL       = 0x10,  
00184     CONTEXT_TABLE      = 0x20,  
00185     CONTEXT_RC_RESIZE  = 0x40   
00186   };
00187   
00188 private:
00189   int _rows, _cols;     // total rows/cols
00190   int _row_header_w;    // width of row header
00191   int _col_header_h;    // height of column header
00192   int _row_position;    // last row_position set (not necessarily == toprow!)
00193   int _col_position;    // last col_position set (not necessarily == leftcol!)
00194   
00195   char _row_header;     // row header enabled?
00196   char _col_header;     // col header enabled?
00197   char _row_resize;     // row resizing enabled?
00198   char _col_resize;     // col resizing enabled?
00199   int _row_resize_min;  // row minimum resizing height (default=1)
00200   int _col_resize_min;  // col minimum resizing width (default=1)
00201   
00202   // OPTIMIZATION: partial row/column redraw variables
00203   int _redraw_toprow;
00204   int _redraw_botrow;
00205   int _redraw_leftcol;
00206   int _redraw_rightcol;
00207   Fl_Color _row_header_color;
00208   Fl_Color _col_header_color;
00209   
00210   int _auto_drag;
00211   int _selecting;
00212 #if FLTK_ABI_VERSION >= 10301
00213   int _scrollbar_size;
00214 #endif
00215 #if FLTK_ABI_VERSION >= 10303
00216   enum {
00217     TABCELLNAV = 1<<0,                  
00218   };
00219   unsigned int flags_;
00220 #endif
00221   
00222   // An STL-ish vector without templates
00223   class FL_EXPORT IntVector {
00224     int *arr;
00225     unsigned int _size;
00226     void init() {
00227       arr = NULL;
00228       _size = 0;
00229     }
00230     void copy(int *newarr, unsigned int newsize) {
00231       size(newsize);
00232       memcpy(arr, newarr, newsize * sizeof(int));
00233     }
00234   public:
00235     IntVector() { init(); }                                     // CTOR
00236     ~IntVector() { if ( arr ) free(arr); arr = NULL; }          // DTOR
00237     IntVector(IntVector&o) { init(); copy(o.arr, o._size); }    // COPY CTOR
00238     IntVector& operator=(IntVector&o) {                         // ASSIGN
00239       init();
00240       copy(o.arr, o._size);
00241       return(*this);
00242     }
00243     int operator[](int x) const { return(arr[x]); }
00244     int& operator[](int x) { return(arr[x]); }
00245     unsigned int size() { return(_size); }
00246     void size(unsigned int count) {
00247       if ( count != _size ) {
00248         arr = (int*)realloc(arr, count * sizeof(int));
00249         _size = count;
00250       }
00251     }
00252     int pop_back() { int tmp = arr[_size-1]; _size--; return(tmp); }
00253     void push_back(int val) { unsigned int x = _size; size(_size+1); arr[x] = val; }
00254     int back() { return(arr[_size-1]); }
00255   };
00256   
00257   IntVector _colwidths;                 // column widths in pixels
00258   IntVector _rowheights;                // row heights in pixels
00259   
00260   Fl_Cursor _last_cursor;               // last mouse cursor before changed to 'resize' cursor
00261   
00262   // EVENT CALLBACK DATA
00263   TableContext _callback_context;       // event context
00264   int _callback_row, _callback_col;     // event row/col
00265   
00266   // handle() state variables.
00267   //    Put here instead of local statics in handle(), so more
00268   //    than one Fl_Table can exist without crosstalk between them.
00269   //
00270   int _resizing_col;                    // column being dragged
00271   int _resizing_row;                    // row being dragged
00272   int _dragging_x;                      // starting x position for horiz drag
00273   int _dragging_y;                      // starting y position for vert drag
00274   int _last_row;                        // last row we FL_PUSH'ed
00275   
00276   // Redraw single cell
00277   void _redraw_cell(TableContext context, int R, int C);
00278   
00279   void _start_auto_drag();
00280   void _stop_auto_drag();
00281   void _auto_drag_cb();
00282   static void _auto_drag_cb2(void *d);
00283   
00284 protected:
00285   enum ResizeFlag {
00286     RESIZE_NONE      = 0,
00287     RESIZE_COL_LEFT  = 1,
00288     RESIZE_COL_RIGHT = 2,
00289     RESIZE_ROW_ABOVE = 3,
00290     RESIZE_ROW_BELOW = 4
00291   };
00292   
00293   int table_w, table_h;                         // table's virtual size (in pixels)
00294   int toprow, botrow, leftcol, rightcol;        // four corners of viewable table
00295   
00296   // selection
00297   int current_row, current_col;
00298   int select_row, select_col;
00299   
00300   // OPTIMIZATION: Precomputed scroll positions for the toprow/leftcol
00301   int toprow_scrollpos;
00302   int leftcol_scrollpos;
00303   
00304   // Dimensions
00305   int tix, tiy, tiw, tih;                       // data table inner dimension xywh
00306   int tox, toy, tow, toh;                       // data table outer dimension xywh
00307   int wix, wiy, wiw, wih;                       // widget inner dimension xywh
00308   
00309   Fl_Scroll *table;                             // container for child fltk widgets (if any)
00310   Fl_Scrollbar *vscrollbar;                     // vertical scrollbar
00311   Fl_Scrollbar *hscrollbar;                     // horizontal scrollbar
00312   
00313   // Fltk
00314   int handle(int e);                            // fltk handle() override
00315   
00316   // Class maintenance
00317   void recalc_dimensions();
00318   void table_resized();                         // table resized; recalc
00319   void table_scrolled();                        // table scrolled; recalc
00320   void get_bounds(TableContext context,         // return x/y/w/h bounds for context
00321                   int &X, int &Y, int &W, int &H);
00322   void change_cursor(Fl_Cursor newcursor);      // change mouse cursor to some other shape
00323   TableContext cursor2rowcol(int &R, int &C, ResizeFlag &resizeflag);
00324   // find r/c given current x/y event
00325   int find_cell(TableContext context,           // find cell's x/y/w/h given r/c
00326                 int R, int C, int &X, int &Y, int &W, int &H);
00327   int row_col_clamp(TableContext context, int &R, int &C);
00328   // clamp r/c to known universe
00329   
00440   virtual void draw_cell(TableContext context, int R=0, int C=0, 
00441                          int X=0, int Y=0, int W=0, int H=0)
00442   { }                                           // overridden by deriving class
00443   
00444   long row_scroll_position(int row);            // find scroll position of row (in pixels)
00445   long col_scroll_position(int col);            // find scroll position of col (in pixels)
00446   
00447   int is_fltk_container() {                     // does table contain fltk widgets?
00448     return( Fl_Group::children() > 3 );         // (ie. more than box and 2 scrollbars?)
00449   }
00450   
00451   static void scroll_cb(Fl_Widget*,void*);      // h/v scrollbar callback
00452   
00453   void damage_zone(int r1, int c1, int r2, int c2, int r3 = 0, int c3 = 0);
00454   
00455   void redraw_range(int topRow, int botRow, int leftCol, int rightCol) {
00456     if ( _redraw_toprow == -1 ) {
00457       // Initialize redraw range
00458       _redraw_toprow = topRow;
00459       _redraw_botrow = botRow;
00460       _redraw_leftcol = leftCol;
00461       _redraw_rightcol = rightCol;
00462     } else {
00463       // Extend redraw range
00464       if ( topRow < _redraw_toprow ) _redraw_toprow = topRow;
00465       if ( botRow > _redraw_botrow ) _redraw_botrow = botRow;
00466       if ( leftCol < _redraw_leftcol ) _redraw_leftcol = leftCol;
00467       if ( rightCol > _redraw_rightcol ) _redraw_rightcol = rightCol;
00468     }
00469     
00470     // Indicate partial redraw needed of some cells
00471     damage(FL_DAMAGE_CHILD);
00472   }
00473   
00474 public:
00480   Fl_Table(int X, int Y, int W, int H, const char *l=0);
00481   
00486   ~Fl_Table();
00487   
00493   virtual void clear() { rows(0); cols(0); table->clear(); }
00494   
00495   // \todo: add topline(), middleline(), bottomline()
00496   
00502   inline void table_box(Fl_Boxtype val) {
00503     table->box(val);
00504     table_resized();
00505   }
00506   
00510   inline Fl_Boxtype table_box( void ) {
00511     return(table->box());
00512   }
00513   
00517   virtual void rows(int val);                   // set/get number of rows
00518   
00522   inline int rows() {
00523     return(_rows);
00524   }
00525   
00529   virtual void cols(int val);                   // set/get number of columns
00530   
00534   inline int cols() {
00535     return(_cols);
00536   }
00537   
00566   inline void visible_cells(int& r1, int& r2, int& c1, int& c2) {
00567     r1 = toprow;
00568     r2 = botrow;
00569     c1 = leftcol;
00570     c2 = rightcol;
00571   } 
00572   
00577   int is_interactive_resize() {
00578     return(_resizing_row != -1 || _resizing_col != -1);
00579   } 
00580   
00584   inline int row_resize() {
00585     return(_row_resize);
00586   }
00587   
00594   void row_resize(int flag) {                   // enable row resizing
00595     _row_resize = flag;
00596   }
00597   
00601   inline int col_resize() {
00602     return(_col_resize);
00603   }
00610   void col_resize(int flag) {                   // enable col resizing
00611     _col_resize = flag;
00612   }
00613   
00617   inline int col_resize_min() {                 // column minimum resizing width
00618     return(_col_resize_min);
00619   }
00620   
00626   void col_resize_min(int val) {
00627     _col_resize_min = ( val < 1 ) ? 1 : val;
00628   } 
00629   
00633   inline int row_resize_min() {                 // column minimum resizing width
00634     return(_row_resize_min);
00635   }
00636   
00642   void row_resize_min(int val) {
00643     _row_resize_min = ( val < 1 ) ? 1 : val;
00644   }
00645   
00649   inline int row_header() {                     // set/get row header enable flag
00650     return(_row_header);
00651   }
00652   
00657   void row_header(int flag) {
00658     _row_header = flag;
00659     table_resized();
00660     redraw();
00661   }
00662   
00666   inline int col_header() {                     // set/get col header enable flag
00667     return(_col_header);
00668   }
00669   
00674   void col_header(int flag) {
00675     _col_header = flag;
00676     table_resized();
00677     redraw();
00678   }
00679   
00683   inline void col_header_height(int height) {   // set/get col header height
00684     _col_header_h = height;
00685     table_resized();
00686     redraw();
00687   }
00688   
00692   inline int col_header_height() {
00693     return(_col_header_h);
00694   }
00695   
00699   inline void row_header_width(int width) {     // set/get row header width
00700     _row_header_w = width;
00701     table_resized();
00702     redraw();
00703   }
00704   
00708   inline int row_header_width() {
00709     return(_row_header_w);
00710   }
00711   
00715   inline void row_header_color(Fl_Color val) {  // set/get row header color
00716     _row_header_color = val;
00717     redraw();
00718   }
00719   
00723   inline Fl_Color row_header_color() {
00724     return(_row_header_color);
00725   } 
00726   
00730   inline void col_header_color(Fl_Color val) {  // set/get col header color
00731     _col_header_color = val;
00732     redraw();
00733   }
00734   
00738   inline Fl_Color col_header_color() {
00739     return(_col_header_color);
00740   }
00741   
00748   void row_height(int row, int height);         // set/get row height
00749   
00753   inline int row_height(int row) {
00754     return((row<0 || row>=(int)_rowheights.size()) ? 0 : _rowheights[row]);
00755   }
00756   
00762   void col_width(int col, int width);           // set/get a column's width
00763   
00767   inline int col_width(int col) {
00768     return((col<0 || col>=(int)_colwidths.size()) ? 0 : _colwidths[col]);
00769   }
00770   
00775   void row_height_all(int height) {             // set all row/col heights
00776     for ( int r=0; r<rows(); r++ ) {
00777       row_height(r, height);
00778     }
00779   }
00780   
00785   void col_width_all(int width) {
00786     for ( int c=0; c<cols(); c++ ) {
00787       col_width(c, width);
00788     }
00789   }
00790   
00794   void row_position(int row);                   // set/get table's current scroll position
00795   
00799   void col_position(int col);
00800   
00804   int row_position() {                          // current row position
00805     return(_row_position);
00806   }
00807   
00811   int col_position() {                          // current col position
00812     return(_col_position);
00813   }
00814   
00820   inline void top_row(int row) {                // set/get top row (deprecated)
00821     row_position(row);
00822   }
00823   
00828   inline int top_row() {
00829     return(row_position());
00830   }
00831   int is_selected(int r, int c);                // selected cell
00832   void get_selection(int &row_top, int &col_left, int &row_bot, int &col_right);
00833   void set_selection(int row_top, int col_left, int row_bot, int col_right);
00834   int move_cursor(int R, int C, int shiftselect);
00835   int move_cursor(int R, int C);
00836   
00840   void resize(int X, int Y, int W, int H);      // fltk resize() override
00841   void draw(void);                              // fltk draw() override
00842   
00843   // This crashes sortapp() during init.
00844   //  void box(Fl_Boxtype val) {
00845   //    Fl_Group::box(val);
00846   //    if ( table ) {
00847   //      resize(x(), y(), w(), h());
00848   //    }
00849   //  }
00850   //  Fl_Boxtype box(void) const {
00851   //    return(Fl_Group::box());
00852   //  }
00853   
00854   // Child group
00855   void init_sizes() {
00856     table->init_sizes();
00857     table->redraw();
00858   }
00859   void add(Fl_Widget& wgt) {
00860     table->add(wgt);
00861     if ( table->children() > 2 ) {
00862       table->show();
00863     } else {
00864       table->hide();
00865     } 
00866   }
00867   void add(Fl_Widget* wgt) {
00868     add(*wgt);
00869   }
00870   void insert(Fl_Widget& wgt, int n) {
00871     table->insert(wgt,n);
00872   }
00873   void insert(Fl_Widget& wgt, Fl_Widget* w2) {
00874     table->insert(wgt,w2);
00875   }
00876   void remove(Fl_Widget& wgt) {
00877     table->remove(wgt);
00878   }
00879   void begin() {
00880     table->begin();
00881   }
00882   void end() {
00883     table->end();
00884     // HACK: Avoid showing Fl_Scroll; seems to erase screen
00885     //       causing unnecessary flicker, even if its box() is FL_NO_BOX.
00886     //
00887     if ( table->children() > 2 ) {
00888       table->show();
00889     } else {
00890       table->hide();
00891     } 
00892     Fl_Group::current(Fl_Group::parent());
00893   }
00894   Fl_Widget * const *array() {
00895     return(table->array());
00896   }
00897   
00912   Fl_Widget *child(int n) const {
00913     return(table->child(n));
00914   }
00915   
00924   int children() const {
00925     return(table->children()-2);    // -2: skip Fl_Scroll's h/v scrollbar widgets
00926   }
00927   int find(const Fl_Widget *wgt) const {
00928     return(table->find(wgt));
00929   }
00930   int find(const Fl_Widget &wgt) const {
00931     return(table->find(wgt));
00932   } 
00933   // CALLBACKS
00934   
00940   int callback_row() {
00941     return(_callback_row);
00942   }
00943   
00949   int callback_col() {
00950     return(_callback_col);
00951   }
00952   
00958   TableContext callback_context() {
00959     return(_callback_context);
00960   }
00961   
00962   void do_callback(TableContext context, int row, int col) {
00963     _callback_context = context;
00964     _callback_row = row;
00965     _callback_col = col;
00966     Fl_Widget::do_callback();
00967   }
00968   
00969 #ifdef FL_DOXYGEN
00970 
00998   void when(Fl_When flags);
00999 #endif
01000   
01001 #ifdef FL_DOXYGEN
01002 
01079   void callback(Fl_Widget*, void*);
01080 #endif
01081 
01082 #if FLTK_ABI_VERSION >= 10301
01083   // NEW
01093   int scrollbar_size() const {
01094       return(_scrollbar_size);
01095   }
01114   void scrollbar_size(int newSize) {
01115       if ( newSize != _scrollbar_size ) redraw();
01116       _scrollbar_size = newSize;
01117   }   
01118 #endif
01119 #if FLTK_ABI_VERSION >= 10303
01120 
01133   void tab_cell_nav(int val) {
01134     if ( val ) flags_ |=  TABCELLNAV;
01135     else       flags_ &= ~TABCELLNAV;
01136   }
01137 
01145   int tab_cell_nav() const {
01146     return(flags_ & TABCELLNAV ? 1 : 0);
01147   }
01148 #endif
01149 };
01150 
01151 #endif /*_FL_TABLE_H*/
01152 
01153 //
01154 // End of "$Id$".
01155 //
  • © 1998-2016 by Bill Spitzak and others.     FLTK

  • © 1998-2016 by Bill Spitzak and others.     FLTK

    Permission is granted to reproduce this manual or any portion for any purpose, provided this copyright and permission notice are preserved.