.\" Copyright (c) 2006-2008 Hypertriton, Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
.\" (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd June 26, 2006
.Dt AG_TABLE 3
.Os
.ds vT Agar API Reference
.ds oS Agar 1.0
.Sh NAME
.Nm AG_Table
.Nd agar table display widget
.Sh SYNOPSIS
.Bd -literal
#include
#include
.Ed
.Sh DESCRIPTION
The
.Nm
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.
.Nm
is optimized for tables that must be rebuilt frequently.
Individual cells, entire rows or entire columns can be selected indepedently.
.Pp
Note that another table display widget,
.Xr AG_Treetbl 3 ,
is also available.
It stores row information in a tree structure and provides a very different
interface from
.Nm .
.Sh INHERITANCE HIERARCHY
.Xr AG_Object 3 ->
.Xr AG_Widget 3 ->
.Nm .
.Sh INITIALIZATION
.nr nS 1
.Ft "AG_Table *"
.Fn AG_TableNew "AG_Widget *parent" "Uint flags"
.Pp
.Ft "AG_Table *"
.Fn AG_TableNewPolled "AG_Widget *parent" "Uint flags" "void (*event_fn)(AG_Event *)" "const char *event_args" "..."
.Pp
.Ft "void"
.Fn AG_TableSizeHint "AG_Table *tbl" "int width" "int nrows"
.Pp
.Ft "void"
.Fn AG_TableSetColHeight "AG_Table *tbl" "int height"
.Pp
.Ft "void"
.Fn AG_TableSetRowHeight "AG_Table *tbl" "int height"
.Pp
.Ft "void"
.Fn AG_TableSetColMin "AG_Table *tbl" "int width"
.Pp
.Ft "void"
.Fn AG_TableSetDefaultColWidth "AG_Table *tbl" "int width"
.Pp
.Ft "void"
.Fn AG_TableSetSelectionMode "AG_Table *tbl" "enum ag_table_selmode mode"
.Pp
.Ft "void"
.Fn AG_TableSetSelectionColor "AG_Table *tbl" "Uint8 r" "Uint8 g" "Uint8 b" "Uint8 a"
.Pp
.Ft "void"
.Fn AG_TableSetSeparator "AG_Table *tbl" "const char *sep"
.Pp
.Ft "AG_MenuItem *"
.Fn AG_TableSetPopup "AG_Table *tbl" "int row" "int col"
.Pp
.Ft "void"
.Fn AG_TableSetRowDblClickFn "AG_Table *tbl" "AG_EventFn fn" "const char *fn_args" "..."
.Pp
.Ft "void"
.Fn AG_TableSetColDblClickFn "AG_Table *tbl" "AG_EventFn fn" "const char *fn_args" "..."
.Pp
.nr nS 0
The
.Fn AG_TableNew
function allocates, initializes and attaches a new
.Nm
widget.
.Pp
The
.Fn AG_TableNewPolled
variant sets the polling flag and configures the
.Sq table-poll
event.
.Fa event_fn
is a pointer to the event-handler function responsible for entering the
values into the table.
.Fa event_args
and the following arguments are optional
.Xr AG_Event 3
style parameters that will be passed on to
.Fa event_fn .
.Pp
Acceptable values for the
.Fa flags
argument include:
.Pp
.Bl -tag -width "AG_TABLE_HIGHLIGHT_COLS "
.It AG_TABLE_MULTI
Allow the user to select multiple items while holding
.Dv CTRL
or
.Dv SHIFT .
.It AG_TABLE_MULTITOGGLE
Allow the user to select multiple items without holding
.Dv CTRL
or
.Dv SHIFT .
.It AG_TABLE_POLL
Table contents are updated dynamically by the
.Sq table-poll
event handler (implied by
.Fn AG_TableNewPolled ) .
.It 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.
.It AG_TABLE_HIGHLIGHT_COLS
Highlight the currently selected column(s) using transparency.
.El
.Pp
The
.Fn AG_TableSizeHint
function requests an initial sizing, where
.Fa width
is the width in pixels and
.Fa nrows
is the number of rows to display.
.Pp
.Fn AG_TableSetColHeight
sets the size of column headers in pixels.
.Fn AG_TableSetRowHeight
sets the size of rows in pixels.
In both cases, the default is dependent on the height of the default font.
.Pp
.Fn 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,
.Fn AG_TableSetColMin
will resize them.
.Pp
.Fn AG_TableSetDefaultColWidth
specifies a "default" width in pixels, to use during initial size requisition
for columns using FILL or a size specification in "%".
.Pp
.Fn AG_TableSetSelectionMode
defines the effect of cursor selections on the table.
Possible values for
.Fa mode
are:
.Bd -literal
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 */
};
.Ed
.Pp
.Fn AG_TableSetSelectionColor
sets the color of the rectangle that will be blended onto selected cells, rows
or columns in order to indicate selection.
.Pp
.Fn AG_TableSetSeparator
changes the set of accepted field-separator characters in
.Fn AG_TableAddRow
(default is ":").
.Pp
The
.Fn AG_TableSetPopup
function creates a new popup menu associated with a row, column or cell.
If
.Fa col
is a valid index and
.Fa row
is -1, the menu is shown when clicking on the header of the given column.
If
.Fa col
is -1 and
.Fa row
is a valid index, the menu is shown when clicking on any cell of the given row.
If
.Fa col
and
.Fa 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.
.Pp
The
.Fn AG_TableSetRowDblClickFn ,
.Fn AG_TableSetColDblClickFn
and
.Fn AG_TableSetCellDblClickFn
functions register a callback routine to invoke upon double-click on a
row, column or cell, respectively, depending on the current selection mode.
The callback routine for
.Fn AG_TableSetRowDblClickFn
is passed the row index as an
.Ft int
argument.
.Fn AG_TableSetColDblClickFn
is passed the column index and
.Fn AG_TableSetCellDblClickFn
is passed the row and column indices in order.
.Sh TABLE FUNCTIONS
.nr nS 1
.Ft "void"
.Fn AG_TableBegin "AG_Table *tbl"
.Pp
.Ft "void"
.Fn AG_TableEnd "AG_Table *tbl"
.Pp
.nr nS 0
.Nm
is aimed at tables with dynamic content that has to be respecified
frequently.
To achieve this, rows must be specified between calls to
.Fn AG_TableBegin
and
.Fn AG_TableEnd .
.Pp
The
.Fn AG_TableBegin
function saves current selection information (to keep selections consistent
across table respecifications), and clears all rows.
.Pp
Since dynamic tables that are respecified periodically usually exhibit high
temporal coherence,
.Fn AG_TableBegin
actually moves existing rows to a pool for possible reuse, to avoid
unnecessary text rendering (and texture uploads in OpenGL mode).
.Sh COLUMN FUNCTIONS
.nr nS 1
.Ft "int"
.Fn AG_TableAddCol "AG_Table *tbl" "const char *name" "const char *size_spec" "int (*sort_fn)(const void *, const void *)"
.Pp
.Ft "void"
.Fn AG_TableSelectCol "AG_Table *tbl" "int col"
.Pp
.Ft "void"
.Fn AG_TableDeselectCol "AG_Table *tbl" "int col"
.Pp
.Ft "void"
.Fn AG_TableSelectAllCols "AG_Table *tbl"
.Pp
.Ft "void"
.Fn AG_TableDeselectAllCols "AG_Table *tbl"
.Pp
.Ft "int"
.Fn AG_TableColSelected "AG_Table *tbl" "int col"
.Pp
.nr nS 0
The
.Fn AG_TableAddCol
function inserts a new column into the table and returns an integer column
identifier.
.Fa name
specifies the text to display in the column header.
.Fa size_spec
is an optional size specification (see
.Xr AG_SizeSpec 3 )
used in initial sizing of the column.
.Fa sort_fn ,
if not NULL, is the compare function to use for items of this column.
It is passed pointers to two
.Ft AG_TableCell
structures to compare.
.Pp
The
.Fn AG_TableSelectCol
and
.Fn AG_TableDeselectCol
functions control the selection flag on the given column.
.Fn AG_TableSelectAllCols
and
.Fn AG_TableDeselectAllCols
set the selection flag on all columns of the table.
.Fn AG_TableColSelected
returns 1 if the given column is selected, 0 otherwise.
.Pp
Note that the of the column selection flags are independent from the
selection flag of individual cells; their meaning is application-specific.
.Pp
.Sh ROW FUNCTIONS
.nr nS 1
.Ft "int"
.Fn AG_TableAddRow "AG_Table *tbl" "const char *fmt" "..."
.Pp
.Ft "void"
.Fn AG_TableSelectRow "AG_Table *tbl" "Uint row"
.Pp
.Ft "void"
.Fn AG_TableDeselectRow "AG_Table *tbl" "Uint row"
.Pp
.Ft "void"
.Fn AG_TableSelectAllRows "AG_Table *tbl"
.Pp
.Ft "void"
.Fn AG_TableDeselectAllRows "AG_Table *tbl"
.Pp
.Ft "void"
.Fn AG_TableRowSelected "AG_Table *tbl" "Uint row"
.Pp
.nr nS 0
The
.Fn AG_TableAddRow
function inserts a new row into the table.
The
.Fa fmt
argument describes the individual fields (or cells) of this row.
By default, the fields are comma-separated (the separator can be changed
using
.Fn 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.
.Pp
Acceptable specifiers include:
.Pp
.Bl -tag -width "%[s8], %[s16], %[s32] "
.It %s
Text string
.It %i, %d
Signed integer
.It %li, %ld
Long integer
.It %lli, %lld
Long long integer
.It %u
Unsigned integer
.It %lu
Unsigned long integer
.It %llu
Unsigned long long integer
.It %[s8], %[s16], %[s32]
Signed 8-bit, 16-bit or 32-bit value
.It %[u8], %[u16], %[u32]
Unsigned 8-bit, 16-bit or 32-bit value
.It %f, %g
Floating-point value (precision modifiers like %.03f are accepted)
.It %p
User pointer (usually stored in hidden columns)
.It %[Ft]
User-specified function of the form:
.Pp
.Ft "void"
.Fn MyTextFn "void *tbl" "char *buf" "size_t len"
.Pp
The text copied into
.Fa buf
(which is
.Fa len
bytes in size) will be displayed in the cell.
.It %[Fs]
User-specified function of the form:
.Pp
.Ft "AG_Surface *"
.Fn MySurfFn "void *tbl" "int x" "int y"
.Pp
The returned
.Xr AG_Surface 3
will be displayed in the cell.
The
.Fa x
and
.Fa y
parameters can be ignored.
.It %[W]
An arbitrary widget to insert into the table.
Note that for efficiency reasons,
.Nm
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
.Fa parent
argument of standard constructor routines should be NULL).
.El
.Pp
The functions
.Fn AG_TableSelectRow
and
.Fn AG_TableDeselectRow
set the selection flag on all cells of the given row.
.Fn AG_TableSelectAllRows
and
.Fn AG_TableDeselectAllRows
set the selection on all cells of the table.
.Fn AG_TableRowSelected
returns 1 if the given row is selected, 0 otherwise.
.Sh CELL FUNCTIONS
.nr nS 1
.Ft "void"
.Fn AG_TableSelectCell "AG_Table *tbl" "Uint row" "Uint col"
.Pp
.Ft "void"
.Fn AG_TableDeselectCell "AG_Table *tbl" "Uint row" "Uint col"
.Pp
.Ft "void"
.Fn AG_TableCellSelected "AG_Table *tbl" "Uint row" "Uint col"
.Pp
.Ft "void"
.Fn AG_TableCompareCells "const AG_TableCell *c1" "const AG_TableCell *c2"
.Pp
.nr nS 0
.Fn AG_TableSelectCell ,
.Fn AG_TableDeselectCell
and
.Fn AG_TableCellSelected
control and query the selection flag on an individual cell located at the
given row and column.
.Pp
The
.Fn AG_TableCompareCells
function compares cells
.Fa c1
and
.Fa 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
.Xr 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.
.Sh MISCELLANEOUS FUNCTIONS
.nr nS 1
.Ft "int"
.Fn AG_TableSaveASCII "AG_Table *tbl" "FILE *f" "char separator"
.Pp
.nr nS 0
.Fn AG_TableSaveASCII
writes the formatted contents of the table into an ASCII file
.Fa f .
Each row is separated by a newline, and cells are separated by the character
given by the
.Fa separator
argument.
Non-text cells are skipped.
The function returns 0 on success, -1 on failure.
.Pp
.Sh EVENTS
The
.Nm
widget reacts to the following events:
.Pp
.Bl -tag -compact -width "window-mousebuttondown"
.It window-mousemotion
Process resizing actions in progress.
.It window-keydown
By default,
.Dv SDLK_UP ,
.Dv SDLK_DOWN ,
.Dv SDLK_PAGEUP
and
.Dv SDLK_PAGEDOWN
will move the current single-row selection.
.It window-mousebuttonup
Stop any resizing action in progress.
.It window-mousebuttondown
.Dv SDL_BUTTON_LEFT
selects the overlapping column, row or cell.
.Dv SDL_BUTTON_RIGHT
works similarly, but displays the popup menu associated with the
selected column or cell, as configured with
.Fn AG_TableSetPopup .
.Dv SDL_BUTTON_WHEELUP
and
.Dv SDL_BUTTON_WHEELDOWN
are used to scroll the view of the table.
.El
.Pp
The
.Nm
widget does not generate any event.
.Sh STRUCTURE DATA
For the
.Ft AG_Table
object:
.Pp
.Bl -tag -compact -width "Uint n "
.It Ft Uint n
Number of columns (read-only).
.It Ft Uint m
Number of rows (read-only).
.El
.Sh EXAMPLES
The following code fragment creates a table and immediately populates it:
.Pp
.Bd -literal -offset indent
AG_Table *tbl;
tbl = AG_TableNew(win, AG_TABLE_EXPAND);
AG_TableAddCol(tbl, "Column 1", "", 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);
.Ed
.Pp
The following code fragment creates a table and arranges for periodical
update of its contents from an
.Fn UpdateMyTable
function:
.Pp
.Bd -literal -offset indent
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);
.Ed
.Pp
For more example usages, see
.Pa demos/table
in the Agar source distribution.
.Sh SEE ALSO
.Xr AG_Intro 3 ,
.Xr AG_Surface 3 ,
.Xr AG_Widget 3 ,
.Xr AG_Window 3
.Sh HISTORY
The
.Nm
widget first appeared in Agar 1.0.