AG_Tlist
— agar
tree/list widget
#include <agar/core.h>
#include <agar/gui.h>
The AG_Tlist
widget shows a scrollable
tree / list of clickable and selectable items. Items can display text and
icons. Items include user-defined data fields (a signed integer
v, an unsigned integer u, a user
pointer p1 and a general-purpose category string
cat).
For cases where the contents of the tree or list may
change externally, a
polling routine
may be defined. Such a routine is expected to clear and repopulate the list
entirely. It may be run periodically at a specified interval, whenever user
interaction events occur, or by explicit call to
AG_TlistRefresh
().
To make polling more efficient (and to preserve per-item states such as
selections across polling cycles), AG_Tlist
relies
on a compare function to test items for equivalence and
reuse assets (including allocated structures and rendered text
surfaces).
AG_Tlist *
AG_TlistNew
(AG_Widget
*parent, Uint
flags);
AG_Tlist *
AG_TlistNewPolled
(AG_Widget
*parent, Uint
flags, void
(*eventFn)(AG_Event *),
const char *eventArgs,
...);
AG_Tlist *
AG_TlistNewPolledMs
(AG_Widget
*parent, Uint
flags, int ms,
void (*eventFn)(AG_Event
*), const char
*eventArgs,
...);
void
AG_TlistSetRefresh
(AG_Tlist
*tl, int ms);
void
AG_TlistRefresh
(AG_Tlist
*tl);
void
AG_TlistSetItemHeight
(AG_Tlist
*tl, int
item_height);
void
AG_TlistSetIconWidth
(AG_Tlist
*tl, int
icon_width);
void
AG_TlistSizeHint
(AG_Tlist
*tl, const char
*text, int
nItems);
void
AG_TlistSizeHintPixels
(AG_Tlist
*tl, int w,
int nItems);
void
AG_TlistSizeHintLargest
(AG_Tlist
*tl, int
nItems);
void
AG_TlistSetDblClickFn
(AG_Tlist
*tl, AG_EventFn fn,
const char *fn_args,
...);
void
AG_TlistSetChangedFn
(AG_Tlist
*tl, AG_EventFn fn,
const char *fn_args,
...);
AG_TlistNew
()
allocates, initializes, and attaches a AG_Tlist
widget.
The
AG_TlistNewPolled
()
variant enables AG_TLIST_POLL
and sets the specified
polling routine eventFn to run periodically (or -1 =
never). The polling routine is expected to clear and populate the
AG_Tlist
. The
AG_TlistNewPolledMs
() variant sets the update rate
to ms milliseconds.
Acceptable flags include:
- AG_TLIST_EXPAND_NODES
- Expand nodes with child items by default.
- AG_TLIST_MULTI
- Allow multiple selections (with ctrl/shift).
- AG_TLIST_MULTITOGGLE
- Enforce multiple selections (without ctrl/shift).
- AG_TLIST_POLL
- List contents are updated dynamically by the "tlist-poll"
handler. This handler is expected to wrap its
AG_TlistAdd
()
calls between AG_TlistBegin
() and
AG_TlistEnd
(). Implied by
AG_TlistNewPolled
().
- AG_TLIST_FIXED_HEIGHT
- Don't reset the item height on "font-changed".
- AG_TLIST_NO_LINES
- Don't draw lines between nodes.
- AG_TLIST_NO_KEYREPEAT
- Disable keyrepeat behavior.
- AG_TLIST_NO_SELECTED
- Don't raise "tlist-selected" on select.
- AG_TLIST_STATELESS
- When using
AG_TLIST_POLL
, don't preserve selection
information across list updates.
- AG_TLIST_HFILL
- Expand horizontally in parent container.
- AG_TLIST_VFILL
- Expand vertically in parent container.
- AG_TLIST_EXPAND
- Shorthand for
AG_TLIST_HFILL
|
AG_TLIST_VFILL
.
AG_TlistSetRefresh
()
sets the rate at which the polling routine will be invoked in milliseconds
(default = 1s). A value of -1 disables automatic updates. When automatic
updates are disabled, updates can be performed by calling
AG_TlistRefresh
(). See the
AG_TLIST_POLL
option for details.
AG_TlistSetItemHeight
()
sets the given, uniform height of all items.
AG_TlistSetIconWidth
() sets the width of item icons
in pixels.
AG_TlistSizeHint
()
requests sufficient height to display nItems items at
once, and sufficient width to display an item containing
text. The
AG_TlistSizeHintPixels
() variant accepts a width
argument in pixels instead of a string and the
AG_TlistSizeHintLargest
() variant uses the largest
text label in the current list of items to determine the width.
AG_TlistSetDblClickFn
()
arranges for the given callback fn to be invoked with
the given arguments (as well as the item pointer) when the user double
clicks on an item.
AG_TlistSetChangedFn
()
arranges for the callback fn to be invoked when the
user selects or deselects an item. The arguments are respectively, a pointer
to the item and an integer with a value of 0 to indicate deselection and 1
to indicate selection.
AG_TlistCompareFn
AG_TlistSetCompareFn
(AG_Tlist
*tl, AG_TlistCompareFn
fn);
int
AG_TlistCompareInts
(const
AG_TlistItem *a, const AG_TlistItem *b));
int
AG_TlistCompareUints
(const
AG_TlistItem *a, const AG_TlistItem *b));
int
AG_TlistCompareStrings
(const
AG_TlistItem *a, const AG_TlistItem *b));
int
AG_TlistComparePtrs
(const
AG_TlistItem *a, const AG_TlistItem *b));
int
AG_TlistComparePtrsAndCats
(const
AG_TlistItem *a, const AG_TlistItem *b));
In order for
AG_Tlist |
to be able to preserve per-item states (such as selections) through
polling updates when using a polling function, it is necessary to be able
to establish equivalence between items. The nature of this equivalence is
application-defined and is determined by the compare
function selected. The
AG_TlistUniq ();
routine (see below) also relies on the compare function.
AG_TlistSetCompareFn ();
sets the comparison function to use when testing between two
AG_TlistItem for equivalence. It returns a pointer
to the previously selected compare function. Compare functions are
defined as:
typedef int (*AG_TlistCompareFn)(const AG_TlistItem *a,
const AG_TlistItem *b);
It is expected to return 0 if the two items are equivalent and
non-zero if the items are not. If the returned value if non-zero, it can
be used to define the sorting order. Returning a positive value in the
case where (a > b) should produce a sort in descending order.
Some basic compare functions are provided:
AG_TlistCompareInts ();
compares the signed integer field v1.
AG_TlistCompareUints ();
compares the unsigned integer field u.
AG_TlistCompareStrings ();
compares the text strings lexicographically. The
comparison is case-sensitive and ignores any locale collation.
AG_TlistComparePtrs ();
compares the pointer fields p1. This is the
default compare function.
AG_TlistComparePtrsAndCats ();
compares both p1 and the category
cat.
|
AG_TlistItem *
AG_TlistAdd
(AG_Tlist
*tl, const AG_Surface
*icon, const char
*format, ...);
AG_TlistItem *
AG_TlistAddS
(AG_Tlist
*tl, const AG_Surface
*icon, const char
*text);
AG_TlistItem *
AG_TlistAddHead
(AG_Tlist
*tl, const AG_Surface
*icon, const char
*format, ...);
AG_TlistItem *
AG_TlistAddHeadS
(AG_Tlist
*tl, const AG_Surface
*icon, const char
*text);
AG_TlistItem *
AG_TlistAddPtr
(AG_Tlist
*tl, const AG_Surface
*icon, const char
*text, const void
*p1);
AG_TlistItem *
AG_TlistAddPtrHead
(AG_Tlist
*tl, const AG_Surface
*icon, const char
*text, const void
*p1);
void
AG_TlistMoveToHead
(AG_Tlist
*tl, AG_TlistItem
*item);
void
AG_TlistMoveToTail
(AG_Tlist
*tl, AG_TlistItem
*item);
void
AG_TlistSetIcon
(AG_Tlist
*tl, AG_TlistItem
*item, const AG_Surface
*icon);
void
AG_TlistSetColor
(AG_Tlist
*tl, AG_TlistItem
*item, const AG_Color
*color);
void
AG_TlistSetFont
(AG_Tlist
*tl, AG_TlistItem
*item, const char
*face, float scale,
Uint flags);
void
AG_TlistDel
(AG_Tlist
*tl, AG_TlistItem
*item);
void
AG_TlistSort
(AG_Tlist
*tl);
void
AG_TlistSortByInt
(AG_Tlist
*tl);
void
AG_TlistUniq
(AG_Tlist
*tl);
void
AG_TlistClear
(AG_Tlist
*tl);
void
AG_TlistBegin
(AG_Tlist
*tl);
void
AG_TlistEnd
(AG_Tlist
*tl);
int
AG_TlistVisibleChildren
(AG_Tlist
*tl, AG_TlistItem
*item);
void
AG_TlistSelect
(AG_Tlist
*tl, AG_TlistItem
*item);
void
AG_TlistSelectIdx
(AG_Tlist
*tl, Uint
index);
void
AG_TlistSelectAll
(AG_Tlist
*tl);
void
AG_TlistDeselect
(AG_Tlist
*tl, AG_TlistItem
*item);
void
AG_TlistDeselectIdx
(AG_Tlist
*tl, Uint
index);
void
AG_TlistDeselectAll
(AG_Tlist
*tl);
AG_TlistItem *
AG_TlistSelectPtr
(AG_Tlist
*tl, void
*ptr);
AG_TlistItem *
AG_TlistSelectText
(AG_Tlist
*tl, const char
*text);
AG_TlistItem *
AG_TlistFindByIndex
(AG_Tlist
*tl, int
index);
AG_TlistItem *
AG_TlistSelectedItem
(AG_Tlist
*tl);
void *
AG_TlistSelectedItemPtr
(AG_Tlist
*tl);
void *
AG_TLIST_ITEM
(idx);
int
AG_TlistFindPtr
(AG_Tlist
*tl, void **p);
AG_TlistItem *
AG_TlistFindText
(AG_Tlist
*tl, const char
*text);
AG_TlistItem *
AG_TlistFirstItem
(AG_Tlist
*tl);
AG_TlistItem *
AG_TlistLastItem
(AG_Tlist
*tl);
void
AG_TlistScrollToStart
(AG_Tlist
*tl);
void
AG_TlistScrollToEnd
(AG_Tlist
*tl);
void
AG_TlistScrollToSelection
(AG_Tlist
*tl);
AG_TlistAdd
()
inserts a newly-allocated item into the list and returns a pointer to it. If
icon is not NULL, it specifies an
AG_Surface(3)
to duplicate and display as an icon.
The
AG_TlistAddHead
()
variant places the item at the head of the list. The
AG_TlistAddPtr
() variant of
AG_TlistAdd
() also sets the pointer field
p1 on initialization.
AG_TlistAddPtrHead
()
places the item at the head of the list.
AG_TlistMoveToHead
()
moves an existing item item to the head of the list.
AG_TlistMoveToTail
() moves an existing item
item to the tail of the list.
AG_TlistSetIcon
()
sets the icon surface associated with item. A
duplicate of the given surface will be used.
AG_TlistSetColor
()
sets an alternate text color for the specified item (or NULL to switch back
to the default).
AG_TlistSetFont
()
sets an alternate font for the specified item. If face
is NULL, use the same font face as the tlist's font.
scale sets the size of the font relative to the
tlist's font. If scale is 1.0f then the same size will
be used. The flags argument is the set of
AG_Font(3)
style flags (such as AG_FONT_BOLD
).
The
AG_TlistDel
()
function detaches and frees item from its parent
tl
.
The
AG_TlistSort
()
routine lexicographically sorts the items in the list by text according to
the current locale collation.
AG_TlistSortByInt
()
sorts items based on their integer values v.
AG_TlistUniq
()
scans the list for duplicates and removes them.
AG_TlistUniq
() uses the compare function to
determine equivalence between items (see
AG_TlistSetCompareFn
()).
AG_TlistClear
()
removes all items attached to the list.
The
AG_TlistBegin
()
function removes all items attached to tl, but
remembers their selection and child item expansion states.
AG_TlistEnd
() compares each item against the saved
state and restores the selection and child item expansion states
accordingly.
The
AG_TlistVisibleChildren
()
function is meant to be called from a polling routine. It tests whether a
newly-created item should make its own child items
visible based on the previously saved state. If there are no matching items
in the saved state (according to the Compare function), then it returns the
default visibility setting (which is 1 if the
AG_TLIST_EXPAND_NODES
option is set, otherwise
0).
AG_TlistSelect
()
sets the selection flag on item (clearing any previous
selection unless AG_TLIST_MULTI
is set).
AG_TlistDeselect
() clears the selection flag on
item. AG_TlistSelectIdx
() and
AG_TlistDeselectIdx
() reference the target
AG_TlistItem by index rather than by pointer.
AG_TlistSelectAll
()
AG_TlistDeselectAll
() sets / clears the selection on
all items attached to tl.
The
AG_TlistSelectPtr
()
function selects and returns the first item with a user pointer value
matching ptr. Similarly,
AG_TlistSelectText
() selects and returns the first
item with a text field equal to text. Both of these
functions invoke "tlist-poll" if the
AG_TLIST_POLL
option is set.
The
AG_TlistFindByIndex
()
function returns the item at index, or NULL if there
is no such item. The AG_TlistSelectedItem
() function
returns the first selected item, or NULL if there are none.
The
AG_TlistSelectedItemPtr
()
function returns the user pointer of the first selected item, or NULL if
there is no selected item. It is not possible to distinguish a non-existent
selection from an actual selection with a NULL user pointer using this
function.
In event handler context, the
AG_TLIST_ITEM
()
macro is a shortcut for AG_TlistSelectedItemPtr
() on
item n from the event stack.
The
AG_TlistFindPtr
()
variant copies the user pointer associated with the first selected item into
p, returning 0 on success or -1 if there is no item
selected. The AG_TlistFindText
() function searches
tl for an item containing the
text string and returns NULL if there is no such
item.
The
AG_TlistFirstItem
()
and AG_TlistLastItem
() functions return the first
and last items on the list.
AG_TlistScrollToStart
()
scrolls the display to the start and
AG_TlistScrollToEnd
() scrolls the display to the end
of the list.
AG_TlistScrollToSelection
()
scrolls to make the first selected item visible. It's a no-op if there are
no selected items.
AG_MenuItem *
AG_TlistSetPopupFn
(AG_Tlist
*tl, AG_EventFn fn,
const char *fn_args,
...);
The AG_Tlist
widget generates the
following events:
tlist-changed
(AG_TlistItem
*item, int state)
- item was selected or unselected.
tlist-selected
(AG_TlistItem
*item)
- item was selected.
tlist-dblclick
(AG_TlistItem
*item)
- The user just double-clicked item. Binding to this
event is equivalent to using
AG_TlistSetDblClickFn
().
tlist-return
(AG_TlistItem
*item)
- The user has selected item and pressed the return
key.
tlist-poll
(void)
- The
AG_TLIST_POLL
flag is set and the widget is
about to be drawn or an event is being processed.
The AG_Tlist
widget provides the following
bindings:
- void *selected
- The p1 (user pointer) value of the selected item, or
NULL if there is no selection. The value of this binding is undefined if
the
AG_TLIST_MULTI
or
AG_TLIST_MULTITOGGLE
flags are in use.
For the AG_Tlist object:
- TAILQ items
- The list of items (linkage is read-only).
- int nItems
- Number of items in total (read-only).
- int nVisible
- Number of items on screen (read-only).
- Uint pollDelay
- Delay in between updates in
AG_TLIST_POLL
mode
(ms).
For the AG_TlistItem structure:
- int selected
- Selection flag.
- void *p1
- User pointer (application-defined).
- int v
- User signed integer value (application-defined).
- Uint u
- User unsigned integer value (application-defined).
- const char *cat
- Category string (application-defined).
- char text[]
- Text label (up to
AG_TLIST_LABEL_MAX
characters).
- int depth
- Depth in tree (0 = root).
- Uint flags
- Item flags (see ITEM FLAGS section
below).
- float scale
- Scaling factor for text display (default = 1.0).
- AG_TLIST_ITEM_DISABLED
- Disable selection and draw in DISABLED style.
- AG_TLIST_NO_SELECT
- Disable selection and draw in DEFAULT style.
- AG_TLIST_ITEM_EXPANDED
- Child items are visible.
- AG_TLIST_HAS_CHILDREN
- At least one child item exists.
- AG_TLIST_NO_POPUP
- Disable popup menus (if any have been created).
The following code fragment displays an external tree structure
using a recursive polling routine.
MyTreeNode *myTreeRoot;
AG_Window *win;
static void
PollMyTreeNode(AG_Tlist *tl, MyTreeNode *node, int depth)
{
AG_TlistItem *ti;
ti = AG_TlistAdd(tl, NULL, "Node %s", node->name);
ti->flags |= AG_TLIST_HAS_CHILDREN;
ti->p1 = node;
ti->depth = depth;
if (AG_TlistVisibleChildren(tl, ti)) {
MyTreeNode *child;
LIST_FOREACH(child, &node->children, children)
PollMyTreeNode(tl, child, depth+1);
}
}
static void
PollMyTree(AG_Event *event)
{
AG_Tlist *tl = AG_TLIST_SELF();
MyTreeNode *root = AG_PTR(1);
AG_TlistBegin(tl);
PollMyTreeNode(tl, root, 0);
AG_TlistEnd(tl);
}
myTreeRoot = InitMyTree();
win = AG_WindowNew(0);
AG_TlistNewPolled(win, 0, PollMyTree, "%p", myTreeRoot);
The AG_Tlist
widget first appeared in Agar
1.0. AG_TlistSelectIdx
(),
AG_TlistDeselectIdx
(),
AG_TlistSetColor
() and
AG_TlistSetFont
() appeared in Agar 1.6.0. Options
AG_TLIST_EXPAND_NODES
,
AG_TLIST_FIXED_HEIGHT
,
AG_TLIST_NO_LINES
,
AG_TLIST_NO_KEYREPEAT
and the per-item flag
AG_TLIST_ITEM_DISABLED
appeared in Agar 1.7.0. The
u and v integer fields and
AG_TlistCompareInts
() and
AG_TlistCompareUints
() appeared in Agar 1.7.0.