# gTreeView

Definition: | include xpGUI.e gdx tree_view = gTreeView([sequence tree_nodes={},] [rtn branchopen=NULL, ] string attributes="", dword_seq args={})
Description: | Creates a nested tree control with expandable/collapsable nodes from a simple [recursive] data structure. tree_nodes: a nested construct of the form {"text"[,attr][,children]}, suitable for passing to gTreeAddNodes(). branchopen: optional routine for deferred loading of sub-tree nodes, see BRANCHOPEN. For more information on the attributes and args parameters see gSetAttributes(). This is a paranormalised function. (see technicalia) The tree_nodes parameter may be empty, or omitted on creation and set via gTreeAddNodes() at some later time. At the time of writing, few treeview attributes are supported, but in time I expect it will cope with at least EXPANDNODE, CONTRACTNODE, FOCUSNODE, TOPITEM, VISIBLENODE, as well as having a few more handler routines, probably. Returns: the identifier of the created element.
pwa/p2js: | Supported.
See Also: | gTreeAddNodes
Example: |
    -- demo\xpGUI\gTreeView.exw
    include xpGUI.e
    constant tree_nodes = {"Figures",               -- (branch with 5 children)
                           {"Other",                -- (leaf)
                            {"triangle",            -- (branch with 3 children)
                             {"STATE","COLLAPSED"},
                             {"equilateral",
                              {"isoceles",          -- (branch with 2 children)
                               {"STATE","COLLAPSED"},
                               {"acute",
                                "obtuse"}},
                              "scalenus"}
                            },
                            {"parallelogram",       -- (branch with 2 children)
                             {"square",             -- (should be open on load)
                              "diamond"}},
                            "2D",                   -- (leaf)
                            {"3D",                  -- (branch)
                             {"STATE","COLLAPSED"}, -- (needed here)
                             {}},                   -- (empty)
                            {"4D",
                             {"STATE","COLLAPSED"},
                             {"some",
                              "other",
                              "branch"},
                             {"random data"} -- (iff attr and children present)
                            }
                           }
                          }

    gdx tree_view = gTreeView(tree_nodes),
        dlg = gDialog(tree_view,`gTreeView`)
    gShow(dlg)
    gMainLoop()
(note: that looks slightly different under GTK[3]) See also gTreeAddNodes for a more details of the structures, splitting/flattening them, and deferred loading.
Attributes: |
Also: | ACTIVE, CANFOCUS, FONT, EXPAND, MINSIZE, MAXSIZE, SIZE, TIP, VISIBLE.
Handlers: |
BRANCHOPEN | Event generated when a branch is expanded, and intended for implementing deferred (sub-tree) loading. procedure branchopen(object treenode) treenode: opaque/backend-specific, suitable for passing directly to gTreeGetUserId() and gTreeAddNodes(). Currently under GTK it is {treeview,iter,path}, under WinAPI it is {treeview,TreeIdx}, and under p2js it is a HTMLUListElement: you may be able to do a few dirty little debug tricks with it, but should cease and desist from doing anything like that in the finished code, plus those details may well change in a future release. Should you not want a user to open a branch, simply don’t put any children in there in the first place. Deferred loading is not worthwhile for a tree the size of the one shown above, but it certainly would be when loading a hard drive (for instance, try right clicking on C:\Windows, select Properties, and watch it start counting, then imagine staring at a blank screen until it finishes) or perhaps a database containing several decades-worth of detailed historical information. The gTreeAddNodes example showcases deferred loading, however you are free to replace "tree_data" with anything you like[/can massage into the right format], including a database or even an (ideally asynchronous) remote fetch that triggers that code (in the main thread) when it completes.
also | KEY: All common handlers are supported.
Technicalia | As this is a paranormalised function, and with no expectation that you should attempt to memorise this lot, except maybe "qraa", you can assume that all of the following are potentially perfectly valid, with the fairly obvious restriction that any parameters must be in strict qraa-order, and no args without attributes:
                            gTreeView()
                            gTreeView(branchopen)
                            gTreeView(attributes)
                            gTreeView(attributes, args)
                            gTreeView(branchopen, attributes)
                            gTreeView(branchopen, attributes, args)
                            gTreeView(tree_nodes)
                            gTreeView(tree_nodes, branchopen)
                            gTreeView(tree_nodes, attributes)
                            gTreeView(tree_nodes, attributes, args)
                            gTreeView(tree_nodes, branchopen, attributes)
                            gTreeView(tree_nodes, branchopen, attributes, args)     -- (the full set)
Note that in practice rid is actually defined as object, and attributes as a sequence rather than a string, however both are thoroughly verified to be of the documented types, after being repositioned via xpGUI.e/paranormalise_qraa().