kmx > IUP-0.101 > IUP::Tree

Download:
IUP-0.101.tar.gz

Dependencies

Annotate this POD

CPAN RT

Open  0
View/Report Bugs
Source   Latest Release: IUP-0.202_1

NAME ^

IUP::Tree - [GUI element] tree containing nodes of branches or leaves with associated text/image

DESCRIPTION ^

Creates a tree containing nodes of branches or leaves. Both branches and leaves can have an associated text and image.

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" actions, branches can only generate a "renamed" action.

The focus node is the node with the focus rectangle, marked nodes have their background inverted.

GTK Motif Windows

USAGE ^

CREATION - new() method

 $tree = IUP::Tree->new( TITLE=>'Root node name' );

Returns: the identifier of the created element, or undef if an error occurs.

NOTE: You can pass to new() other ATTRIBUTE=>'value' or CALLBACKNAME=>\&func pairs relevant to this element - see IUP::Manual::02_Elements.

Tree - Hierarchy

Branches can contain other branches or leaves. When ADDROOT=Yes the tree has initially one branch, the root. The first node always has id=0 and depth=0. The tree nodes have a sequential identification number (id), starting by the first, with id=0, and increases for each node independent from the node depth. The following picture illustrates the numbering of the nodes in a tree.

Tree nodes and Ids:

Since you have to add each node the creation of this tree can be done in several ways because the action attributes ADD* and INSERT* use an existent node to position the new node. The following pseudo code initializes the tree from top to bottom sequencially:

 TITLE0 = "Figures"
   ADDLEAF0 = "Other"    // Use the previous node as reference
   ADDBRANCH1 = "triangle"
     ADDLEAF2 = "equilateral"
     ADDLEAF3 = "isoceles"
     ADDLEAF4 = "scalenus"
   INSERTBRANCH2 = "parallelogram"  // Use the previous node at the same depth as reference
     ADDLEAF6 = "square"
     ADDLEAF7 = "diamond"
   INSERTBRANCH6 = "2D"
   INSERTBRANCH9 = "3D"

The following pseudo code initializes the tree from bottom to top sequentially (except for branches), and also uses the focus node:

 VALUE = 0  // Set the focus node at the first (default for a new element)
 TITLE = "Figures"
 ADDBRANCH = "3D"
 ADDBRANCH = "2D"
 ADDBRANCH = "parallelogram"
 ADDLEAF1 = "diamond"
 ADDLEAF1 = "square"
 ADDBRANCH = "triangle"
 ADDLEAF1 = "scalene"
 ADDLEAF1 = "isosceles"
 ADDLEAF1 = "equilateral"
 ADDLEAF = "Other"

Notice that in both cases the initialization of the tree is highly dependent on the order of the operations. Currently we can NOT garantie the order before mapping to the native system, so the initialization must be performed after the tree is mapped.

Scrollbars are automatically displayed if the tree is greater than its display area.

Branches may be added in IUP::Lua using a Lua Table, see iup.TreeAddNodes.

Tree - 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 branch is opened, allowing the use of a larger IUP::Tree without too much overhead. Then when the parent branch is closed the subtree can be removed. But the subtree must have at least 1 node so the branch can be opened and closed, empty branches can NOT be opened.

Tree - User Data

The node id does not always correspond to the same node as the tree is modified. For example, an id=2 will always refer to the third node in the tree, so if you add a node before the third node, the node with id=2 will now refer to the new node, and the old node will now have id=3. For that reason, each node can store an user data pointer uniquely identifying the node. To set or retrieve the user data of a node use the USERDATAid attribute, or the Extra Functions below to associate a user data to a node and to find a node given its user data.

Tree - Images

IUP::Tree 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 IUP::Tree can be obtained by means of function IUP::GetHandle. The names of the predefined images are: IMGLEAF, IMGCOLLAPSED, IMGEXPANDED, IMGBLANK (blank sheet of paper) and IMGPAPER (written sheet of paper). By default:

 "IMAGELEAF" uses "IMGLEAF"
 "IMAGEBRANCHCOLLAPSED" uses "IMGCOLLAPSED"
 "IMAGEBRANCHEXPANDED" uses "IMGEXPANDED"
 "IMGBLANK" and "IMGPAPER" are designed for use as "IMAGELEAF"

Tree - Simple Marking

Is the IUP::Tree default operation mode (MARKMODE=SINGLE). In this mode only one node can be selected.

Tree - Multiple Marking

IUP::Tree allows marking several nodes simultaneously using the Shift and Control keys. To use multiple marking set MARKMODE=MULTIPLE. In GTK and Motif multiple nodes can also be selected using a rubber band if SHOW_DRAGDROP=NO.

When a user keeps the Control key pressed, the individual marking mode is used. This way, the focus 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 focus 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 keys being pressed, or when the space bar is pressed together with Control.

Tree - Navigation

Using the keyboard:

In Motif when pressing Tab the focus goes to the next visible node, if there are no next visible node then the next control in the dialog receives the focus. In Windows and GTK the focus simply goes directly to the next control.

Using the left mouse button:

Tree - Removing a Node with "Del"

By default the Del key is not processed, but you can implement it using a simple K_ANY callback:

Callback handler prototype:

 sub k_any_handler {
   my ($self, $c) = @_
   if ($c == K_DEL) {
     $self->SetAttribute( DELNODE=>"MARKED" );
   }
   return IUP_CONTINUE;
 }

ATTRIBUTES

For more info about concept of attributes (setting/getting values etc.) see IUP::Manual::03_Attributes. Attributes specific to this element:

General

ADDEXPANDED

(non inheritable)

Defines if branches will be expanded when created. The branch will be actually expanded when it receives the first child. Possible values: "YES" = The branches will be created expanded; "NO" = The branches will be created collapsed. Default: "YES".

ADDROOT

(non inheritable)

Automatically adds an empty branch as the first node when the tree is mapped. Default: "YES". (Since 3.1)

AUTOREDRAW

[Windows] (non inheritable)

Automatically redraws the tree when something has change. Set to NO to add many items to the tree without updating the display. Default: "YES". (since 3.3)

BGCOLOR

Background color of the tree. Default: the global attribute TXTBGCOLOR.

CANFOCUS

(creation only) (non inheritable)

Enables the focus traversal of the control. In Windows the control will still get the focus when clicked. Default: YES.

COUNT

(read only) (non inheritable)

Returns the total number of nodes in the tree.

DRAGDROP

[Windows and GTK Only] (non inheritable)

Enable or disable the drag&drop of files. Default: NO, but if DROPFILES_CB is defined when the element is mapped then it will be automatically enabled. This is NOT related to the drag&drop of nodes inside the tree.

DROPEQUALDRAG

(non inheritable)

If enabled will allow a drop node to be equal to the drag node. Used only if SHOWDRAGDROP =Yes. In the case the nodes are equal the callback return value is ignored and nothing is done after. (since 3.3)

EXPAND

(non inheritable)

The default value is "YES".

FGCOLOR

Default text foreground color. Once each node is created it will not change its color when FGCOLOR is changed. Default: the global attribute TXTFGCOLOR.

HIDEBUTTONS

(creation only)

Hide the expand and collapse buttons. In GTK, branches will be only expanded programmatically. In Motif it did not work and crash the test. (GTK 2.12)

HIDELINES

(creation only)

Hide the lines that connect the nodes in the hierarchy. (GTK 2.10)

INDENTATION

Sets the indentation level in pixels. The visual effect of changing the indentation is highly system dependent. In GTK it acts as an additional indent value, and the lines do not follow the extra indent. In Windows is limited to a minimum of 5 pixels. (GTK 2.12)

RASTERSIZE

(non inheritable)

The initial size is "400x200". Set to NULL to allow the automatic layout use smaller values.

SHOWDRAGDROP

(creation only, non inheritable)

Enables the drag and drop of nodes, and enables the DRAGDROP_CB callback. Default: "NO". Works only if MARKMODE=SINGLE.

SPACING

Vertical internal padding for each node. Notice that the distance between each node will be actually 2x the spacing.

TOPITEM

(write-only)

Position the given node identifier at the top of the tree or near to make it visible. If any parent node is collapsed then they are automatically expanded.

The following common attributes are also accepted:

Nodes (non inheritable)

For these attributes "id" is the specified branch identifier. If id is empty, then the focus node is used as the specified node.

Images (non inheritable)

Focus Node

Marks

Hierarchy (non inheritable)

Editing

CALLBACKS

For more info about concept of callbacks (setting callback handlers etc.) see IUP::Manual::04_Callbacks. Callbacks specific to this element:

SELECTION_CB

Action generated when a node is selected or deselected. This action occurs when the user clicks with the mouse or uses the keyboard with the appropriate combination of keys.

Callback handler prototype:

 sub selection_cb_handler {
   my ($self, $id, $status) = @_;
   #...
 }

$self: identifier of the element that activated the event.

$id: Node identifier.

$status: 1=node selected, 0=node unselected.

MULTISELECTION_CB

Action generated after a continuous range of nodes is selected in one single operation. If not defined the SELECTION_CB with status=1 will be called for all nodes in the range. The range is always completely included, independent if some nodes were already marked. That single operation also guaranties that all other nodes outside the range are already not selected. Called only if MARKMODE=MULTIPLE.

Callback handler prototype:

 sub multiselection_cb_handler {
   my ($self, $ids, $n) = @_;
   #...
 }

$self: identifier of the element that activated the event.

$ids: Reference to array of node identifiers. This array is kept for backward compatibility, the range is simply defined by $ids-[0]> to $ids-[$n-1]>, where $ids-[$i+1]=$ids->[$i]+1>.

$n: Number of nodes in the array.

MULTIUNSELECTION_CB

Action generated before multiple nodes are unselected in one single operation. If not defined the SELECTION_CB with status=0 will be called for all nodes in the range. The range is not necessarily continuous. Called only if MARKMODE=MULTIPLE. (Since 3.1)

Callback handler prototype:

 sub multiunselection_cb_handler {
   my ($self, $ids, $n) = @_;
   #...
 }

$self: identifier of the element that activated the event.

$ids: Reference to array of node identifiers.

$n: Number of nodes in the array (should correspond to the size of $ids).

BRANCHOPEN_CB

Action generated when a branch is expanded. This action occurs when the user clicks the "+" sign on the left of the branch, or when double clicks the branch, or hits Enter on a collapsed branch.

Callback handler prototype:

 sub branchopen_cb_handler {
   my ($self, $id) = @_;
   #...
 }

$self: identifier of the element that activated the event.

$id: node identifier.

Returns: IUP_IGNORE for the branch not to be opened, or IUP_DEFAULT for the branch to be opened.

BRANCHCLOSE_CB

Action generated when a branch is collapsed. This action occurs when the user clicks the "-" sign on the left of the branch, or when double clicks the branch, or hits Enter on an expanded branch.

Callback handler prototype:

 sub branchclose_cb_handler {
   my ($self, $id) = @_;
   #...
 }

$self: identifier of the element that activated the event.

$id: node identifier.

Returns: IUP_IGNORE for the branch not to be closed, or IUP_DEFAULT for the branch to be closed.

EXECUTELEAF_CB

Action generated when a leaf is to be executed. This action occurs when the user double clicks a leaf, or hits Enter on a leaf.

Callback handler prototype:

 sub executeleaf_cb_handler {
   my ($self, $id) = @_;
   #...
 }

$self: identifier of the element that activated the event.

$id: node identifier.

SHOWRENAME_CB

Action generated when a node is about to be renamed. It occurs when the user clicks twice the node or press F2. Called only if SHOWRENAME=YES.

Callback handler prototype:

 sub showrename_cb_handler {
   my ($self, $id) = @_;
   #...
 }

$self: identifier of the element that activated the event.

$id: node identifier.

Returns: if IUP_IGNORE is returned, the rename is canceled (in GTK the rename continuous but the edit box is read-only).

RENAME_CB

Action generated after a node was renamed in place. It occurs when the user press Enter after editing the name, or when the text box looses it focus. Called only if SHOWRENAME=YES.

Callback handler prototype:

 sub rename_cb_handler {
   my ($self, $id, $title) = @_;
   #...
 }

$self: identifier of the element that activated the event.

$id: node identifier.

$title: new node title.

Returns: The new title is accepted only if the callback returns IUP_DEFAULT. If the callback does not exists the new title is always accepted. If the user pressed Enter and the callback returns IUP_IGNORE the editing continues. If the text box looses its focus the editing stops always.

DRAGDROP_CB

Action generated when a drag & drop is executed. Only active if SHOWDRAGDROP=YES.

Callback handler prototype:

 sub dragdrop_cb_handler {
   my ($self, $drag_id, $drop_id, $isshift, $iscontrol) = @_;
   #...
 }

$self: identifier of the element that activated the event.

$drag_id: Identifier of the clicked node where the drag start.

$drop_id: Identifier of the clicked node where the drop were executed.

$isshift: Boolean flag indicating the shift key state.

$iscontrol: Boolean flag indicating the control key state.

Returns: if returns IUP_CONTINUE, or if the callback is not defined and SHOWDRAGDROP=YES, then the node is moved to the new position. If Ctrl is pressed then the node is copied instead of moved. If the drop node is a branch and it is expanded, then the drag node is inserted as the first child of the node. If the branch is not expanded or the node is a leaf, then the drag node is inserted as the next brother of the drop node.

NODEREMOVED_CB

Action generated when a node is going to be removed. It is only a notification, the action can not be aborted. No node dependent attribute can be consulted during the callback. Not called when the tree is unmapped.

Callback handler prototype:

 sub noderemoved_cb_handler {
   my ($self, $userdata_ref) = @_;
   #...
 }

$self: identifier of the element that activated the event.

$userdata_ref: perl reference associated via TreeSetUserId with a node being removed

RIGHTCLICK_CB

Action generated when the right mouse button is pressed over a node.

Callback handler prototype:

 sub rightclick_cb_handler {
   my ($self, $id) = @_;
   #...
 }

$self: identifier of the element that activated the event.

$id: node identifier.

BUTTON_CB

Action generated when any mouse button is pressed or released inside the element. Use ConvertXYToPos to convert (x,y) coordinates in the node identifier.

MOTION_CB

Action generated when the mouse is moved over the element. Use ConvertXYToPos to convert (x,y) coordinates in item the node identifier.

DROPFILES_CB

[Windows and GTK Only]

Action generated when one or more files are dropped in the element.

The following common callbacks are also accepted:

NOTES ^

Extra Functions

IUP::Tree has functions that allow associating a perl reference to a node. In order to do that, you provide the id of the node and the reference to userdata; even if the node's id changes later on, the reference to userdata will still be associated with the given node. These functions use the USERDATA(id) attribute.

IMPORTANT: Do not manipulate USERDATA(id) attribute directly, always use "TreeSetUserId()" in TreeSetUserId and TreeGetUserId.

TreeSetUserId()

 $userdata_ref = { item1=>1, item2=>2 };
 $tree->TreeSetUserId($id, $userdata_ref);

$id: Node identifier.

$userdata_ref: reference (to scalar, array, hash ... whatever) to be associated with the node. Use undef to remove the association.

Returns: a non zero value if the node was found.

Associates an userdata_ref with a given id. If the id of the node is changed, the userdata_ref remains the same.

TreeGetUserId()

 $userdata_ref = $tree->TreeGetUserId($id);

$id: Node identifier.

Returns the reference to data associated to the node or undef if none was associated. SetUserId must have been called for the node with the given id.

TreeGetId()

 $id = $tree->TreeGetId($userdata_ref);

$userdata_ref: Reference to data associated to the node.

Returns the id of the node that has the userdata_ref on success or undef if not found. SetUserId must have been called with the same userdata_ref.

BEWARE: If you wanna use this function keep in mind that you probably want to assure that the same reference will not be associated with more that 1 node.

TreeAddNodes()

 $tree->TreeAddNodes($tree2add, $id);
 #or
 $tree->TreeAddNodes($tree2add);

$tree2add: table of nodes (required structure see below)

$id: optional existing node. The default is the first (0).

Initializes the tree using the hash or hash reference as values for the tree nodes using ADDBRANCH and ADDLEAF. For example:

 $t_singleroot = {
   TITLE=>"Animals", child=>[
     "0.Extra",
     { TITLE=>"1.Mammals",     child=>["Horse",  "Whale"] },
     "2.Extra",
     { TITLE=>"3.Crustaceans", child=>["Shrimp", "Lobster"] },
     "4.Extra",
   ],
 };

 $t_rootless = [
   "0.Extra",
   { TITLE=>"1.Mammals",     child=>["Horse",  "Whale"] },
   { TITLE=>"2.Crustaceans", child=>["Shrimp", "Lobster"] },
   "3.Extra",
   "4.Extra",
   { TITLE=>"5.Extra", child=>["Dog", "Cat"] },
 ];
 
 $dlg->Map();
 $tree1->TreeAddNodes($t_rootless,-1);   #has to go after dialog->Map()
 $tree2->TreeAddNodes($t_singleroot,-1); #has to go after dialog->Map()
 $dlg->Show();

XXX-FIXME-not-true-for-perl Inside a table BRANCHNAME defines a branch and its title, LEAFNAME defines a leaf and its title. When a node inside a branch is not a table then it is a leaf and only defines the leaf title. When LEAFNAME or BRANCHNAME are used you can also define other node attributes: COLOR, STATE, TITLEFONT, MARKED, IMAGE and IMAGEEXPANDED; without specifying the node id. You can also use USERID to associate an userdata or table just like in TREESETUSERID.

Example:

Initial layout After calling:
$tree->TreeAddNodes( {TITLE=>"subtree", child=>["item1","item2"]}, 9);

TreeInsertNodes()

 $tree->TreeInsertNodes($tree2add, $id);
 #or
 $tree->TreeInsertNodes($tree2add);

Same as TreeAddNodes but the depth of the new node is always the same of the reference node. If the reference node is a leaf, then the id of the new node will be the id of the reference node + 1. If the reference node is a branch the id of the new node will be the id of the reference node + 1 + the total number of child nodes of the reference node.

Initial layout After calling:
$tree->TreeInsertNodes( {TITLE=>"subtree", child=>["item1","item2"]}, 9);

TreeSetNodeAttributes()

 $tree->TreeSetNodeAttributes($id, $attrs);

$id: existing node.

$attrs: table of attributes.

Sets a group of attributes stored in a table in the form:

 $attrs = {
   TITLE => "Text",
   COLOR => "0 0 220",
   IMAGE => $img,   
 }
 $tree->TreeSetNodeAttributes($id, $attrs); 
 #which sets:
 # $tree->SetAttribute( "TITLE$id" => "Text" );
 # $tree->SetAttribute( "COLOR$id" => "0 0 220" );
 # $tree->SetAttribute( "IMAGE$id" => $img );

TreeSetAncestorsAttributes()

 $tree->TreeSetAncestorsAttributes($id, $attrs);

$id: existing node

$attrs: table of attributes

Calls TreeSetNodeAttributes for all ancestors of the given node (not including the node).

TreeSetDescentsAttributes()

 $tree->TreeSetDescentsAttributes($id, $attrs);

$id: existing node

$tree: table of attributes

Calls TreeSetNodeAttributes for all descendents of the given node (not including the node).

Utility Functions

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

 $elem->SetAttributeId($name, $id, $value);
 $elem->GetAttributeId($name, $id);

They work just like the respective traditional set and get functions. But the attribute string is complemented with the id value. For ex:

 $elem->SetAttributeId("KIND", 30, $value) ~~ $elem->SetAttribute("KIND30", $value);
 
 $elem->SetAttributeId("ADDLEAF", 10, $value) ~~ $elem->SetAttribute("ADDLEAF10", $value);

But these functions are faster than the traditional functions because they do not need to parse the attribute name string and the application does not need to concatenate the attribute name with the id.

EXAMPLES ^

The element IUP::Tree is used in the following sample scripts:

SEE ALSO ^

The original doc: iuptree.html

syntax highlighting: