FLTK 1.3.4
Fl_Table.H
1 //
2 // "$Id: Fl_Table.H 11094 2016-01-31 02:49:56Z AlbrechtS $"
3 //
4 // Fl_Table -- A table widget
5 //
6 // Copyright 2002 by Greg Ercolano.
7 // Copyright (c) 2004 O'ksi'D
8 //
9 // This library is free software. Distribution and use rights are outlined in
10 // the file "COPYING" which should have been included with this file. If this
11 // file is missing or damaged, see the license at:
12 //
13 // http://www.fltk.org/COPYING.php
14 //
15 // Please report all bugs and problems on the following page:
16 //
17 // http://www.fltk.org/str.php
18 //
19 
20 #ifndef _FL_TABLE_H
21 #define _FL_TABLE_H
22 
23 #include <sys/types.h>
24 #include <string.h> // memcpy
25 #ifdef WIN32
26 #include <malloc.h> // WINDOWS: malloc/realloc
27 #else /*WIN32*/
28 #include <stdlib.h> // UNIX: malloc/realloc
29 #endif /*WIN32*/
30 
31 #include <FL/Fl.H>
32 #include <FL/Fl_Group.H>
33 #include <FL/Fl_Scroll.H>
34 #include <FL/Fl_Box.H>
35 #include <FL/Fl_Scrollbar.H>
36 
170 class FL_EXPORT Fl_Table : public Fl_Group {
171 public:
178  CONTEXT_NONE = 0,
179  CONTEXT_STARTPAGE = 0x01,
180  CONTEXT_ENDPAGE = 0x02,
181  CONTEXT_ROW_HEADER = 0x04,
182  CONTEXT_COL_HEADER = 0x08,
183  CONTEXT_CELL = 0x10,
184  CONTEXT_TABLE = 0x20,
185  CONTEXT_RC_RESIZE = 0x40
186  };
187 
188 private:
189  int _rows, _cols; // total rows/cols
190  int _row_header_w; // width of row header
191  int _col_header_h; // height of column header
192  int _row_position; // last row_position set (not necessarily == toprow!)
193  int _col_position; // last col_position set (not necessarily == leftcol!)
194 
195  char _row_header; // row header enabled?
196  char _col_header; // col header enabled?
197  char _row_resize; // row resizing enabled?
198  char _col_resize; // col resizing enabled?
199  int _row_resize_min; // row minimum resizing height (default=1)
200  int _col_resize_min; // col minimum resizing width (default=1)
201 
202  // OPTIMIZATION: partial row/column redraw variables
203  int _redraw_toprow;
204  int _redraw_botrow;
205  int _redraw_leftcol;
206  int _redraw_rightcol;
207  Fl_Color _row_header_color;
208  Fl_Color _col_header_color;
209 
210  int _auto_drag;
211  int _selecting;
212 #if FLTK_ABI_VERSION >= 10301
213  int _scrollbar_size;
214 #endif
215 #if FLTK_ABI_VERSION >= 10303
216  enum {
217  TABCELLNAV = 1<<0,
218  };
219  unsigned int flags_;
220 #endif
221 
222  // An STL-ish vector without templates
223  class FL_EXPORT IntVector {
224  int *arr;
225  unsigned int _size;
226  void init() {
227  arr = NULL;
228  _size = 0;
229  }
230  void copy(int *newarr, unsigned int newsize) {
231  size(newsize);
232  memcpy(arr, newarr, newsize * sizeof(int));
233  }
234  public:
235  IntVector() { init(); } // CTOR
236  ~IntVector() { if ( arr ) free(arr); arr = NULL; } // DTOR
237  IntVector(IntVector&o) { init(); copy(o.arr, o._size); } // COPY CTOR
238  IntVector& operator=(IntVector&o) { // ASSIGN
239  init();
240  copy(o.arr, o._size);
241  return(*this);
242  }
243  int operator[](int x) const { return(arr[x]); }
244  int& operator[](int x) { return(arr[x]); }
245  unsigned int size() { return(_size); }
246  void size(unsigned int count) {
247  if ( count != _size ) {
248  arr = (int*)realloc(arr, count * sizeof(int));
249  _size = count;
250  }
251  }
252  int pop_back() { int tmp = arr[_size-1]; _size--; return(tmp); }
253  void push_back(int val) { unsigned int x = _size; size(_size+1); arr[x] = val; }
254  int back() { return(arr[_size-1]); }
255  };
256 
257  IntVector _colwidths; // column widths in pixels
258  IntVector _rowheights; // row heights in pixels
259 
260  Fl_Cursor _last_cursor; // last mouse cursor before changed to 'resize' cursor
261 
262  // EVENT CALLBACK DATA
263  TableContext _callback_context; // event context
264  int _callback_row, _callback_col; // event row/col
265 
266  // handle() state variables.
267  // Put here instead of local statics in handle(), so more
268  // than one Fl_Table can exist without crosstalk between them.
269  //
270  int _resizing_col; // column being dragged
271  int _resizing_row; // row being dragged
272  int _dragging_x; // starting x position for horiz drag
273  int _dragging_y; // starting y position for vert drag
274  int _last_row; // last row we FL_PUSH'ed
275 
276  // Redraw single cell
277  void _redraw_cell(TableContext context, int R, int C);
278 
279  void _start_auto_drag();
280  void _stop_auto_drag();
281  void _auto_drag_cb();
282  static void _auto_drag_cb2(void *d);
283 
284 protected:
285  enum ResizeFlag {
286  RESIZE_NONE = 0,
287  RESIZE_COL_LEFT = 1,
288  RESIZE_COL_RIGHT = 2,
289  RESIZE_ROW_ABOVE = 3,
290  RESIZE_ROW_BELOW = 4
291  };
292 
293  int table_w, table_h; // table's virtual size (in pixels)
294  int toprow, botrow, leftcol, rightcol; // four corners of viewable table
295 
296  // selection
297  int current_row, current_col;
298  int select_row, select_col;
299 
300  // OPTIMIZATION: Precomputed scroll positions for the toprow/leftcol
301  int toprow_scrollpos;
302  int leftcol_scrollpos;
303 
304  // Dimensions
305  int tix, tiy, tiw, tih; // data table inner dimension xywh
306  int tox, toy, tow, toh; // data table outer dimension xywh
307  int wix, wiy, wiw, wih; // widget inner dimension xywh
308 
309  Fl_Scroll *table; // container for child fltk widgets (if any)
310  Fl_Scrollbar *vscrollbar; // vertical scrollbar
311  Fl_Scrollbar *hscrollbar; // horizontal scrollbar
312 
313  // Fltk
314  int handle(int e); // fltk handle() override
315 
316  // Class maintenance
317  void recalc_dimensions();
318  void table_resized(); // table resized; recalc
319  void table_scrolled(); // table scrolled; recalc
320  void get_bounds(TableContext context, // return x/y/w/h bounds for context
321  int &X, int &Y, int &W, int &H);
322  void change_cursor(Fl_Cursor newcursor); // change mouse cursor to some other shape
323  TableContext cursor2rowcol(int &R, int &C, ResizeFlag &resizeflag);
324  // find r/c given current x/y event
325  int find_cell(TableContext context, // find cell's x/y/w/h given r/c
326  int R, int C, int &X, int &Y, int &W, int &H);
327  int row_col_clamp(TableContext context, int &R, int &C);
328  // clamp r/c to known universe
329 
440  virtual void draw_cell(TableContext context, int R=0, int C=0,
441  int X=0, int Y=0, int W=0, int H=0)
442  { } // overridden by deriving class
443 
444  long row_scroll_position(int row); // find scroll position of row (in pixels)
445  long col_scroll_position(int col); // find scroll position of col (in pixels)
446 
447  int is_fltk_container() { // does table contain fltk widgets?
448  return( Fl_Group::children() > 3 ); // (ie. more than box and 2 scrollbars?)
449  }
450 
451  static void scroll_cb(Fl_Widget*,void*); // h/v scrollbar callback
452 
453  void damage_zone(int r1, int c1, int r2, int c2, int r3 = 0, int c3 = 0);
454 
455  void redraw_range(int topRow, int botRow, int leftCol, int rightCol) {
456  if ( _redraw_toprow == -1 ) {
457  // Initialize redraw range
458  _redraw_toprow = topRow;
459  _redraw_botrow = botRow;
460  _redraw_leftcol = leftCol;
461  _redraw_rightcol = rightCol;
462  } else {
463  // Extend redraw range
464  if ( topRow < _redraw_toprow ) _redraw_toprow = topRow;
465  if ( botRow > _redraw_botrow ) _redraw_botrow = botRow;
466  if ( leftCol < _redraw_leftcol ) _redraw_leftcol = leftCol;
467  if ( rightCol > _redraw_rightcol ) _redraw_rightcol = rightCol;
468  }
469 
470  // Indicate partial redraw needed of some cells
471  damage(FL_DAMAGE_CHILD);
472  }
473 
474 public:
480  Fl_Table(int X, int Y, int W, int H, const char *l=0);
481 
486  ~Fl_Table();
487 
493  virtual void clear() { rows(0); cols(0); table->clear(); }
494 
495  // \todo: add topline(), middleline(), bottomline()
496 
502  inline void table_box(Fl_Boxtype val) {
503  table->box(val);
504  table_resized();
505  }
506 
510  inline Fl_Boxtype table_box( void ) {
511  return(table->box());
512  }
513 
517  virtual void rows(int val); // set/get number of rows
518 
522  inline int rows() {
523  return(_rows);
524  }
525 
529  virtual void cols(int val); // set/get number of columns
530 
534  inline int cols() {
535  return(_cols);
536  }
537 
566  inline void visible_cells(int& r1, int& r2, int& c1, int& c2) {
567  r1 = toprow;
568  r2 = botrow;
569  c1 = leftcol;
570  c2 = rightcol;
571  }
572 
578  return(_resizing_row != -1 || _resizing_col != -1);
579  }
580 
584  inline int row_resize() {
585  return(_row_resize);
586  }
587 
594  void row_resize(int flag) { // enable row resizing
595  _row_resize = flag;
596  }
597 
601  inline int col_resize() {
602  return(_col_resize);
603  }
610  void col_resize(int flag) { // enable col resizing
611  _col_resize = flag;
612  }
613 
617  inline int col_resize_min() { // column minimum resizing width
618  return(_col_resize_min);
619  }
620 
626  void col_resize_min(int val) {
627  _col_resize_min = ( val < 1 ) ? 1 : val;
628  }
629 
633  inline int row_resize_min() { // column minimum resizing width
634  return(_row_resize_min);
635  }
636 
642  void row_resize_min(int val) {
643  _row_resize_min = ( val < 1 ) ? 1 : val;
644  }
645 
649  inline int row_header() { // set/get row header enable flag
650  return(_row_header);
651  }
652 
657  void row_header(int flag) {
658  _row_header = flag;
659  table_resized();
660  redraw();
661  }
662 
666  inline int col_header() { // set/get col header enable flag
667  return(_col_header);
668  }
669 
674  void col_header(int flag) {
675  _col_header = flag;
676  table_resized();
677  redraw();
678  }
679 
683  inline void col_header_height(int height) { // set/get col header height
684  _col_header_h = height;
685  table_resized();
686  redraw();
687  }
688 
692  inline int col_header_height() {
693  return(_col_header_h);
694  }
695 
699  inline void row_header_width(int width) { // set/get row header width
700  _row_header_w = width;
701  table_resized();
702  redraw();
703  }
704 
708  inline int row_header_width() {
709  return(_row_header_w);
710  }
711 
715  inline void row_header_color(Fl_Color val) { // set/get row header color
716  _row_header_color = val;
717  redraw();
718  }
719 
724  return(_row_header_color);
725  }
726 
730  inline void col_header_color(Fl_Color val) { // set/get col header color
731  _col_header_color = val;
732  redraw();
733  }
734 
739  return(_col_header_color);
740  }
741 
748  void row_height(int row, int height); // set/get row height
749 
753  inline int row_height(int row) {
754  return((row<0 || row>=(int)_rowheights.size()) ? 0 : _rowheights[row]);
755  }
756 
762  void col_width(int col, int width); // set/get a column's width
763 
767  inline int col_width(int col) {
768  return((col<0 || col>=(int)_colwidths.size()) ? 0 : _colwidths[col]);
769  }
770 
775  void row_height_all(int height) { // set all row/col heights
776  for ( int r=0; r<rows(); r++ ) {
777  row_height(r, height);
778  }
779  }
780 
785  void col_width_all(int width) {
786  for ( int c=0; c<cols(); c++ ) {
787  col_width(c, width);
788  }
789  }
790 
794  void row_position(int row); // set/get table's current scroll position
795 
799  void col_position(int col);
800 
804  int row_position() { // current row position
805  return(_row_position);
806  }
807 
811  int col_position() { // current col position
812  return(_col_position);
813  }
814 
820  inline void top_row(int row) { // set/get top row (deprecated)
821  row_position(row);
822  }
823 
828  inline int top_row() {
829  return(row_position());
830  }
831  int is_selected(int r, int c); // selected cell
832  void get_selection(int &row_top, int &col_left, int &row_bot, int &col_right);
833  void set_selection(int row_top, int col_left, int row_bot, int col_right);
834  int move_cursor(int R, int C, int shiftselect);
835  int move_cursor(int R, int C);
836 
840  void resize(int X, int Y, int W, int H); // fltk resize() override
841  void draw(void); // fltk draw() override
842 
843  // This crashes sortapp() during init.
844  // void box(Fl_Boxtype val) {
845  // Fl_Group::box(val);
846  // if ( table ) {
847  // resize(x(), y(), w(), h());
848  // }
849  // }
850  // Fl_Boxtype box(void) const {
851  // return(Fl_Group::box());
852  // }
853 
854  // Child group
855  void init_sizes() {
856  table->init_sizes();
857  table->redraw();
858  }
859  void add(Fl_Widget& wgt) {
860  table->add(wgt);
861  if ( table->children() > 2 ) {
862  table->show();
863  } else {
864  table->hide();
865  }
866  }
867  void add(Fl_Widget* wgt) {
868  add(*wgt);
869  }
870  void insert(Fl_Widget& wgt, int n) {
871  table->insert(wgt,n);
872  }
873  void insert(Fl_Widget& wgt, Fl_Widget* w2) {
874  table->insert(wgt,w2);
875  }
876  void remove(Fl_Widget& wgt) {
877  table->remove(wgt);
878  }
879  void begin() {
880  table->begin();
881  }
882  void end() {
883  table->end();
884  // HACK: Avoid showing Fl_Scroll; seems to erase screen
885  // causing unnecessary flicker, even if its box() is FL_NO_BOX.
886  //
887  if ( table->children() > 2 ) {
888  table->show();
889  } else {
890  table->hide();
891  }
893  }
894  Fl_Widget * const *array() {
895  return(table->array());
896  }
897 
912  Fl_Widget *child(int n) const {
913  return(table->child(n));
914  }
915 
924  int children() const {
925  return(table->children()-2); // -2: skip Fl_Scroll's h/v scrollbar widgets
926  }
927  int find(const Fl_Widget *wgt) const {
928  return(table->find(wgt));
929  }
930  int find(const Fl_Widget &wgt) const {
931  return(table->find(wgt));
932  }
933  // CALLBACKS
934 
940  int callback_row() {
941  return(_callback_row);
942  }
943 
949  int callback_col() {
950  return(_callback_col);
951  }
952 
959  return(_callback_context);
960  }
961 
962  void do_callback(TableContext context, int row, int col) {
963  _callback_context = context;
964  _callback_row = row;
965  _callback_col = col;
967  }
968 
969 #ifdef FL_DOXYGEN
970 
998  void when(Fl_When flags);
999 #endif
1000 
1001 #ifdef FL_DOXYGEN
1002 
1079  void callback(Fl_Widget*, void*);
1080 #endif
1081 
1082 #if FLTK_ABI_VERSION >= 10301
1083  // NEW
1093  int scrollbar_size() const {
1094  return(_scrollbar_size);
1095  }
1114  void scrollbar_size(int newSize) {
1115  if ( newSize != _scrollbar_size ) redraw();
1116  _scrollbar_size = newSize;
1117  }
1118 #endif
1119 #if FLTK_ABI_VERSION >= 10303
1120 
1133  void tab_cell_nav(int val) {
1134  if ( val ) flags_ |= TABCELLNAV;
1135  else flags_ &= ~TABCELLNAV;
1136  }
1137 
1145  int tab_cell_nav() const {
1146  return(flags_ & TABCELLNAV ? 1 : 0);
1147  }
1148 #endif
1149 };
1150 
1151 #endif /*_FL_TABLE_H*/
1152 
1153 //
1154 // End of "$Id: Fl_Table.H 11094 2016-01-31 02:49:56Z AlbrechtS $".
1155 //
void col_resize(int flag)
Allows/disallows column resizing by the user.
Definition: Fl_Table.H:610
Fl_Widget is the base class for all widgets in FLTK.
Definition: Fl_Widget.H:101
int row_resize_min()
Returns the current row minimum resize value.
Definition: Fl_Table.H:633
A table of widgets or other content.
Definition: Fl_Table.H:170
Fl_Boxtype table_box(void)
Returns the current box type used for the data table.
Definition: Fl_Table.H:510
Fl_Cursor
The following constants define the mouse cursors that are available in FLTK.
Definition: Enumerations.H:1048
int rows()
Returns the number of rows in the table.
Definition: Fl_Table.H:522
int row_header()
Returns if row headers are enabled or not.
Definition: Fl_Table.H:649
int col_header_height()
Gets the column header height.
Definition: Fl_Table.H:692
int callback_col()
Returns the current column the event occurred on.
Definition: Fl_Table.H:949
Fl_Widget * child(int n) const
Returns the child widget by an index.
Definition: Fl_Table.H:912
void table_box(Fl_Boxtype val)
Sets the kind of box drawn around the data table, the default being FL_NO_BOX.
Definition: Fl_Table.H:502
void col_header_height(int height)
Sets the height in pixels for column headers and redraws the table.
Definition: Fl_Table.H:683
Fl static class.
virtual void clear()
Clears the table to zero rows (rows(0)), zero columns (cols(0)), and clears any widgets (table->clear...
Definition: Fl_Table.H:493
int col_header()
Returns if column headers are enabled or not.
Definition: Fl_Table.H:666
void col_width_all(int width)
Convenience method to set the width of all columns to the same value, in pixels.
Definition: Fl_Table.H:785
Fl_When
These constants determine when a callback is performed.
Definition: Enumerations.H:439
Fl_Group * parent() const
Returns a pointer to the parent widget.
Definition: Fl_Widget.H:254
Fl_Color row_header_color()
Returns the current row header color.
Definition: Fl_Table.H:723
TableContext
The context bit flags for Fl_Table related callbacks.
Definition: Fl_Table.H:177
void row_resize_min(int val)
Sets the current row minimum resize value.
Definition: Fl_Table.H:642
A child needs to be redrawn.
Definition: Enumerations.H:1106
Fl_Color col_header_color()
Gets the color for column headers.
Definition: Fl_Table.H:738
void visible_cells(int &r1, int &r2, int &c1, int &c2)
Returns the range of row and column numbers for all visible and partially visible cells in the table...
Definition: Fl_Table.H:566
Fl_Boxtype
Definition: Enumerations.H:603
int cols()
Get the number of columns in the table.
Definition: Fl_Table.H:534
void row_height_all(int height)
Convenience method to set the height of all rows to the same value, in pixels.
Definition: Fl_Table.H:775
The Fl_Group class is the FLTK container widget.
Definition: Fl_Group.H:41
int is_interactive_resize()
Returns 1 if someone is interactively resizing a row or column.
Definition: Fl_Table.H:577
int scrollbar_size() const
Gets the current size of the scrollbars' troughs, in pixels.
Definition: Fl_Table.H:1093
int tab_cell_nav() const
Get state of table's 'Tab' key cell navigation flag.
Definition: Fl_Table.H:1145
void tab_cell_nav(int val)
Flag to control if Tab navigates table cells or not.
Definition: Fl_Table.H:1133
void row_header_color(Fl_Color val)
Sets the row header color and causes the screen to redraw.
Definition: Fl_Table.H:715
int col_width(int col)
Returns the current width of the specified column in pixels.
Definition: Fl_Table.H:767
int row_position()
Returns the current row scroll position as a row number.
Definition: Fl_Table.H:804
void col_header(int flag)
Enable or disable column headers.
Definition: Fl_Table.H:674
void row_resize(int flag)
Allows/disallows row resizing by the user.
Definition: Fl_Table.H:594
virtual void draw_cell(TableContext context, int R=0, int C=0, int X=0, int Y=0, int W=0, int H=0)
Subclass should override this method to handle drawing the cells.
Definition: Fl_Table.H:440
int col_resize()
Returns if column resizing by the user is allowed.
Definition: Fl_Table.H:601
void top_row(int row)
Sets which row should be at the top of the table, scrolling as necessary, and the table is redrawn...
Definition: Fl_Table.H:820
int row_height(int row)
Returns the current height of the specified row as a value in pixels.
Definition: Fl_Table.H:753
void col_header_color(Fl_Color val)
Sets the color for column headers and redraws the table.
Definition: Fl_Table.H:730
int children() const
Returns how many child widgets the group has.
Definition: Fl_Group.H:75
int top_row()
Returns the current top row shown in the table.
Definition: Fl_Table.H:828
int row_header_width()
Returns the current row header width (in pixels).
Definition: Fl_Table.H:708
void col_resize_min(int val)
Sets the current column minimum resize value.
Definition: Fl_Table.H:626
unsigned int Fl_Color
An FLTK color value; see also Colors.
Definition: Enumerations.H:934
void do_callback()
Calls the widget callback.
Definition: Fl_Widget.H:861
int children() const
Returns the number of children in the table.
Definition: Fl_Table.H:924
This container widget lets you maneuver around a set of widgets much larger than your window...
Definition: Fl_Scroll.H:87
void scrollbar_size(int newSize)
Sets the pixel size of the scrollbars' troughs to newSize, in pixels.
Definition: Fl_Table.H:1114
int callback_row()
Returns the current row the event occurred on.
Definition: Fl_Table.H:940
int col_resize_min()
Returns the current column minimum resize value.
Definition: Fl_Table.H:617
int row_resize()
Returns if row resizing by the user is allowed.
Definition: Fl_Table.H:584
int col_position()
Returns the current column scroll position as a column number.
Definition: Fl_Table.H:811
TableContext callback_context()
Returns the current 'table context'.
Definition: Fl_Table.H:958
The Fl_Scrollbar widget displays a slider with arrow buttons at the ends of the scrollbar.
Definition: Fl_Scrollbar.H:43
void row_header_width(int width)
Sets the row header width to n and causes the screen to redraw.
Definition: Fl_Table.H:699
static Fl_Group * current()
Returns the currently active group.
Definition: Fl_Group.cxx:84
void row_header(int flag)
Enables/disables showing the row headers.
Definition: Fl_Table.H:657