Fl_Group | +----Fl_Table | +----Fl_Table_Row
#include <FL/Fl_Table.H>
This widget does not handle the data in the table. The draw_cell() method must be overridden by a subclass to manage drawing the contents of the cells.
This widget can be used in several ways:
When acting as part of a custom widget, events on the cells and/or headings generate callbacks when they are clicked by the user. You control when events are generated based on the setting for Fl_Table::when().
When acting as a container for FLTK widgets, the FLTK widgets maintain themselves. Although the draw_cell() method must be overridden, its contents can be very simple. See the draw_cell() code in widgettable.cxx.
The following variables are available to classes deriving from Fl_Table:
x()/y()/w()/h() -- Fl_Table widget's outer dimension. The outer edge of the border of the Fl_Table. (Red in the diagram above) wix/wiy/wiw/wih -- Fl_Table widget's inner dimension. The inner edge of the border of the Fl_Table. eg. if the Fl_Table's box() is FL_NO_BOX, these values are the same as x()/y()/w()/h(). (Yellow in the diagram above) tox/toy/tow/toh -- The table's outer dimension. The outer edge of the border around the cells, but inside the row/col headings and scrollbars. (Green in the diagram above) tix/tiy/tiw/tih -- The table's inner dimension. The inner edge of the border around the cells, but inside the row/col headings and scrollbars. AKA the table's clip region. eg. if the table_box() is FL_NO_BOX, these values are the same as tox/toyy/tow/toh. (Blue in the diagram above)
The callback function should use the following functions to determine the context/row/column:
callback_row() and callback_col() will be set to the row and column number the event occurred on. If someone clicked on a row header, col will be 0. If someone clicked on a column header, row will be 0.
callback_context() will return one of the following:
Fl_Table::CONTEXT_ROW_HEADER | Someone clicked on a row header. Excludes resizing. |
Fl_Table::CONTEXT_COL_HEADER | Someone clicked on a column header. Excludes resizing. |
Fl_Table::CONTEXT_CELL |
Someone clicked on a cell. To receive callbacks for FL_RELEASE events, you must set when(FL_WHEN_RELEASE). |
Fl_Table::CONTEXT_RC_RESIZE |
Someone is resizing rows/columns either interactively,
or via the col_width() or
row_height() API.
Use is_interactive_resize() to determine interactive resizing. If resizing a column, R=0 and C=column being resized. If resizing a row, C=0 and R=row being resized. NOTE: To receive resize events, you must set when(FL_WHEN_CHANGED). |
Example:
class MyTable { [..] private: // Handle events that happen on the table void event_callback2() { int R = callback_row(), // row where event occurred C = callback_col();i // column where event occurred TableContext context = callback_context(); // which part of table fprintf(stderr, "callback: Row=%d Col=%d Context=%d Event=%d\n", R, C, (int)context, (int)Fl::event()); } // Actual static callback static void event_callback(Fl_Widget*, void* data) { MyTable *o = (MyTable*)data; o->event_callback2(); } public: MyTable() // Constructor { [..] table.callback(&event_callback, (void*)this); // setup callback table.when(FL_WHEN_CHANGED|FL_WHEN_RELEASE); // when to call it } };
callback_row() returns the current row the event occurred on.
callback_col() returns the current column the event occurred on.
callback_context() returns the current 'table context'. See possible contexts.
Typically used in loops, eg:
for ( int i=0; i<children(); i++ ) { Fl_Widget *w = child(i); [..] }
See Also: child(), which has an example loop showing how these methods should be used.
Only cells that are completely (or partially) visible will be told to draw.
context will be one of the following:
Fl_Table::CONTEXT_STARTPAGE | When table, or parts of the table, are about to be redrawn. Use to initialize static data, such as font selections. r/c will be zero, x/y/w/h will be the dimensions of the table's entire data area. (Useful for locking a database before accessing; see also visible_cells()) |
Fl_Table::CONTEXT_ENDPAGE | When table has completed being redrawn. r/c will be zero, x/y/w/h dimensions of table's data area. (Useful for unlocking a database after accessing) |
Fl_Table::CONTEXT_ROW_HEADER | Whenever a row header cell needs to be drawn. |
Fl_Table::CONTEXT_COL_HEADER | Whenever a column header cell needs to be drawn. |
Fl_Table::CONTEXT_CELL | Whenever a data cell in the table needs to be drawn. |
Fl_Table::CONTEXT_RC_RESIZE | Whenever table or row/column is resized or scrolled,
either interactively or via col_width() or row_height().
Useful for fltk containers that need to resize or move the child fltk widgets. |
row and col will be set to the row and column number the user clicked on. In the case of row headers, col will be 0. In the case of column headers, row will be 0.
x/y/w/h will be the position and dimensions of where the cell should be drawn.
In the case of custom widgets, a minimal draw_cell() override might look like the following. With custom widgets it is up to the caller to handle drawing everything within the dimensions of the cell, including handling the selection color. Note all clipping must be handled as well; this allows drawing outside the dimensions of the cell if so desired for 'custom effects'.
// This is called whenever Fl_Table wants you to draw a cell void MyTable::draw_cell(TableContext context, int R=0, int C=0, int X=0, int Y=0, int W=0, int H=0) { static char s[40]; sprintf(s, "%d/%d", R, C); // text for each cell switch ( context ) { case CONTEXT_STARTPAGE: // Fl_Table telling us its starting to draw page fl_font(FL_HELVETICA, 16); return; case CONTEXT_ROW_HEADER: // Fl_Table telling us it's draw row/col headers case CONTEXT_COL_HEADER: fl_push_clip(X, Y, W, H); { fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, color()); fl_color(FL_BLACK); fl_draw(s, X, Y, W, H, FL_ALIGN_CENTER); } fl_pop_clip(); return; case CONTEXT_CELL: // Fl_Table telling us to draw cells fl_push_clip(X, Y, W, H); { // BG COLOR fl_color( row_selected(R) ? selection_color() : FL_WHITE); fl_rectf(X, Y, W, H); // TEXT fl_color(FL_BLACK); fl_draw(s, X, Y, W, H, FL_ALIGN_CENTER); // BORDER fl_color(FL_LIGHT2); fl_rect(X, Y, W, H); } fl_pop_clip(); return; default: return; } //NOTREACHED }
The second form returns the number of columns in the table.
The second form returns if column headers are enabled or not; 1=enabled, 0=disabled.
The second form returns the current column header color.
The second form returns the current column header height (in pixels).
The second form returns the current column minimum resize value.
The second form returns the current column scroll position as a column number.
The second form returns the current value of this flag.
The second form returns the current width of the specified column in pixels and causes the screen to redraw.
The second form returns the number of rows in the table.
The second form returns the value of this flag.
The second form returns the current row header color.
The second form returns the current row header width (in pixels).
The second form returns the current row minimum resize value.
The second form returns the current row scroll position as a row number.
The second form returns the current value of this flag.
The second form returns the current height of the specified row as a value in pixels.
The second form returns the current box type used for the data table.
The second form returns the current top row shown in the table. This row may be partially obscured.
These values can be used e.g. by your draw_cell() routine during CONTEXT_STARTPAGE to figure out what cells are about to be redrawn, for the purposes of locking the data from a database before it's drawn.
leftcol rightcol : : toprow .. .-------------------. | | | V I S I B L E | | | | T A B L E | | | botrow .. '-------------------`e.g. in a table where the visible rows are 5-20, and the visible columns are 100-120, then those variables would be:
The second form returns the current value of when().
These are the only values currently supported:
FL_WHEN_CHANGED | callback() will be called when rows or columns are resized (interactively or via col_width() or row_height()), passing CONTEXT_RC_RESIZE via callback_context(). |
FL_WHEN_RELEASE | callback() will be called during FL_RELEASE events, such as when someone releases a mouse button somewhere on the table. |
The callback() routine is sent a TableContext that indicates the context the event occurred in, such as in a cell, in a header, or elsewhere on the table. When an event occurs in a cell or header, callback_row() and callback_col() can be used to determine the row and column. The callback can also look at the regular fltk event values (ie. Fl::event() and Fl::button()) to determine what kind of event is occurring.