Organising Multiple Widgets in a Tree-Like Structure with Gnocl

WJG (15/Dec/09) In an earlier post to the wiki the question was raised as to the possibility of packing widgets into a gnocl::tree widget. Well, this is not possibile as the tree widget is related to gnocl::list. The significant difference being that the tree allows rows to be hidden and the tree permits editable entries. For those applications where a tree like structure is needed to present a wide range of configurable options, then a different solution is required. Fortunately this process is really easy to implement using Tcl. Here's a simple framework using the gnocl::expander widget.

#---------------
# widgetTree.tcl
#---------------
# Created by William J Giddings
# 15-Dec-2009
#---------------
# Description:
#---------------

#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "[email protected]"

package require Gnocl

namespace eval widgetTree {}

#---------------
# initialise the widget tree itself
#---------------
proc tree:create { } {
    set tree [gnocl::box -orientation vertical]
    return $tree
}

#---------------
# add node to the tree
#---------------
proc tree:addNode { {label NEW} } {
    set box [gnocl::box -orientation vertical]
    set node [gnocl::expander -label $label -child $box]
    return $node
}

#---------------
# add item to the specified node
#---------------
proc tree:node:addItem { node item} {
    set box [$node cget -child]
    $box add $item
    return $item
}


#=========================
# Put the above to the test.
#=========================

set TRANSPORT [tree:create]

# create some node in the tree
foreach item {cars planes shipping} {
    set [set item] [tree:addNode $item]
    $TRANSPORT add [set ${item}]
}

# populate each of the nodes

# cars
foreach item {Lagonda Avis Daimler} {
    tree:node:addItem $cars [gnocl::button -text $item]
}

# planes
foreach {item str} {Boulton-Paul X Vickers Y DeHaviland Z} {
    set tmp [gnocl::box]
    set lab [gnocl::label -text $str]
    set scl [gnocl::scale -orientation horizontal \
            -digits 0 -variable $item \
            -onValueChanged {puts "value is now %v == $item"} -value 32]
    $tmp add $lab
    $tmp add $scl -expand 1 -fill {1 1}

    tree:node:addItem $planes $tmp

}

# shipping
foreach item {Cunard P&O Star} {
    tree:node:addItem $shipping [gnocl::entry -value $item -variable $item ]
}

# add scolling capability and then display
gnocl::window -child [gnocl::scrolledWindow -child $TRANSPORT] \
    -onDestroy exit -width 200 -height 300

gnocl::mainLoop

And here's a screenshot.

http://lh3.ggpht.com/_yaFgKvuZ36o/Sydq0rGZG3I/AAAAAAAAALU/Gk1m3J0a97c/s800/Screenshot-widgetTree.png