AG_Table — agar
    table display widget
#include <agar/core.h>
#include <agar/gui.h>
 
The AG_Table widget displays a set of
    cells organized in one or more columns. Cells can be associated with text,
    numerical values, pointers to numerical values, or custom functions.
    AG_Table is optimized for tables that must be
    rebuilt frequently. Individual cells, entire rows or entire columns can be
    selected indepedently.
Note that another table display widget,
    AG_Treetbl(3),
    is also available. It stores row information in a tree structure and
    provides a very different interface from
  AG_Table.
AG_Table *
  
  AG_TableNew(AG_Widget
    *parent, Uint
    flags);
  
  AG_Table *
  
  AG_TableNewPolled(AG_Widget
    *parent, Uint
    flags, void
    (*event_fn)(AG_Event *),
    const char *event_args,
    ...);
  
  void
  
  AG_TableSetPollInterval(AG_Table
    *tbl, Uint ms);
  
  void
  
  AG_TableSizeHint(AG_Table
    *tbl, int width,
    int nrows);
  
  void
  
  AG_TableSetColHeight(AG_Table
    *tbl, int
  height);
  
  void
  
  AG_TableSetRowHeight(AG_Table
    *tbl, int
  height);
  
  void
  
  AG_TableSetColMin(AG_Table
    *tbl, int
  width);
  
  void
  
  AG_TableSetDefaultColWidth(AG_Table
    *tbl, int
  width);
  
  void
  
  AG_TableSetSelectionMode(AG_Table
    *tbl, enum
    ag_table_selmode mode);
  
  void
  
  AG_TableSetSeparator(AG_Table
    *tbl, const char
    *sep);
  
  void
  
  AG_TableSetRowClickFn(AG_Table
    *tbl, AG_EventFn
    fn, const char
    *fn_args, ...);
  
  void
  
  AG_TableSetColClickFn(AG_Table
    *tbl, AG_EventFn
    fn, const char
    *fn_args, ...);
  
  void
  
  AG_TableSetCellClickFn(AG_Table
    *tbl, AG_EventFn
    fn, const char
    *fn_args, ...);
  
  void
  
  AG_TableSetRowDblClickFn(AG_Table
    *tbl, AG_EventFn
    fn, const char
    *fn_args, ...);
  
  void
  
  AG_TableSetColDblClickFn(AG_Table
    *tbl, AG_EventFn
    fn, const char
    *fn_args, ...);
  
  void
  
  AG_TableSetCellDblClickFn(AG_Table
    *tbl, AG_EventFn
    fn, const char
    *fn_args, ...);
  
  void
  
  AG_TableSetColumnAction(AG_Table
    *tbl, Uint
  action);
The
    AG_TableNew()
    function allocates, initializes and attaches a new
    AG_Table widget.
The
    AG_TableNewPolled()
    variant sets the polling flag and configures the ‘table-poll’
    event. event_fn is a pointer to the event-handler
    function responsible for populating the table (see
    AG_TableBegin() and
    AG_TableEnd() for details).
    event_args and the following arguments are optional
    AG_Event(3)
    style parameters that will be passed on to
  event_fn.
Acceptable flags include:
  - AG_TABLE_MULTI
 
  - Allow the user to select multiple items while holding
      
CTRL or SHIFT. 
  - AG_TABLE_MULTITOGGLE
 
  - Allow the user to select multiple items without holding
      
CTRL or SHIFT. 
  - AG_TABLE_POLL
 
  - Table contents are updated dynamically by the ‘table-poll’
      event handler (implied by
      
AG_TableNewPolled()). 
  - AG_TABLE_SCROLL_TO_SEL
 
  - If the selection is not visible, scroll towards it. This flag is
      writeable, but is automatically set or cleared by keyboard events.
 
  - AG_TABLE_HIGHLIGHT_COLS
 
  - Highlight the currently selected column(s) using transparency.
 
  - AG_TABLE_HFILL
 
  - Expand horizontally in parent container.
 
  - AG_TABLE_VFILL
 
  - Expand vertically in parent container.
 
  - AG_TABLE_EXPAND
 
  - Shorthand for 
AG_TABLE_HFILL |
      AG_TABLE_VFILL.
      This is recommended as an alternative to calling
      AG_TableSizeHint(). 
  - AG_TABLE_NOAUTOSORT
 
  - Disable automatic sorting (see
    
AG_TableSort()). 
The
    AG_TableSetPollInterval()
    function specifies an alternate update interval for polled tables in
    milliseconds (default is 250ms). Polling may be paused by calling
    AG_TableSetPollInterval() with an argument of 0.
The
    AG_TableSizeHint()
    function requests an initial sizing, where width is
    the width in pixels and nrows is the number of rows to
    display.
AG_TableSetColHeight()
    sets the size of column headers in pixels.
    AG_TableSetRowHeight() sets the size of rows in
    pixels. In both cases, the default is dependent on the height of the default
    font.
AG_TableSetColMin()
    sets the minimum allowed column width, in pixels. The default is a small
    value intended to prevent the user from resizing columns to zero size. If
    existing columns are smaller than the specified value,
    AG_TableSetColMin() will resize them.
AG_TableSetDefaultColWidth()
    specifies a "default" width in pixels, to use during initial size
    requisition for columns using FILL or a size specification in
  "%".
AG_TableSetSelectionMode()
    defines the effect of cursor selections on the table. Possible values for
    mode are:
enum ag_table_selmode {
	AG_TABLE_SEL_ROWS,	/* Select entire rows */
	AG_TABLE_SEL_CELLS,	/* Select individual cells */
	AG_TABLE_SEL_COLS	/* Select entire columns */
};
 
AG_TableSetSeparator()
    changes the set of accepted field-separator characters in
    AG_TableAddRow() (default is ":").
The
    AG_TableSetRowClickFn(),
    AG_TableSetColClickFn() and
    AG_TableSetCellClickFn() functions register a
    callback routine to invoke upon single-click on a row, column or cell,
    respectively, depending on the current selection mode. The callback routine
    for AG_TableSetRowClickFn() is passed the row index
    as an int argument.
    AG_TableSetColClickFn() is passed the column index
    and AG_TableSetCellClickFn() is passed the row and
    column indices in order.
The
    AG_TableSetRowDblClickFn(),
    AG_TableSetColDblClickFn(), and
    AG_TableSetCellDblClickFn() variants register
    callbacks to invoke on double-click. If both single and double-click
    callbacks are defined, only the single-click callback is used.
The
    AG_TableSetColumnAction()
    specifies the action(s) to take whenever a column header is pressed.
    Acceptable arguments to flags include:
  - AG_TABLE_SELECT
 
  - Select the entire column.
 
  - AG_TABLE_SORT
 
  - Change the sort direction of the column.
 
void
  
  AG_TableBegin(AG_Table
    *tbl);
  
  void
  
  AG_TableEnd(AG_Table
    *tbl);
  
  void
  
  AG_TableSort(AG_Table
    *tbl);
  
  void
  
  AG_TableClear(AG_Table
    *tbl);
Tables created with
    AG_TableNewPolled()
    are periodically repopulated, using a callback routine. In this callback
    routine, calls to AG_TableAddRow() should be
    enclosed between AG_TableBegin() and
    AG_TableEnd(). It is not allowed to add or remove
    columns from the callback routine. The
    AG_TableBegin() function, notably, saves current
    selection information (to keep selections consistent across table
    re-population), and clears all rows.
This method of repopulating a table using a
    function nicely separates the GUI from the underlying application. It is
    also more efficient than it seems, since
    AG_TableBegin()
    will re-use the resources (e.g., already rendered text surfaces) of
    unchanged cells.
The
    AG_TableSort()
    function sorts the rows of the table. This function is useful in combination
    with the AG_TABLE_NOAUTOSORT option.
The
    AG_TableClear()
    routine clears the rows of the table. It is equivalent to calling
    AG_TableBegin().
int
  
  AG_TableAddCol(AG_Table
    *tbl, const char
    *name, const char
    *size_spec, int
    (*sortFn)(const void *, const void *));
  
  void
  
  AG_TableSelectCol(AG_Table
    *tbl, int col);
  
  void
  
  AG_TableDeselectCol(AG_Table
    *tbl, int col);
  
  void
  
  AG_TableSelectAllCols(AG_Table
    *tbl);
  
  void
  
  AG_TableDeselectAllCols(AG_Table
    *tbl);
  
  int
  
  AG_TableColSelected(AG_Table
    *tbl, int col);
The
    AG_TableAddCol()
    function inserts a new column into the table, returning the number of the
    new column if successful, or -1 if an error has occurred.
    name specifies the text to display in the column
    header. size_spec is an optional size specification
    (see
    AG_SizeSpec(3))
    used in initial sizing of the column. sortFn, if not
    NULL, is the compare function to use for items of this column. It is passed
    pointers to two AG_TableCell structures to
  compare.
The
    AG_TableSelectCol()
    and AG_TableDeselectCol() functions control the
    selection flag on the given column.
    AG_TableSelectAllCols() and
    AG_TableDeselectAllCols() set the selection flag on
    all columns of the table. AG_TableColSelected()
    returns 1 if the given column is selected, 0 otherwise.
Note that the of the column selection flags are independent from
    the selection flag of individual cells; their meaning is
    application-specific.
int
  
  AG_TableAddRow(AG_Table
    *tbl, const char
    *fmt, ...);
  
  void
  
  AG_TableSelectRow(AG_Table
    *tbl, int row);
  
  void
  
  AG_TableDeselectRow(AG_Table
    *tbl, int row);
  
  void
  
  AG_TableSelectAllRows(AG_Table
    *tbl);
  
  void
  
  AG_TableDeselectAllRows(AG_Table
    *tbl);
  
  void
  
  AG_TableRowSelected(AG_Table
    *tbl, int row);
The
    AG_TableAddRow()
    function inserts a new row into the table and returns the new row number, or
    -1 if a failure has occurred. The fmt argument
    describes the individual fields (or cells) of this row. By default, the
    fields are comma-separated (the separator can be changed using
    AG_TableSetSeparator()). Note that it is possible to
    mix fields of differing types into a same column as long as the sorting
    function of that column can handle the combinations.
Acceptable specifiers include:
  - %s
 
  - Text string
 
  - %i, %d
 
  - Signed integer
 
  - %li, %ld
 
  - Long integer
 
  - %lli, %lld
 
  - Long long integer
 
  - %u, %x
 
  - Unsigned integer
 
  - %lu, %lx
 
  - Unsigned long integer
 
  - %llu, %llx
 
  - Unsigned long long integer
 
  - %[s8], %[s16], %[s32]
 
  - Signed 8-bit, 16-bit or 32-bit value
 
  - %[u8], %[u16], %[u32]
 
  - Unsigned 8-bit, 16-bit or 32-bit value
 
  - %f, %g
 
  - Floating-point value (precision modifiers like %.03f are accepted)
 
  - %p
 
  - User pointer (usually stored in hidden columns)
 
  - %[Ft]
 
  - User-specified function of the form:
    
void
        MyTextFn(void
        *tbl, char *buf, AG_Size
        len)
    The text copied into buf (which is
        len bytes in size) will be displayed in the
      cell.
   
  - %[Fs]
 
  - User-specified function of the form:
    
AG_Surface *
        MySurfFn(void
        *tbl, int x, int
      y)
    The returned
        AG_Surface(3)
        will be displayed in the cell. Note that this surface will be
        automatically freed once the widget is destroyed (similarly to
        AG_WidgetMapSurface(3),
        see %[FS] variant below). The x and
        y parameters can be ignored.
   
  - %[FS]
 
  - Same as "%[Fs]", except that Agar will never try to free the
      returned surface (similarly to
      AG_WidgetMapSurfaceNODUP(3)).
 
  - %[W]
 
  - A widget instance to insert into the table.
 
The functions
    AG_TableSelectRow()
    and AG_TableDeselectRow() set the selection flag on
    all cells of the given row. AG_TableSelectAllRows()
    and AG_TableDeselectAllRows() set the selection on
    all cells of the table. AG_TableRowSelected()
    returns 1 if the given row is selected, 0 otherwise.
AG_TableCell *
  
  AG_TableGetCell(AG_Table
    *tbl, int row,
    int col);
  
  void
  
  AG_TableSelectCell(AG_Table
    *tbl, int row,
    int col);
  
  void
  
  AG_TableDeselectCell(AG_Table
    *tbl, int row,
    int col);
  
  void
  
  AG_TableCellSelected(AG_Table
    *tbl, int row,
    int col);
  
  void
  
  AG_TableCompareCells(const
    AG_TableCell *c1, const
    AG_TableCell *c2);
  
  void
  
  AG_TablePrintCell(AG_Table
    *tbl, const AG_TableCell
    *c, char *dst,
    AG_Size dstLen);
The
    AG_TableGetCell()
    routine returns a pointer to the table cell currently at the specified row
    and column position.
AG_TableSelectCell(),
    AG_TableDeselectCell() and
    AG_TableCellSelected() control and query the
    selection flag on an individual cell located at the given row and
  column.
The
    AG_TableCompareCells()
    function compares cells c1 and
    c2. It returns 0 if the contents of the two cells is
    identical, otherwise the returned value depends on the type. If the cells
    have different types, it returns 1. If they are text-based, the return value
    of
    strcmp(3)
    is returned. If they are numerical, the difference is returned. For pointer
    and surface cells, the return value is 1 if they differ.
The
    AG_TablePrintCell()
    function writes a formatted string representation of the current cell value,
    to the fixed-size buffer dst.
int
  
  AG_TableSaveASCII(AG_Table
    *tbl, FILE *f,
    char separator);
AG_TableSaveASCII()
    writes the formatted contents of the table into an ASCII file
    f. Each row is separated by a newline, and cells are
    separated by the character given by the separator
    argument. The function returns 0 on success, -1 on failure.
The AG_Table widget generates the
    following events:
  row-selected(int
    index) 
  - The row at specified index was selected.
 
For the AG_Table object:
  - AG_TableCell *cells
 
  - Cell data in sorted rows (read-only).
 
  - AG_TableCol *cols
 
  - Column data (read-only);
 
  - int n
 
  - Number of columns (read-only).
 
  - int m
 
  - Number of rows (read-only).
 
For the AG_TableCell structure:
  - enum ag_table_cell_type type
 
  - Data type (see below).
 
  - Uint id
 
  - Optional user-specified ID (or 0).
 
  - char fmt[]
 
  - Format string (read-only; see
      
AG_TableAddRow()). 
  - AG_Widget *widget
 
  - Embedded widget for 
AG_CELL_WIDGET type cells
      (read-only). 
  - int selected
 
  - Selection flag (1 = selected, 0 = not selected).
 
  - AG_Table *tbl
 
  - Back pointer to 
AG_Table widget. 
For the AG_TableCol structure:
  - char name[]
 
  - Column header text string (read-only).
 
  - Uint flags
 
  - Flags including 
AG_TABLE_COL_FILL (expand to fill
      remaining space), AG_TABLE_COL_ASCENDING (sort
      ascending), AG_TABLE_COL_DESCENDING (sort
      descending) and AG_TABLE_COL_SELECTED (column
      selection flag). 
  - int w
 
  - Column width in pixels (read-only).
 
  - int wPct
 
  - Column width in % (or -1).
 
The cell data type is determined by enum
    ag_table_cell_type:
  - AG_CELL_NULL
 
  - Empty cell.
 
  - AG_CELL_STRING
 
  - C string.
 
  - AG_CELL_INT
 
  - Integer value.
 
  - AG_CELL_UINT
 
  - Unsigned integer value.
 
  - AG_CELL_LONG
 
  - Native long integer.
 
  - AG_CELL_LONG
 
  - Native unsigned long integer.
 
  - AG_CELL_FLOAT
 
  - Floating point number (single-precision).
 
  - AG_CELL_DOUBLE
 
  - Floating point number (double-precision).
 
  - AG_CELL_PSTRING
 
  - Pointer to a C string.
 
  - AG_CELL_PINT
 
  - Pointer to an integer.
 
  - AG_CELL_PUINT
 
  - Pointer to an unsigned integer.
 
  - AG_CELL_PLONG
 
  - Pointer to a long integer.
 
  - AG_CELL_PULONG
 
  - Pointer to a unsigned long integer.
 
  - AG_CELL_INT64
 
  - 64-bit integer (if 
HAVE_64BIT only). 
  - AG_CELL_PUINT8
 
  -  
 
  - AG_CELL_PSINT8
 
  -  
 
  - AG_CELL_PUINT16
 
  -  
 
  - AG_CELL_PSINT16
 
  -  
 
  - AG_CELL_PUINT32
 
  -  
 
  - AG_CELL_PSINT32
 
  -  
 
  - AG_CELL_PUINT64
 
  -  
 
  - AG_CELL_PSINT64
 
  - Pointer to an integer in specified format.
 
  - AG_CELL_PFLOAT
 
  -  
 
  - AG_CELL_PDOUBLE
 
  - Pointer to a floating-point number.
 
  - AG_CELL_POINTER
 
  - Generic pointer.
 
  - AG_CELL_FN_SU
 
  - Function returning a surface (see %[Fs]).
 
  - AG_CELL_FN_SU_NODUP
 
  - Function returning a surface that should not be freed (see %[FS]).
 
  - AG_CELL_FN_TXT
 
  - Function returning a text string.
 
  - AG_CELL_WIDGET
 
  - Embedded widget (see %[W]).
 
The following code fragment creates a table and immediately
    populates it:
AG_Table *tbl;
tbl = AG_TableNew(win, AG_TABLE_EXPAND);
AG_TableAddCol(tbl, "Column 1", "<ExpectedSize>", NULL);
AG_TableAddCol(tbl, "Column 2", NULL, NULL);
AG_TableAddRow(tbl, "%s:%i", "Item1", 123);
AG_TableAddRow(tbl, "%s:%i", "Item2", 456);
AG_TableAddRow(tbl, "%s:%i", "Item3", 789);
 
The following code fragment creates a table and arranges for
    periodical update of its contents from an
    UpdateMyTable() function:
void
UpdateMyTable(AG_Event *event)
{
	AG_Table *tbl = AG_TABLE_SELF();
	AG_TableBegin(tbl);
	AG_TableAddRow(tbl, "%s:%d", "foo", 1234);
	AG_TableEnd(tbl);
}
...
AG_Table *tbl;
tbl = AG_TableNewPolled(win, AG_TABLE_EXPAND, UpdateMyTable, NULL);
 
For more example usages, see tests/table.c
    in the Agar source distribution.
The AG_Table widget first appeared in Agar
    1.0.