Example 2: Dynamic tree view (filled on demand)

Form file "form1.per":
LAYOUT 
GRID
{
<Tree t1                       >
 Name             Description 
[c1              |c2           ]
[c1              |c2           ]
[c1              |c2           ]
[c1              |c2           ]
}
END 
END

ATTRIBUTES
LABEL c1 = FORMONLY.name;
PHANTOM FORMONLY.pid;
PHANTOM FORMONLY.id;
PHANTOM FORMONLY.hasChildren;
LABEL c2 = FORMONLY.descr;
TREE t1: tree1
    IMAGEEXPANDED  = "open", 
    IMAGECOLLAPSED = "folder",
    IMAGELEAF = "file",
    PARENTIDCOLUMN = pid,
    IDCOLUMN = id,
    ISNODECOLUMN = hasChildren;
END

INSTRUCTIONS
SCREEN RECORD sr_tree(FORMONLY.*);
END
Dynamic tree DISPLAY ARRAY:
DEFINE tree DYNAMIC ARRAY OF RECORD
    name STRING,
    pid STRING,
    id STRING,
    hasChildren BOOLEAN,
    description STRING
END RECORD

MAIN
    DEFINE id INTEGER

    OPEN FORM f FROM "form1"
    DISPLAY FORM f 

    LET tree[1].pid = 0
    LET tree[1].id = 1
    LET tree[1].name = "Root"
    LET tree[1].hasChildren = TRUE
    DISPLAY ARRAY tree TO sr_tree.* ATTRIBUTES(UNBUFFERED)
    BEFORE DISPLAY
        CALL DIALOG.setSelectionMode("sr_tree",1)
    ON EXPAND(id)
        CALL expand(DIALOG,id)
    ON COLLAPSE(id)
        CALL collapse(DIALOG,id)
    END DISPLAY
END MAIN

FUNCTION collapse(d,p)
    DEFINE d ui.Dialog 
    DEFINE p INTEGER
    WHILE p < tree.getLength()
        IF tree[p + 1].pid != tree[p].id THEN EXIT WHILE END IF
        CALL d.deleteNode("sr_tree", p + 1)
    END WHILE
END FUNCTION

FUNCTION expand(d,p)
    DEFINE d ui.Dialog 
    DEFINE p INTEGER
    DEFINE id STRING
    DEFINE i, x INTEGER
    FOR i = 1 TO 4
        LET x = d.appendNode("sr_tree", p)
        LET id = tree[p].id || "." || i 
        LET tree[x].id = id 
        -- tree[x].pid is implicitly set by the appendNode() method...
        LET tree[x].name = "Node " || id 
        IF i MOD 2 THEN
            LET tree[x].hasChildren = TRUE
        ELSE
            LET tree[x].hasChildren = FALSE
        END IF
        LET tree[x].description = "This is node " || tree[x].name 
    END FOR
END FUNCTION