Omnis Technical Note TNGI0003 Updated October 2009

Omnis Tree Control

For Omnis Studio
By Peter Kelly

What's the best way to build a tree?

Contents

Dataname Property
Method 1 - Default Lines
Method 2 - Notation
Method 3 - Building From A List

Tree External component

kRelationalList - Example
kFlatList - Example

Dataname Property
The Omnis tree control unlike most other GUI controls is not data bound, in other words it does not have a dataname property. It does however support three ways to populate it. You can design the tree in design mode, add individual nodes to the tree using the notation method $add, or add a complete set of nodes using a list. This technical note describes all methods.

Method 1 - Default Lines
One of simplest ways to populate a tree is to use the design mode property $treedefaultlines. This property is a design mode property only. If your tree will have a fixed set of nodes that will always be required then this may be a good choice. The only Omnis code you need to write is when Omnis informs you that your node is being expanded. For example, if you were creating a browser to view all of the classes in your Omnis library, you could create a tree with a range of default nodes with names such as '$windows', '$reports', '$searches'. When one of the nodes is expanded, you would add the child nodes to the expanding node using either method 2 or method 3 below.

Steps for creating a tree using default lines.

  1. Open a window class
  2. Add a tree control to the window - and select it.
  3. Press the button on the 'treedefaultlines' property in the property inspector
  4. Use the 'design a tree' dialog to create your basic tree

Try right clicking ( option clicking on some platforms ) on the nodes you add to the tree to set other node specific properties.

Method 2 - Notation
Using $add to create a new node is the most flexible way to add items to a tree. Initially if the default lines of a tree has not been set, the tree will be empty. To add a new root node to a tree you use the $add method of the tree object. e.g. $cinst.$objs.tree.$add("Root"). To add a new node to an existing node, you must first have a reference to the node you want to insert a node into, then use the $add method of the node reference. e.g. mynode.$add("Child Node"). When using $add to create nodes the result is a reference to the new node.

Steps for creating a tree

  1. using the $add method
  2. Open a window class
  3. Add a tree control to the window and give the control a name such a 'tree' via the property inspector
  4. View the class methods for the window class
  5. In $construct for the window class type the following:
First define a local item reference variable called 'lNewNode'

##### Method '$construct' #####
No. Method text
1 ; First we create an initial root node
2  >Do $cinst.$objs.tree.$add("Root") Returns lNewNode
3
4 ; Now using the node returned, add some child nodes
5  Do lNewNode.$add("Child Node")
6 Do lNewNode.$add("Child Node")
7
8 ; Add some more nodes even deeper.
9  Do lNewNode.$add("Child Node") Returns lNewNode
10  Do lNewNode.$add("Child X Node")
11   Do lNewNode.$add("Child X Node")

Method 3 - Building From A List
This is the most complex way of populating a tree control, but has the benefit that a whole tree or group of nodes can be added at once. When populating from a list, the list has to be structured in a particular way. The control supports two types of list structure, one where some of the columns in the list define addition properties for the nodes that will be created, such as icons or textcolor.

When populating from a list, you will use the $setnodelist method of the tree control. This method takes 3 parameters $setnodelist( mode, parentnode, list )

mode is the type of structure the list object is assumed to hold. In this first list example, the mode will be kRelationalList, in the second it will be kFlatList.

parentnode is the node in which to insert the new nodes. If this is #NULL or 0, the method will assume the root of the tree as the base for all new nodes. An example of where parentnode not be #NULL is if you were creating a help browser and already have a tree with nodes defining topics, when the node expands you could create a list of sub-topics and pass the topics node in is as the parent.

list is the list object populated with data defining the new nodes.

kRelationalList - Example
This first example will use the kRelationalList defined structure. Below we have an Omnis list alreadypopulated with data in 3 columns. When $setnodelist is called with a list of this type, the
following will happen.

First Omnis searches for a root node given the name in column1 ("RootNode"). If it does not exist, it creates one. It then moves to column 2 and looks for a node with the name ("Child 1") within the root
node either just created or found.

If this child node does not exist, it creates it, then moves on to the next column until no more columns are found. So, after row 1 has been completed we will have a tree with a root node ("RootNode") and one child called ("Child 1").

It then repeats the process of searching first and creating if not found at the correct level for each row.


Column 1
Column 2
Column 3
RootNode Child 1  
RootNode Child 2 Child 1
RootNode Child 2 Child 2
RootNode Child 2 Child 3
RootNode Child 3  

##### Method '$list1' #####
No. Method text
1 ; First set the list object and define it
2 Set current list lList
3 Define list {lCol1,lCol2,lCol3}
4
5 ; Add some rows to the list object
6 Add line to list {("Root Node","Child 1")}
7 Add line to list {("Root Node","Child 2","Child 1")}
8 Add line to list {("Root Node","Child 2","Child 2")}
9 Add line to list {("Root Node","Child 2","Child 3")}
10 Add line to list {("Root Node","Child 3")}
11
12 ; Now call the tree object with our list
13 Do $cinst.$objs.tree.$setnodelist(kRelationalList,#NULL,lList)

kFlatList - Example
This second example will use the kFlatList defined structure. Below we have another Omnis list already populated with data but with extra columns. When using $setnodelist with kFlatList as the mode, Omnis looks at the number of columns in the list and assumes the last 5 will be used for node attributes.

Also the way Omnis builds the tree from the nodes is different to that of kRelationalList. In this case Omnis searches the tree looking for a root node with the name stored in column 1, if it cannot find one it creates one and sets the new nodes properties based on the extra 5 columns then moves onto the next row. If it could find one, it searches inside the found node for a node with the name stored in columns 2 and so on.The additional properties that can be set for each new node created are :

$iconid is the icon that will be assigned to the new node
$ident is the unique id that will be assigned to the new node $enterable if set allows the new nodes name to be changed by the user at runtime
$showexpandalways is set means the node will always show an expand collapse box even if the node has no children. Normally Omnis only shows the box if the node has child nodes
$textcolor is the text color that the new node will draw in

Column 1
Column 2
$iconid $ident $ident $showexp.. $textcolor
RootNode     1 0 0 0
RootNode Child 1 Child 1 2 0 0 0
RootNode Child 2 Child 2 3 0 0 0
AnotherRoot   Child 3 4 0 0 0
AnotherRoot Child 1   5 0 0 0

##### Method '$list2' #####
No. Method text
1 ; First set the list object and define it
2 Set current list lList
3 Define list {lCol1,lCol2,lCol3,lCol4,lCol5,lCol6,lCol7}
4
5 ; Add some rows to the list object
6 Add line to list {("Root Node","",0,1,0,0,kRed)}
7 Add line to list {("Root Node","Child1",0,2,0,0,0)}
8 Add line to list {("Root Node","Child2",0,3,0,0,kRed)}
9 Add line to list {("Another Root","",0,4,0,0,0)}
10 Add line to list {(" Another Root ","Child1",0,5,0,0,kRed)}
11
12 ; Now call the tree object with our list
13 Do $cinst.$objs.tree.$setnodelist(kFlatList,#NULL,lList)

Tree External component

The Tree external component has very similar functionality as the window Tree List component. However it has different tree mode constants as follows:

kTreeDataXMLSaveTree works in conjunction with the OXML method $savetree.

kTreeDataFlatList and kTreeDataFlatListWithTags are the same as the window Tree list control - they correspond to kFlatList and kFlatListTag.

kTreeDataXMLPaths and kTreeDataXMLIds are for internal use only and should not be used.

Download RTF document

Download example library