IupTree - control

IUP - Portable User Interface

IupTree

Creates a tree containing nodes of branches or leaves. It inherits from IupCanvas.

The branches can be expanded or collapsed. When a branch is expanded, its immediate children are visible, and when it is collapsed they are hidden. The leaves can generate an executed or renamed action, branches can only generate renamed actions. Both branches and leaves can have an associated text. The selected node is the node with the focus rectangle, marked nodes have their background inverted.

Parameters/Return

Ihandle* IupTree(void); [in C] 
iuptree{} -> (elem: iuplua_tag) [in IupLua3]
iup.tree{} -> (elem: iuplua_tag) [in IupLua5]
tree() [in LED]

This function returns the identifier of the created IupTree, or NULL if an error occurs.

Attributes

General

SCROLLBAR FONT
ADDEXPANDED

Marks

CTRL
SHIFT
STARTING
VALUE
MARKED

Images

IMAGELEAF
IMAGEBRANCHCOLLAPSED
IMAGEBRANCHEXPANDED
IMAGEid
IMAGEEXPANDEDid

Nodes

NAME
STATE
DEPTH
KIND
PARENT
COLOR

Action

ADDLEAF
ADDBRANCH
DELNODE

REDRAW

Callbacks

SELECTION_CB: Action generated when an node is selected or deselected.
BRANCHOPEN_CB
: Action generated when a branch is expanded.
BRANCHCLOSE_CB
: Action generated when a branch is collapsed.
EXECUTELEAF_CB
: Action generated when a leaf is to be executed.
RENAMENODE_CB
: Action generated when a node is to be renamed.
RIGHTCLICK_CB
: Action generated when the right mouse button is pressed over a node.

Notes

Branches may be added in IupLua using a Lua Table (see Example 2). 

Hierarchy

Branches can contain other branches or leaves. The tree always has at least one branch, the root, which will be the parent of all the first level branches and leaves.

Structure

The IupTree is stored as a list, so that each node or branch has an associated identification number (id), starting by the root, with id=0. However, this number does not always correspond to the same node as the tree is modified. For example, a node with id 2 will always refer to the third node in the tree. For that reason, there is also userid, which allows identifying a specific node. The userid always refers to the same node (just as the associated text). The userid may contain a user-created structure allowing the identification of a node.

Each node also contains its depth level, starting by the root, which has depth 0. To allow inserting nodes in any position, sometimes the depth of a node must be explicitly changed. For instance, if you create a leaf in a child branch of the root, it will be created with depth 2. To make it become a child of the root, its depth must be set to 1.

Images

IupTree has three types of images: one associated to the leaf, one to the collapsed branch and the other to the expanded branch. Each image can be changed, both globally and individually.

The predefined images used in IupTree can be obtained by means of function IupGetHandle.The names of the predefined images are: IMGLEAF, IMGCOLLAPSED, IMGEXPANDED, IMGBLANK (blank sheet of paper) and IMGPAPER (written sheet of paper).

Scrollbar

IupTree’s scrollbar is activated by default and works automatically. When a node leaves the visible area, the scrollbar automatically scrolls so as to make it visible. We recommend not changing the SCROLLBAR attribute.

Fonts

The fonts used by IupTree are like the ones defined by IUP (see attribute FONT). We recommend using only IUP-defined fonts.

Manipulation

Node insertion or removal is done by means of attributes. It is allowed to remove nodes and branches inside callbacks associated to opening or closing branches.

This means that the user may insert nodes and branches only when necessary when the parent brach is opened, allowing the use of a larger IupTree without too much overhead. Then when the parent branch is closed the subtree can be removed. A side-effect of this use is that the expanded or collapsed state of the children branches must be managed by the user.

When a node is added, removed or renamed the tree is not automatically redrawn. You must set REDRAW=YES when you finish changing the tree.

Simple Marking

Is the IupTree’s default operation mode. In this mode only one node is marked, and it matches the selected node.

Multiple Marking

IupTree allows marking several nodes simultaneously using the Shift and Control keys. To use multiple marking, the user must use attributes SHIFT and CTRL.

When a user keeps the Control key pressed, the individual marking mode is used. This way, the selected node can be modified without changing the marked node. To reverse a node marking, the user simply has to press the space bar.

When the user keeps the Shift key pressed, the block marking mode is used. This way, all nodes between the selected node and the initial node are marked, and all others are unmarked. The initial node is changed every time a node is marked without the Shift key being pressed. This happens when any movement is done without Shift or Control being pressed, or when the space bar is pressed together with Control.

Removing a Node with "Del"

You can simply implement a K_ANY or KEYPRESS_CB and do:

int k_any(Ihandle* self, int c)
{
  if (c == K_DEL) 
  {
    IupSetAttribute(self,"DELNODE","MARKED");
    IupSetAttribute(self,"REDRAW","");
  }
  return IUP_DEFAULT;
}

Navigation

Using the keyboard:

  • Arrow Up/Down: Shifts the selected node to the neighbor node, according to the arrow direction.
  • Arrow Left/Right: Makes the branch collapse/expand
  • Home/End: Selects the root/last node.
  • Page Up/Page Down: Selects the node one page above/below the selected node.
  • Enter: If the selected node is an expanded branch, it is collapsed; if it is a collapsed branch, it is expanded; if it is a leaf, it is executed.
  • Space If the Control key is pressed marks or unmarks a node, if not calls the rename callback.

Using the mouse:

  • Clicking a node: Selects the clicked node.
  • Clicking a (-/+) box: Makes the branch to the right of the (-/+) box collapse/expand.
  • Clicking an empty region: Unmarks all nodes (including the selected one).
  • Double-clicking a node image: If the selected node is an expanded branch, it is collapsed; if it is a collapsed branch, it is expanded; if it is a leaf, it is executed.
  • Double-clicking a node text: Calls the rename callback.

Extra Functions

IupTree has functions that allow associating a pointer (or a user defined id) to a node. In order to do that, you provide the id of the node and the pointer (userid); even if the node's id changes later on, the userid will still be associated with the given node. In IupLua, instead of a pointer the same functions are defined for tables.

int IupTreeSetUserId(Ihandle *self, int id, void *userid); [in C]
IupTreeSetUserId(self: handle, id: number, userid: userdata); [in IupLua3]
iup.TreeSetUserId(self: handle, id: number, userid: userdata); [in IupLua5]

self: Identifier of the IupTree interacting with the user.
id: Node identifier.
userid: User pointer associated to the node. Use NULL value to free reference.

Note: This function needs to be called again freeing the node from the userdata or it will never be garbage collected.

void* IupTreeGetUserId(Ihandle *self, int id); [in C] 
IupTreeGetUserId(self: handle, id: number) -> (ret: userdata) [in IupLua3]
iup.TreeGetUserId(self: handle, id: number) -> (ret: userdata) [in IupLua5]

self: Identifier of the IupTree interacting with the user.
id: Node identifier.
Returns the pointer associated to the node.

int IupTreeGetId(Ihandle *self, void *userid); [in C] 
IupTreeGetId(self: handle, userid: userdata) -> (ret: number) [in IupLua3]
iup.TreeGetId(self: handle, userid: userdata) -> (ret: number) [in IupLua5]

self: Identifier of the IupTree interacting with the user.
userid: Pointer associated to the node.
Returns the id of the node on success and -1 on failure
.

IupTreeSetTableId(self: handle, id: number, table: table) [in IupLua3]
iup.TreeSetTableId(self: handle, id: number, table: table) [in IupLua5]

self: Identifier of the IupTree interacting with the user.
id: Node identifier.
table: Table that should be associated to the node or leaf. Use nil value to free reference.

Notes: This function needs to be called again freeing the node from the table or the table will never be garbage collected. Also, the user should not use the same table to reference different nodes (neither in the same nor across different trees.)

iup.TreeGetTableId(self: handle, table: table) -> (ret: number) [in IupLua3]
iup.TreeGetTableId(self: handle, table: table) -> (ret: number) [in IupLua5]

self: Identifier of the IupTree interacting with the user.
table: Table that should be associated to the node or leaf.
Returns the id of the node on success and nil otherwise.

iup.TreeGetTable(self: handle, id: number) -> (ret: table) [in IupLua3]
iup.TreeGetTable(self: handle, id: number) -> (ret: table) [in IupLua5]

self: Identifier of the IupTree interacting with the user.
id: Node identifier.
Returns the table of the node on success and nil otherwise.

Examples

Creates a IupTree with the values shown on the images below, and allows the user to change them dynamically.

iuptree_motif.gif (14Kb) iuptree_windows.gif (8Kb)

See Also

IupCanvas