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_TableSetSelectionColor
(AG_Table
*tbl, Uint8 r,
Uint8 g,
Uint8 b,
Uint8 a);
void
AG_TableSetSeparator
(AG_Table
*tbl, const char
*sep);
AG_MenuItem *
AG_TableSetPopup
(AG_Table
*tbl, int row,
int col);
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 (equivalent to invoking
AG_ExpandHoriz(3)).
- AG_TABLE_VFILL
- Expand vertically in parent (equivalent to invoking
AG_ExpandVert(3)).
- 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_TableSetSelectionColor
() sets the color
of the rectangle that will be blended onto selected cells, rows or columns
in order to indicate selection.
AG_TableSetSeparator
() changes the set of
accepted field-separator characters in
AG_TableAddRow
() (default is ":").
The AG_TableSetPopup
() function creates a
contextual
AG_Menu(3)
item associated with a row, column or cell. If col is
a valid index and row is -1, the menu is shown when
clicking on the header of the given column. If col is
-1 and row is a valid index, the menu is shown when
clicking on any cell of the given row. If col and
row are both valid indices, the menu is shown when
clicking on the given cell. If both indices are -1, the menu is shown when
clicking on any cell. If a contextual menu already exists for the specified
indices, AG_TableSetPopup
() returns a pointer to the
existing menu item.
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);
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.
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 occured. 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
occured. 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
- Unsigned integer
- %lu
- Unsigned long integer
- %llu
- 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, size_t 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 to insert into the table. The widget must have the
AG_WIDGET_TABLE_EMBEDDABLE
flag set or the
operation will fail. Note that for efficiency reasons,
AG_Table
is not treated like a standard widget
container, so widgets that are inserted into the table in this way should
not be attached to any parent (e.g., the parent
argument of standard constructor routines should be NULL). Embedded
widgets are automatically freed when cells are deleted.
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,
size_t 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
- Cell data type (see below).
- Uint id
- Optional user-specified ID or 0.
- Uint flags
- Option flags. If
AG_TABLE_CELL_NOCOMPARE
is set,
this cell will be ignored when comparing cells of a polled table against
the backing store in order to restore selection state.
- 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).
- int selected
- Column is selected (assuming column selection mode).
- int w
- Column width in pixels (read-only).
- int x
- Current column position (local widget coordinates).
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_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.