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.

Creation

Ihandle* IupTree(void); [in C] 
iuptree{} -> (elem: ihandle) [in IupLua3]
iup.tree{} -> (elem: ihandle) [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
SHOWDRAGDROP
SHOWRENAME
RENAMECARET
RENAMESELECTION

Marks

CTRL
SHIFT
STARTING
VALUE
MARKED

Images

IMAGELEAF
IMAGEBRANCHCOLLAPSED
IMAGEBRANCHEXPANDED
IMAGEid
IMAGEEXPANDEDid

Nodes

NAME
STATE
DEPTH
KIND
PARENT
COLOR

Action

ADDLEAF
ADDBRANCH
DELNODE

REDRAW
RENAMENODE

Callbacks

SELECTION_CB: Action generated when an node is selected or deselected.
MULTI
SELECTION_CB
: Action generated when multiple nodes are selected with the mouse and the shift key pressed.
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.
RENAME_CB
: Action generated when a node new name was entered.
SHOW
RENAME_CB
: Action generated when a new name is about to be entered.
DRAGDROP_CB
: Action generated when a drag & drop is executed.
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.

Colors

The IupTree colors are fixed by definition. The tree background color is "255 255 255" in Windows and "156 156 165" in Motif. The tree selected node color is "8 33 107" in Windows and "0 0 156" in Motif.

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.
  • Ctrl+Space Marks or unmarks a node.
  • F2: Calls the rename callback or invoke the inplace rename.

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 or invoke the inplace rename.

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: ihandle, id: number, userid: userdata) [in IupLua3]
iup.TreeSetUserId(self: ihandle, 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: ihandle, id: number) -> (ret: userdata) [in IupLua3]
iup.TreeGetUserId(self: ihandle, 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: ihandle, userid: userdata) -> (ret: number) [in IupLua3]
iup.TreeGetId(self: ihandle, 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: ihandle, id: number, table: table) [in IupLua3]
iup.TreeSetTableId(self: ihandle, 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: ihandle, table: table) -> (ret: number) [in IupLua3]
iup.TreeGetTableId(self: ihandle, 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: ihandle, id: number) -> (ret: table) [in IupLua3]
iup.TreeGetTable(self: ihandle, 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.

Utility Functions

These functions can be used to help set and get attributes from the matrix:

void  IupTreeSetAttribute (Ihandle *n, char* a, int id, char* v);
void  IupTreeStoreAttribute(Ihandle *n, char* a, int id, char* v);
char* IupTreeGetAttribute (Ihandle *n, char* a, int id);
int   IupTreeGetInt (Ihandle *n, char* a, int id);
float IupTreeGetFloat (Ihandle *n, char* a, int id);
void  IupTreeSetfAttribute (Ihandle *n, char* a, int id, char* f, ...);

They work just like the respective tradicional set and get functions. But the attribute string is complemented with the L and C values. For ex:

IupTreeSetAttribute(n, "KIND" , 30, v) = IupSetAttribute(n, "KIND30", v)
IupTreeSetAttribute(n, "ADDLEAF" , 10, v) = IupSetAttribute(n, "ADDLEAF10", v)

See also the IupTreeUtil by Sergio Maffra and Frederico Abraham. It is an utility wrapper in C++ for the IupTree.

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