Version 2 of megawidget framework with tclOO (1)

Updated 2009-12-05 23:20:51 by hae

This is another megawidget framework. It uses typedlist package. It's a class which create an megawidget as an ensemble command.

Code :

package require tkpath 0.3.0
package require Tktable
package require typedlist

oo::class create megawidget {
    variable path
    variable myOptions
    variable WidgetTree
    variable rootPath
    variable hPostConfig
    constructor {tree} {
        variable WidgetTree
        my variable OptionListe

        set OptionListe [list widget mwidget wOptions myOption bScripts \
                             handler hMethods hVars hVal hPostConfig\
                             gmPack gmNotebook gmPane gmText gmCanvas gmTable \
                             CanvasItem TkpItem spanTable textIsPeer scTable default]

        ::set WidgetTree(script) $tree

        foreach o [list {*}$OptionListe < > ^ v @] {
            typedlist create $o
        }
    }
    method getTreeScript {} {
        variable WidgetTree
        return $WidgetTree(script)
    }
    method getTree {} {
        variable WidgetTree
        return $WidgetTree(tree)
    }

    method getOptions {args} {
        variable myOptions

        set e [lindex $args 0]
        if {(![catch {info object class $e}]) && ([info object class $e] eq "::typedlist") && ([$e type] eq "default")} {
            set default [$e get]
            set args [lassign $args dummy]
        } else {
            set default []
        }
        if {[dict exist $myOptions {*}$args]} {
            return [dict get $myOptions {*}$args]
        } else {
            return $default
        }
    }
    method createHandler {handler path} {
        variable rootPath

        namespace eval ::${rootPath}::$handler {}
        namespace eval ::${rootPath}::$path {}

        proc ::${rootPath}::${handler}::path {} "return ${path}_"
        proc ::${rootPath}::${handler}::obj {} "return ${path}"
        proc ::${rootPath}::${handler}::configure {args} "${path}_ configure {*}\$args"
        proc ::${rootPath}::${handler}::do {args} "${path}_ {*}\$args"
        proc ::${rootPath}::${handler}::bind {event script} [subst -noc {
            ::bind ${path}_ \$event \$script
        }]
        proc ::${rootPath}::${handler}::parent {args} [subst -noc {
            return [winfo parent ${path}_]
        }]
        proc ::${rootPath}::${handler}::brother {args} [subst -noc {
            return [winfo children [winfo parent ${path}_]]
        }]
        proc ::${rootPath}::${path}::handler {args} [subst -noc {
            return $handler
        }]
        proc ::${rootPath}::${handler}::space {args} [subst -noc {
            return ::${rootPath}::${handler}
        }]

        namespace eval ::${rootPath}::$handler namespace export *
        namespace eval ::${rootPath}::$handler namespace ensemble create
        namespace eval ::${rootPath}::$path namespace export *
        namespace eval ::${rootPath}::$path namespace ensemble create
        namespace eval ::${rootPath} namespace export *
        namespace eval ::${rootPath} namespace ensemble create
        
        return $handler
    }

    method getSpace {} {
        return [self namespace]
    }

    method unknown {w args} {
        variable myOptions

        if {[string match .* $w]} {
            if {[winfo exist $w]} {
                return -code error -message "$w already exist"
            }
            if {[winfo exist ${w}_]} {
                return -code error -message "${w}_ already exist"
            }
            if {[string last . $w] == 0} {
                # la fenêtre parente . existe toujours
                if {$w ne "."} {
                    set myOptions $args
                    # puts myOption:$args
                    my _build $w
                    return $w
                } else {
                    return -code error -message "$w is the toplevel window !"
                }
            } elseif {[set lastdot [string last . $w]] > 0} {
                # la fenêtre parent doit exister
                if {[set ParentWindow [winfo exist [string range $w 0 ${lastdot}-1]]]} {
                    # Options 
                    set myOptions $args
                    my _build $w
                    return $w
                } else {
                    return -code error -message "window $ParentWindow doesn't exist"
                }
            }
        } else {
            return -code error -message "Bad widget path name $w"
        }
    }
    method _build {w} {
        variable WidgetTree
        variable path
        variable rootPath
        variable hPostConfig

        set rootPath $w
        set path ${w}_
        frame ${w}_

        namespace eval ::${rootPath} {}

        ::set WidgetTree(tree) [my eval $WidgetTree(script)]

        my make $WidgetTree(tree)

        proc ::${rootPath}::rootpath {args} [subst -noc {
            return ${rootPath}_
        }]

        namespace eval ::${rootPath} namespace export *
        namespace eval ::${rootPath} namespace ensemble create

        foreach e  $hPostConfig {
            eval $e
        }
    }

    method make {tree} {
        variable WidgetTree
        variable path
        variable rootPath
        variable myOptions
        variable hPostConfig
        my variable OptionListe

        set isWidgetCreated 0
        
        lassign [lrepeat [llength $OptionListe] []] {*}$OptionListe

        if {(![catch {info object class $tree}]) && ([info object class $tree] eq "::typedlist") \
                && (([$tree type] eq ">") \
                         || ([$tree type] eq "<") \
                         || ([$tree type] eq "v") \
                         || ([$tree type] eq "^") \
                         || ([$tree type] eq "@"))} {

            set SIDE [dict get [dict create > left v top ^ bottom < right @ {}] [$tree type]]

            set P $path
            foreach e [$tree get] {
                if {(![catch {info object class $e}]) && ([info object class $e] eq "::typedlist")} {
                    if {[$e type] eq "mwidget"} {
                        lassign [lrepeat [llength $OptionListe] []] {*}$OptionListe
                        set mwCommand [lindex [$e get] 0]
                        set path ${path}.[regsub -all {::} [string tolower $mwCommand 0 0] {_}][incr id]
                        set WidgetTree($path,wtype) "mwidget"
                        set WidgetTree(${path}_,gm) Pack; #pack en valeur par défault

                        foreach o [lrange [$e get] 1 end] {
                            if {(![catch {info object class $o}]) && ([info object class $o] eq "::typedlist")} {
                                if {[$o type] eq "wOptions"} {
                                    set wOptions [$o get]
                                    set wOptions [regsub -all %MW $wOptions ${rootPath}];  # substitution MegaWidget
                                    set wOptions [regsub -all %${rootPath} $wOptions %MW]; # unsubstitute protected MegaWidget
                                    set wOptions [regsub -all %O $wOptions [self]];        # substitution Object
                                    set wOptions [regsub -all %[self] $wOptions %O];       # unsubstitute protected Object
                                }

                                if {[$o type] eq "gmPack"} {
                                    set gmPack [$o get]
                                    set WidgetTree(${path}_,gm) Pack
                                } 
                                if {[$o type] eq "gmNotebook"} {
                                    set gmNotebook [$o get]
                                    set WidgetTree(${path}_,gm) Notebook
                                    set WidgetTree(${path},gm) Notebook
                                }
                                if {[$o type] eq "gmTable"} {
                                    set gmTable [$o get]
                                    set WidgetTree(${path}_,gm) Table
                                    set WidgetTree(${path},gm) Table
                                }
                                if {[$o type] eq "gmPane"} {
                                    set gmPane [$o get]
                                    set WidgetTree(${path}_,gm) Panewindow
                                    set WidgetTree(${path},gm) Panewindow
                                }
                                if {[$o type] eq "gmCanvas"} {
                                    set gmCanvas [$o get]
                                    set WidgetTree(${path}_,gm) Canvas
                                    set WidgetTree(${path},gm) Canvas
                                }
                                if {[$o type] eq "gmText"} {
                                    set gmText [$o get]
                                    set WidgetTree(${path}_,gm) Text
                                    set WidgetTree(${path},gm) Text
                                }
                                if {[$o type] eq "handler"} {
                                    set handler [lindex [$o get] 0]
                                    # création du raccourci
                                    namespace eval ::${rootPath}::$handler {}
                                    namespace eval ::${rootPath}::$path {}

                                    proc ::${rootPath}::${handler}::path {} "return ${path}_"
                                    proc ::${rootPath}::${handler}::obj {} "return ${path}"
                                    proc ::${rootPath}::${handler}::configure {args} "${path}_ configure {*}\$args"
                                    proc ::${rootPath}::${handler}::do {args} "${path}_ {*}\$args"
                                    proc ::${rootPath}::${handler}::bind {event script} [subst -noc {
                                        ::bind ${path}_ \$event \$script
                                    }]
                                    proc ::${rootPath}::${handler}::parent {args} [subst -noc {
                                        return [winfo parent ${path}_]
                                    }]
                                    proc ::${rootPath}::${handler}::brother {args} [subst -noc {
                                        return [winfo children [winfo parent ${path}_]]
                                    }]
                                    proc ::${rootPath}::${path}::handler {args} [subst -noc {
                                        return $handler
                                    }]
                                    proc ::${rootPath}::${handler}::space {args} [subst -noc {
                                        return ::${rootPath}::${handler}
                                    }]
                                    
                                    foreach mv [lrange [$o get] 1 end] {
                                        if {([info object class $mv] eq "::typedlist")} {
                                            if {[$mv type] eq "hMethods"} {
                                                foreach {Name Args Body} [$mv get] {
                                                    set Body [regsub -all %MW $Body ${rootPath}];  # substitution MegaWidget
                                                    set Body [regsub -all %${rootPath} $Body %MW]; # unsubstitute protected MegaWidget
                                                    set Body [regsub -all %O $Body [self]];        # substitution Object
                                                    set Body [regsub -all %[self] $Body %O];       # unsubstitute protected Object
                                                    proc  ::${rootPath}::${handler}::$Name $Args $Body
                                                }
                                            } elseif {[$mv type] eq "hVars"} {
                                                foreach v [$mv get] {
                                                    if {(![catch {info object class $v}]) \
                                                            && ([info object class $v] eq "::typedlist")\
                                                            && ([$v type] eq "hVal")} {
                                                        namespace eval ::${rootPath}::${handler} set $var $v
                                                    } else {
                                                        namespace eval ::${rootPath}::${handler} variable [set var $v]
                                                    }
                                                }
                                            } else {
                                                # puts "don't know"
                                            }
                                        } else {
                                            continue
                                        }
                                    }
                                    namespace eval ::${rootPath}::$handler namespace export *
                                    namespace eval ::${rootPath}::$handler namespace ensemble create
                                    namespace eval ::${rootPath}::$path namespace export *
                                    namespace eval ::${rootPath}::$path namespace ensemble create
                                }
                            }
                        }
                        set isWidgetCreated 0
                        
                    } elseif {[$e type] eq "widget"} {
                        # widget command en 0
                        lassign [lrepeat [llength $OptionListe] []] {*}$OptionListe
                        set wCommand [lindex [$e get] 0]
                        set path ${path}.[regsub -all {::} $wCommand {_}][incr id]
                        set WidgetTree($path,wtype) "widget"
                        set WidgetTree($path,gm) Pack; #pack en valeur par défault
                        foreach o [lrange [$e get] 1 end] {
                            if {(![catch {info object class $o}]) && ([info object class $o] eq "::typedlist")} {
                                if {[$o type] eq "wOptions"} {
                                    set wOptions [$o get]
                                    set wOptions [regsub -all %MW $wOptions ${rootPath}];  # substitution MegaWidget
                                    set wOptions [regsub -all %${rootPath} $wOptions %MW]; # unsubstitute protected MegaWidget
                                    set wOptions [regsub -all %O $wOptions [self]];        # substitution Object
                                    set wOptions [regsub -all %[self] $wOptions %O];       # unsubstitute protected Object
                                }

                                if {[$o type] eq "gmPack"} {
                                    set gmPack [$o get]
                                    set gmPack [regsub -all %MW $gmPack ${rootPath}];  # substitution MegaWidget
                                    set gmPack [regsub -all %${rootPath} $gmPack %MW]; # unsubstitute protected MegaWidget
                                    set gmPack [regsub -all %O $gmPack [self]];        # substitution Object
                                    set gmPack [regsub -all %[self] $gmPack %O];       # unsubstitute protected Object

                                    set WidgetTree($path,gm) Pack
                                }
                                if {[$o type] eq "gmNotebook"} {
                                    set gmNotebook [$o get]
                                    set WidgetTree($path,gm) Notebook
                                }
                                if {[$o type] eq "gmTable"} {
                                    set gmTable [$o get]
                                    set WidgetTree($path,gm) Table
                                }
                                if {[$o type] eq "gmPane"} {
                                    set gmPane [$o get]
                                    set WidgetTree($path,gm) Panewindow
                                }
                                if {[$o type] eq "gmCanvas"} {
                                    set gmCanvas [$o get]
                                    set WidgetTree($path,gm) Canvas
                                }
                                if {[$o type] eq "gmText"} {
                                    set gmText [$o get]
                                    set WidgetTree($path,gm) Text
                                }
                                if {[$o type] eq "textIsPeer"} {
                                    set textIsPeer [$o get]
                                    if {! [info exist WidgetTree(peer,$textIsPeer)]} {
                                        # première création : normal
                                        set WidgetTree(peer,$textIsPeer) $path
                                    } else {
                                        set WidgetTree(peer,$path) $textIsPeer
                                    }
                                }
                                if {[$o type] eq "bScripts"} {
                                    set bScripts []
                                    foreach {bSeq bSc} [$o get] {
                                        set bSc [regsub -all %MW $bSc ${rootPath}];  # substitution MegaWidget
                                        set bSc [regsub -all %${rootPath} $bSc %MW]; # unsubstitute protected MegaWidget
                                        set bSc [regsub -all %O $bSc [self]];        # substitution Object
                                        set bSc [regsub -all %[self] $bSc %O];       # unsubstitute protected Object
                                        lappend bScripts $bSeq $bSc
                                    }
                                }
                                if {[$o type] eq "handler"} {
                                    set handler [lindex [$o get] 0]
                                    # création du raccourci
                                    namespace eval ::${rootPath}::$handler {}
                                    namespace eval ::${rootPath}::$path {}

                                    proc ::${rootPath}::${handler}::path {} "return $path"
                                    proc ::${rootPath}::${handler}::configure {args} "$path configure {*}\$args"
                                    proc ::${rootPath}::${handler}::do {args} "$path {*}\$args"
                                    proc ::${rootPath}::${handler}::bind {event script} [subst -noc {
                                        ::bind $path \$event \$script
                                    }]
                                    proc ::${rootPath}::${handler}::parent {args} [subst -noc {
                                        return [winfo parent $path]
                                    }]
                                    proc ::${rootPath}::${handler}::brother {args} [subst -noc {
                                        return [winfo children [winfo parent $path]]
                                    }]
                                    proc ::${rootPath}::${path}::handler {args} [subst -noc {
                                        return $handler
                                    }]
                                    proc ::${rootPath}::${handler}::space {args} [subst -noc {
                                        return ::${rootPath}::${handler}
                                    }]
                                    
                                    foreach mv [lrange [$o get] 1 end] {
                                        # puts $mv
                                        if {([info object class $mv] eq "::typedlist")} {
                                            if {[$mv type] eq "hMethods"} {
                                                foreach {Name Args Body} [$mv get] {
                                                    set Body [regsub -all %MW $Body ${rootPath}];  # substitution MegaWidget
                                                    set Body [regsub -all %${rootPath} $Body %MW]; # unsubstitute protected MegaWidget
                                                    set Body [regsub -all %O $Body [self]];        # substitution Object
                                                    set Body [regsub -all %[self] $Body %O];       # unsubstitute protected Object
                                                    proc  ::${rootPath}::${handler}::$Name $Args $Body
                                                    # puts "5:$Name $Args $Body"
                                                }
                                            } elseif {[$mv type] eq "hVars"} {
                                                foreach v [$mv get] {
                                                    if {(![catch {info object class $v}]) \
                                                            && ([info object class $v] eq "::typedlist")\
                                                            && ([$v type] eq "hVal")} {
                                                        namespace eval ::${rootPath}::${handler} set $var [$v get]
                                                    } else {
                                                        namespace eval ::${rootPath}::${handler} variable [set var $v]
                                                    }
                                                }
                                            } elseif {[$mv type] eq "hPostConfig"} {
                                                # Un script à évaluer après création
                                                # Création de tout ou bien juste du handler ? A voir ...
                                                set hPostConfig [regsub -all %MW [$mv get] ${rootPath}];  # substitution MegaWidget
                                                set hPostConfig [regsub -all %${rootPath} $hPostConfig %MW]; # unsubstitute protected MegaWidget
                                                set hPostConfig [regsub -all %O $hPostConfig [self]];        # substitution Object
                                                set hPostConfig [regsub -all %[self] $hPostConfig %O];       # unsubstitute protected Object
                                            } else {
                                                # puts "unknow option"
                                            }
                                        } else {
                                            continue
                                        }
                                    }
                                    namespace eval ::${rootPath}::$handler namespace export *
                                    namespace eval ::${rootPath}::$handler namespace ensemble create
                                    namespace eval ::${rootPath}::$path namespace export *
                                    namespace eval ::${rootPath}::$path namespace ensemble create
                                }
                                if {([$o type] eq ">")\
                                        ||([$o type] eq "<")\
                                        ||([$o type] eq "v")\
                                        ||([$o type] eq "^")\
                                        ||([$o type] eq "@")} {
                                    
                                    if {! $isWidgetCreated} {
                                        set isWidgetCreated 1
                                        # SubWidgets

                                        # 1. créer la widget parent
                                        if {[catch {set WidgetTree(peer,$path)} res]} {
                                            if {$WidgetTree($path,wtype) eq "widget"} {
                                                if {![winfo exist $path]} {
                                                    $wCommand $path {*}$wOptions
                                                } else {
                                                    $path conf {*}$wOptions
                                                }
                                            } elseif {$WidgetTree($path,wtype) eq "mwidget"} {
                                                if {![winfo exist ${path}_]} {
                                                    $mwCommand $path {*}$wOptions
                                                    set path [$path rootpath]
                                                } else {
                                                    # puts To\ do
                                                }
                                            }
                                        } else {
                                            if {![winfo exist $path]} {
                                                $WidgetTree(peer,$res) peer create $path {*}$wOptions
                                            } else {
                                                # puts To\ do
                                            }
                                        }
                                        # 2. geometry management
                                        switch $WidgetTree($path,gm) {
                                            Pack {
                                                pack $path -expand 1 -fill both {*}[expr {($SIDE ne "") ? [list -side $SIDE] : ""}] {*}$gmPack
                                            }
                                            Notebook {
                                                switch $SIDE {
                                                    "right" {
                                                        [winfo parent $path] insert 0 $path {*}$gmNotebook
                                                    }
                                                    "left" -
                                                    default {
                                                        [winfo parent $path] add $path {*}$gmNotebook
                                                    }
                                                }
                                            }
                                            Panewindow {
                                                switch $SIDE {
                                                    "right" - bottom {
                                                        [winfo parent $path] insert 0 $path {*}$gmPane
                                                    }
                                                    "left" - "top" - default {
                                                        [winfo parent $path] add $path {*}$gmPane
                                                    }
                                                }
                                            }
                                            Table {
                                                [winfo parent $path] window configure {*}$gmTable -window $path
                                            }
                                            default {}
                                        }
                                        # 3. gestion des évènements
                                        foreach {bSeq bSc} $bScripts {
                                            bind $path $bSeq $bSc
                                        }
                                    }
                                    # continuation du processus
                                    my make $o
                                }
                            } else {
                                # On assume que ce sont des options
                                # tk_messageBox -message $o
                                lappend wOptions $o
                            }
                        }
                    } elseif {[$e type] eq "TkpItem"} {
                        $path create {*}[$e get]
                        continue
                    } elseif {[$e type] eq "spanTable"} {
                        $path span {*}[$e get]
                        continue
                    } elseif {[$e type] eq "scTable"} {
                        $path {*}[$e get]
                        continue
                    }
                    if {! $isWidgetCreated} {
                        set isWidgetCreated 1
                        # SubWidgets
                        # 1. créer la widget parent
                        if {[catch {set WidgetTree(peer,$path)} res]} {
                            if {$WidgetTree($path,wtype) eq "widget"} {
                                if {![winfo exist $path]} {
                                   # tk_messageBox -message $wOptions
                                    $wCommand $path {*}$wOptions
                                } else {
                                    $path conf {*}$wOptions
                                }
                            } elseif {$WidgetTree($path,wtype) eq "mwidget"} {
                                if {![winfo exist ${path}_]} {
                                    $mwCommand $path {*}$wOptions
                                    set path [$path rootpath]
                                } else {
                                    # puts To\ do
                                }
                            }
                        } else {
                            if {![winfo exist $path]} {
                                $WidgetTree(peer,$res) peer create $path {*}$wOptions
                            } else {
                                # puts To\ do
                            }
                        }
                        
                        # 2. geometry management
                        switch $WidgetTree($path,gm) {
                            Pack {
                                pack $path -expand 1 -fill both {*}[expr {($SIDE ne "") ? [list -side $SIDE] : ""}] {*}$gmPack
                            }
                            Notebook {
                                switch $SIDE {
                                    "right" {
                                        [winfo parent $path] insert 0 $path {*}$gmNotebook
                                    }
                                    "left" -
                                    default {
                                        [winfo parent $path] add $path {*}$gmNotebook
                                    }
                                }
                            }
                            Panewindow {
                                switch $SIDE {
                                    "right" - bottom {
                                        [winfo parent $path] insert 0 $path {*}$gmPane
                                    }
                                    "left" - "top" - default {
                                        [winfo parent $path] add $path {*}$gmPane
                                    }
                                }
                            }
                            Table {
                                [winfo parent $path] window configure {*}$gmTable -window $path
                            }
                            default {}
                        }
                        # 3. gestion des évènements
                        foreach {bSeq bSc} $bScripts {
                            bind $path $bSeq $bSc
                        }
                    }
                }
                # réinitilisation du chemin au chemin parent
                set path $P
                set isWidgetCreated 0
            }; # fin foreach
        }
    }
}

package provide megawidget

Examples

A multilibox widget

package require megawidget

megawidget create MultiListBox {
    v \
        [widget ttk::panedwindow -orient horizontal \
             [> \
                  {*}[catch {
                      image create photo img:sash -data {
                          R0lGODlhBQB5AKECADMzM9TQyP///////yH+EUNyZWF0ZWQgd2l0aCBHSU1QACH5BAEKAAMALAAA
                          AAAFAHkAAAJOjA95y+0LUAxpUkufboLh1UFPiIyeKTqk8R1rpp5xysk1zbytoaPl/LsFczYiDlRE
                          Hl1J5pLXhD4DPSDLd7XChFnudgO2KC5izA6sqTQKADs=
                      }
                      
                      ttk::style element create Sash.xsash image \
                          [list img:sash ] \
                          -border {1 1} -sticky ew -padding {1 1}
                      
                      ttk::style layout TPanedwindow {
                          Sash.xsash
                      }}; set 0 []]\
                  [set L {}; 
                   set Font [my getOptions [default TkDefaultFont] -font];
                   set TitleFont [my getOptions [default TkDefaultFont] -titlefont];
                   for {set i 0} {$i < [set NbCols [my getOptions -nbcols]]} {incr i} {
                       lappend L [widget ttk::frame \
                                      [gmPane -weight [my getOptions [default 1] -$i -weight]]\
                                      [v \
                                           [widget label \
                                                [wOptions -relief groove \
                                                     -text [my getOptions -$i -text] \
                                                     -font $TitleFont \
                                                     -justify center]\
                                                [handler title$i\
                                                     [hMethods \
                                                          sort {} [subst -noc {
                                                              set sens -increasing
                                                              if {[lsort [set [%MW column$i do cget -listvariable]]] \
                                                                      eq [set [%MW column$i do cget -listvariable]]} {
                                                                  set sens -decreasing
                                                              } elseif {[lsort -decreasing [set [%MW column$i do cget -listvariable]]] \
                                                                      eq [set [%MW column$i do cget -listvariable]]} {
                                                                  set sens -increasing
                                                              }
                                                              set L []
                                                              set len [llength [set [%MW column0 do cget -listvariable]]]
                                                              for {set j 0} {\$j < \$len} {incr j} {
                                                                  for {set k 0} {\$k < $NbCols} {incr k} {
                                                                      lappend L [lindex [set [%MW column\$k do cget -listvariable]] \$j]
                                                                  }
                                                              }
                                                              set L [lsort \$sens -stride $NbCols -index $i \$L]
                                                              for {set k 0} {\$k < $NbCols} {incr k} {
                                                                  set [%MW column\$k do cget -listvariable] []
                                                                  for {set j 0} {\$j < \$len} {incr j} {
                                                                      lappend [%MW column\$k do cget -listvariable] [lindex \$L [expr {\$j*$NbCols+\$k}]]
                                                                  }
                                                              }
                                                          }]]
                                                    ]\
                                                [bScripts <ButtonPress-1> [subst {%MW title$i sort}]]\
                                                [gmPack -expand 0 -fill x -padx 0 -ipady 3 -anchor center]]\
                                           [widget listbox \
                                                [wOptions -exportselection 0 \
                                                     -selectbackground [my getOptions [default GoldenRod4] -selectbackground]\
                                                     -font $Font\
                                                     -listvariable [set [namespace current]::L$i[incr j] []; set k 0;
                                                                    foreach e [set [my getOptions -listvariable]] {
                                                                        if {[expr {$k%$NbCols}] == $i} {
                                                                            lappend [namespace current]::L$i$j $e
                                                                        }
                                                                        incr k
                                                                    }; set res [namespace current]::L$i$j]]\
                                                [gmPack -padx 0 -pady 2]\
                                                [handler column$i \
                                                     [hMethods \
                                                          mref {X Y x y} [my getOptions -mref]\
                                                          href {} [my getOptions -href]\
                                                         ]]\
                                                [bScripts \
                                                     <<ListboxSelect>> [subst -noc {
                                                         set index [%W curselection]
                                                         set NumCol [%MW %W handler]
                                                         for {set i 0} {\$i<$NbCols} {incr i} {
                                                             if {"column\$i" eq \$NumCol} continue
                                                             %MW column\$i do selection clear 0 end
                                                             %MW column\$i do selection set \$index
                                                         }
                                                     }] \
                                                     <MouseWheel> [subst -noc {
                                                         set NumCol [%MW %W handler]
                                                         for {set i 0} {\$i<$NbCols} {incr i} {
                                                             if {"column\$i" eq \$NumCol} continue
                                                             %MW column\$i do yview scroll [expr -%D/30] units
                                                         }
                                                     }]\
                                                     <Double-1> [subst -noc {
                                                         set NumCol [%MW %W handler]
                                                         %MW \$NumCol href 
                                                     }]\
                                                     <ButtonPress-3> [subst -noc {
                                                         set NumCol [%MW %W handler]
                                                         %MW \$NumCol mref %X %Y %x %y
                                                     }]\
                                                    ]]]]\
                       }]\
                  {*}$L \
                 ]
         ]
}
# create a notebook of multilistbox

megawidget create mlbnb {
     > \
         [widget ttk::notebook\
              [> \
                   {*}[set L [];
                      for {set i 0} {$i < [my getOptions -nb]} {incr i} {
                          lappend L [mwidget MultiListBox \
                                         [gmNotebook -text [my getOptions -$i -text]] \
                                         [handler tab$i]\
                                         [wOptions \
                                              -nbcols [my getOptions -$i -nbcols] \
                                              -listvariable [my getOptions -$i -listvariable] \
                                              -font [my getOptions [default TkDefaultFont] -$i -font]\
                                              -titlefont [my getOptions [default TkDefaultFont] -$i -titlefont]\
                                              {*}[set K [];
                                                  for {set j 0} {$j < [my getOptions [default 0] -$i -nbcols]} {incr j} {
                                                      lappend K -$j [my getOptions -$i -$j]
                                                  }
                                                  set K] \
                                              -href [my getOptions [default {}] -$i -href]\
                                              -mref [my getOptions [default {return}] -$i -mref]]]
                      }
                      set L]]]
}

# Test
# 1) some data

set TclCommands {{after} {Control Constructs} {Execute a command after a time delay} {append} {Variables and Procedures} {Append to variable} {array} {Variables and Procedures} {Manipulate array variables} {bgerror} {Interpreter Routines} {Command invoked to process background errors} {binary} {String Handling} {Insert and extract fields from binary strings} {break} {Control Constructs} {Abort looping command} {catch} {Control Constructs} {Evaluate script and trap exceptional returns} {cd} {System Related} {Change working directory} {clock} {System Related} {Obtain and manipulate time} {close} {Output} {Close an open channel.} {concat} {List Handling} {Join lists together} {continue} {Control Constructs} {Skip to the next iteration of a loop} {dde} {Platform-specific} {Execute a Dynamic Data Exchange command} {encoding} {Library Procedures} {Manipulate encodings} {eof} {Output} {Check for end of file condition on channel} {error} {Control Constructs} {Generate an error} {eval} {Control Constructs} {Evaluate a Tcl script} {exec} {System Related} {Invoke subprocess(es)} {exit} {System Related} {End the application} {expr} {Expr} {Evaluate an expression} {fblocked} {Output} {Test whether the last input operation exhausted all available input} {fconfigure} {Output} {Set and get options on a channel} {fcopy} {Output} {Copy data from one channel to another.} {file} {Output} {Manipulate file names and attributes} {fileevent} {Output} {Execute a script when a channel becomes readable or writable} {flush} {Output} {Flush buffered output for a channel} {for} {Control Constructs} {``For'' loop} {foreach} {Control Constructs} {Iterate over all elements in one or more lists} {format} {String Handling} {Format a string in the style of sprintf} {gets} {Output} {Read a line from a channel} {glob} {System Related} {Return names of files that match patterns} {global} {Variables and Procedures} {Access global variables} {history} {Interpreter Routines} {Manipulate the history list} {http} {Library Procedures} {Client-side implementation of the HTTP/1.0 protocol.} {if} {Control Constructs} {Execute scripts conditionally} {incr} {Variables and Procedures} {Increment the value of a variable} {info} {Interpreter Routines} {Return information about the state of the Tcl interpreter} {interp} {Interpreter Routines} {Create and manipulate Tcl interpreters} {join} {List Handling} {Create a string by joining together list elements} {lappend} {Variables and Procedures} {Append list elements onto a variable} {lindex} {List Handling} {Retrieve an element from a list} {linsert} {List Handling} {Insert elements into a list} {list} {List Handling} {Create a list} {llength} {List Handling} {Count the number of elements in a list} {load} {Packages and Source files} {Load machine code and initialize new commands.} {loadTk} {Packages and Source files} {Load Tk into a safe interpreter.} {lrange} {List Handling} {Return one or more adjacent elements from a list} {lreplace} {List Handling} {Replace elements in a list with new elements} {lsearch} {List Handling} {See if a list contains a particular element} {lset} {Variables and Procedures} {Change an element in a list} {lsort} {List Handling} {Sort the elements of a list} {memory} {Interpreter Routines} {Control Tcl memory debugging capabilities.} {msgcat} {Library Procedures} {Tcl message catalog} {namespace} {Variables and Procedures} {create and manipulate contexts for commands and variables} {open} {Output} {Open a file-based or command pipeline channel} {package} {Packages and Source files} {Facilities for package loading and version control} {pid} {System Related} {Retrieve process id(s)} {pkg::create} {Packages and Source files} {Construct an appropriate \fBpackage ifneeded\fR} {pkg_mkIndex} {Packages and Source files} {Build an index for automatic loading of packages} {proc} {Variables and Procedures} {Create a Tcl procedure} {puts} {Output} {Write to a channel} {pwd} {System Related} {Return the current working directory} {re_syntax} {String Handling} {Syntax of Tcl regular expressions.} {read} {Output} {Read from a channel} {regexp} {String Handling} {Match a regular expression against a string} {registry} {Platform-specific} {Manipulate the Windows registry} {regsub} {String Handling} {Perform substitutions based on regular expression pattern matching} {rename} {Variables and Procedures} {Rename or delete a command} {resource} {Platform-specific} {Manipulate Macintosh resources} {return} {Control Constructs} {Return from a procedure} {scan} {String Handling} {Parse string using conversion specifiers in the style of sscanf} {seek} {Output} {Change the access position for an open channel} {set} {Variables and Procedures} {Read and write variables} {socket} {Output} {Open a TCP network connection} {source} {Packages and Source files} {Evaluate a file or resource as a Tcl script} {split} {List Handling} {Split a string into a proper Tcl list} {string} {String Handling} {Manipulate strings} {subst} {String Handling} {Perform backslash, command, and variable substitutions} {switch} {Control Constructs} {Evaluate one of several scripts, depending on a given value} {tell} {Output} {Return current access position for an open channel} {time} {System Related} {Time the execution of a script} {trace} {Variables and Procedures} {Monitor variable accesses, command usages and command executions} {unknown} {Interpreter Routines} {Handle attempts to use non-existent commands} {unset} {Variables and Procedures} {Delete variables} {update} {Control Constructs} {Process pending events and idle callbacks} {uplevel} {Control Constructs} {Execute a script in a different stack frame} {upvar} {Variables and Procedures} {Create link to variable in a different stack frame} {variable} {Variables and Procedures} {create and initialize a namespace variable} {vwait} {Control Constructs} {Process events until a variable is written} {while} {Control Constructs} {Execute script repeatedly as long as a condition is met}}

set TkCommands {console General {Control the console on systems without a real console} destroy General {Destroy one or more windows} tk General {Manipulate Tk internal state} tkerror General {Command invoked to process background errors} tkvars General {Variables used or set by Tk} tkwait General {Wait for variable to change or window to be destroyed} winfo General {Return window-related information} wish General {Simple windowing shell} wm General {Communicate with window manager} bitmap {Resources and Options} {Images that display two colors} colors {Resources and Options} {symbolic color names recognized by Tk} cursors {Resources and Options} {mouse cursors available in Tk} font {Resources and Options} {Create and inspect fonts.} image {Resources and Options} {Create and manipulate images} keysyms {Resources and Options} {keysyms recognized by Tk} option {Resources and Options} {Add/retrieve window options to/from the option database} options {Resources and Options} {Standard options supported by widgets} tk_setPalette {Resources and Options} {Modify the Tk color palette} photo {Resources and Options} {Full-color images} button Widgets {Create and manipulate button widgets} canvas Widgets {Create and manipulate canvas widgets} checkbutton Widgets {Create and manipulate checkbutton widgets} entry Widgets {Create and manipulate entry widgets} frame Widgets {Create and manipulate frame widgets} label Widgets {Create and manipulate label widgets} labelframe Widgets {Create and manipulate labelframe widgets} listbox Widgets {Create and manipulate listbox widgets} menu Widgets {Create and manipulate menu widgets} menubutton Widgets {Create and manipulate menubutton widgets} message Widgets {Create and manipulate message widgets} tk_optionMenu Widgets {Create an option menubutton and its menu} panedwindow Widgets {Create and manipulate panedwindow widgets} radiobutton Widgets {Create and manipulate radiobutton widgets} scale Widgets {Create and manipulate scale widgets} scrollbar Widgets {Create and manipulate scrollbar widgets} spinbox Widgets {Create and manipulate spinbox widgets} text Widgets {Create and manipulate text widgets} ttk_button {Themed Widgets} {Widget that issues a command when pressed} ttk_checkbutton {Themed Widgets} {On/off widget} ttk_combobox {Themed Widgets} {text field with popdown selection list} ttk_entry {Themed Widgets} {Editable text field widget} ttk_frame {Themed Widgets} {Simple container widget} ttk_image {Themed Widgets} {Define an element based on an image} ttk_intro {Themed Widgets} {Introduction to the Tk theme engine} ttk_label {Themed Widgets} {Display a text string and/or image} ttk_labelframe {Themed Widgets} {Container widget with optional label} ttk_menubutton {Themed Widgets} {Widget that pops down a menu when pressed} ttk_notebook {Themed Widgets} {Multi-paned container widget} ttk_panedwindow {Themed Widgets} {Multi-pane container window} ttk_progressbar {Themed Widgets} {Provide progress feedback} ttk_radiobutton {Themed Widgets} {Mutually exclusive option widget} ttk::scale {Themed Widgets} {Create and manipulate a scale widget} ttk_scrollbar {Themed Widgets} {Control the viewport of a scrollable widget} ttk_separator {Themed Widgets} {Separator bar} ttk_sizegrip {Themed Widgets} {Bottom-right corner resize widget} ttk_style {Themed Widgets} {Manipulate style database} ttk_treeview {Themed Widgets} {hierarchical multicolumn data display widget} ttk_vsapi {Themed Widgets} {Define a Microsoft Visual Styles element} ttk_widget {Themed Widgets} {Standard options and commands supported by Tk themed widgets} tk_chooseColor {Dialogs and toplevels} {pops up a dialog box for the user to select a color.} tk_chooseDirectory {Dialogs and toplevels} {pops up a dialog box for the user to select a directory.} tk_dialog {Dialogs and toplevels} {Create modal dialog and wait for response} fontchooser {Dialogs and toplevels} {control font selection dialog} tk_getOpenFile {Dialogs and toplevels} {pop up a dialog box for the user to select a file to open or save.} tk_messageBox {Dialogs and toplevels} {pops up a message window and waits for user response.} tk_popup {Dialogs and toplevels} {Post a popup menu} toplevel {Dialogs and toplevels} {Create and manipulate toplevel widgets} grid {Geometry management} {Geometry manager that arranges widgets in a grid} lower {Geometry management} {Change a window's position in the stacking order} pack {Geometry management} {Geometry manager that packs around edges of cavity} place {Geometry management} {Geometry manager for fixed or rubber-sheet placement} raise {Geometry management} {Change a window's position in the stacking order} bind {Events and bindings} {Arrange for X events to invoke Tcl scripts} bindtags {Events and bindings} {Determine which bindings apply to a window, and order of evaluation} event {Events and bindings} {Miscellaneous event facilities: define virtual events and generate events} focus {Events and bindings} {Manage the input focus} tk_focusNext {Events and bindings} {Utility procedures for managing the input focus.} grab {Events and bindings} {Confine pointer and keyboard events to a window sub-tree} bell {Inter-client Communication} {Ring a display's bell} clipboard {Inter-client Communication} {Manipulate Tk clipboard} selection {Inter-client Communication} {Manipulate the X selection} send {Inter-client Communication} {Execute a command in a different application}}

set ActiveHelp [dict create after mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/after.htm append mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/append.htm format mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/format.htm array mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/array.htm bgerror mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/bgerror.html binary mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/binary.htm break mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/break.htm catch mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/catch.htm cd mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/cd.htm clock mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/clock.htm close mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/close.htm concat mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/concat.htm continue mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/continue.htm dde mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/dde.htm encoding mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/encoding.htm eof mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/eof.htm error mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/error.htm eval mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/eval.htm exec mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/exec.htm exit mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/exit.htm expr mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/expr.htm fblocked mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/fblocked.htm fconfigure mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/fconfigure.htm fcopy mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/fcopy.htm file mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/file.htm fileevent mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/fileevent.htm flush mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/flush.htm for mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/for.htm foreach mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/foreach.htm gets mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/gets.htm glob mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/glob.htm global mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/global.htm history mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/history.htm http mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/http.htm if mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/if.htm incr mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/incr.htm info mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/info.htm interp mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/interp.htm join mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/join.htm lappend mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/lappend.htm lindex mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/lindex.htm linsert mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/linsert.htm list mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/list.htm llength mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/llength.htm load mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/load.htm loadTk mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/loadTk.htm lrange mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/lrange.htm lreplace mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/lreplace.htm lsearch mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/lsearch.htm lset mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/lset.htm lsort mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/lsort.htm memory mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/memory.htm msgcat mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/msgcat.htm namespace mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/namespace.htm open mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/open.htm package mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/package.htm pid mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/pid.htm pkg::create mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/packagens.htm pkg_mkIndex mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/pkgMkIndex.htm proc mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/proc.htm puts mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/puts.htm pwd mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/pwd.htm re_syntax mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/re_syntax.htm read mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/read.htm regexp mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/regexp.htm registry mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/registry.htm regsub mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/regsub.htm rename mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/rename.htm return mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/return.htm scan mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/scan.htm seek mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/seek.htm set mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/set.htm socket mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/socket.htm source mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/source.htm split mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/split.htm string mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/string.htm subst mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/subst.htm switch mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/switch.htm tell mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/tell.htm time mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/time.htm trace mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/trace.htm unknown mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/unknown.htm unset mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/unset.htm update mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/update.htm uplevel mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/uplevel.htm upvar mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/upvar.htm variable mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/variable.htm vwait mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/vwait.htm while mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TclCmd/while.htm console mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/console.htm destroy mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/destroy.htm tk mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/tk.htm tkerror mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/tkerror.htm tkvars mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/tkvars.htm tkwait mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/tkwait.htm winfo mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/winfo.htm wish mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/UserCmd/wish.htm wm mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/wm.htm bitmap mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/bitmap.htm colors mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/colors.htm cursors mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/cursors.htm font mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/font.htm image mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/image.htm keysyms mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/keysyms.htm option mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/option.htm options mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/options.htm tk_setPalette mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/palette.htm photo mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/photo.htm button mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/button.htm canvas mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/canvas.htm checkbutton mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/checkbutton.htm entry mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/entry.htm frame mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/frame.htm label mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/label.htm labelframe mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/labelframe.htm listbox mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/listbox.htm menu mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/menu.htm menubutton mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/menubutton.htm message mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/message.htm tk_optionMenu mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/optionMenu.htm panedwindow mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/panedwindow.htm radiobutton mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/radiobutton.htm scale mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/scale.htm scrollbar mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/scrollbar.htm spinbox mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/spinbox.htm text mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/text.htm ttk_button mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_button.htm ttk_checkbutton mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_checkbutton.htm ttk_combobox mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_combobox.htm ttk_entry mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_entry.htm ttk_frame mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_frame.htm ttk_image mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_image.htm ttk_intro mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_intro.htm ttk_label mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_label.htm ttk_labelframe mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_labelframe.htm ttk_menubutton mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_menubutton.htm ttk_notebook mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_notebook.htm ttk_panedwindow mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_panedwindow.htm ttk_progressbar mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_progressbar.htm ttk_radiobutton mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_radiobutton.htm ttk::scale mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk::scale.htm ttk_scrollbar mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_scrollbar.htm ttk_separator mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_separator.htm ttk_sizegrip mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_sizegrip.htm ttk_style mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_style.htm ttk_treeview mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_treeview.htm ttk_vsapi mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_vsapi.htm ttk_widget mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/ttk_widget.htm tk_chooseColor mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/chooseColor.htm tk_chooseDirectory mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/chooseDirectory.htm tk_dialog mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/dialog.htm fontchooser mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/fontchooser.htm tk_getOpenFile mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/getOpenFile.htm tk_messageBox mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/messageBox.htm tk_popup mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/popup.htm toplevel mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/toplevel.htm grid mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/grid.htm lower mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/lower.htm pack mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/pack.htm place mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/place.htm raise mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/raise.htm bind mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/bind.htm bindtags mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/bindtags.htm event mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/event.htm focus mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/focus.htm tk_focusNext mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/focusNext.htm grab mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/grab.htm bell mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/bell.htm clipboard mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/clipboard.htm selection mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/selection.htm send mk:@MSITStore:C:/tcl8.6/doc/ActiveTclHelp8.6.chm::/tcl/TkCmd/send.htm]


set TclLib [list page {Parser Generator} tcldocstrip {Tcl-based Docstrip Processor} nnslog {Name service facility, Commandline Logging Client Application} nns {Name service facility, Commandline Client Application} dtplite {Lightweight DocTools Markup Processor} nnsd {Name service facility, Commandline Server Application} aes {Implementation of the AES block cipher} bee {BitTorrent Serialization Format Encoder/Decoder} asn {ASN.1 BER encoder/decoder} des {Implementation of the DES and triple-DES ciphers} sum {Calculate a sum(1) compatible checksum} crc16 {Perform a 16bit Cyclic Redundancy Check} cksum {Calculate a cksum(1) compatible checksum} crc32 {Perform a 32bit Cyclic Redundancy Check} csv {Procedures to handle CSV data.} dns {Tcl Domain Name Service Client} tcllib_ip {IPv4 and IPv6 address manipulation} ftp::geturl {Uri handler for ftp urls} ftp {Client-side tcl implementation of the ftp protocol} picoirc {Small and simple embeddable IRC client.} irc {Create IRC connection and interface.} md4 {MD4 Message-Digest Algorithm} md5 {MD5 Message-Digest Algorithm} map::slippy::fetcher {Accessing a server providing tiles for slippy-based maps} map::slippy {Common code for slippy based map packages} map::slippy::cache {Management of a tile cache in the local filesystem} log {Procedures to log messages of libraries and applications.} logger::utils {Utilities for logger} logger {System to control logging of events.} logger::appender {Collection of predefined appenders for logger} nameserv::server {Name service facility, Server} nameserv::auto {Name service facility, Client Extension} nameserv {Name service facility, Client} nameserv::common {Name service facility, shared definitions} nns_intro {Name service facility, introduction} nameserv::protocol {Name service facility, client/server protocol} ntp_time {Tcl Time Service Client} otp {One-Time Passwords} png {PNG querying and manipulation of meta data} rc4 {Impementation of the RC4 stream cipher} rcs {RCS low level utilities} tar {Tar file creation, extraction & manipulation} tie {Array persistence} tie {Array persistence, standard data sources} uevent {User events} uevent::onidle {Request merging and deferal to idle time} uri_urn {URI utilities, URN scheme} uri {URI utilities} wip {Word Interpreter} cmdline {Procedures to process command lines and options.} transfer::data::destination {Data destination} transfer::copy::queue {Queued transfers} transfer::copy {Data transfer foundation} transfer::data::source {Data source} transfer::transmitter {Data source} transfer::receiver {Data source} transfer::connect {Connection setup} comm {A remote communication facility for Tcl (8.3 and later)} comm_wire {The comm wire protocol} exif {Tcl EXIF extracts and parses EXIF fields from digital images} ftpd {Tcl FTP server implementation} html {Procedures to generate HTML structures} autoproxy {Automatic HTTP proxy usage and authentication} jpeg {JPEG querying and manipulation of meta data} json {JSON parser} ldapx {LDAP extended object interface} ldap {LDAP client} math::interpolate {Interpolation routines} math::geometry {Geometrical computations} math::calculus::romberg {Romberg integration} math::fourier {Discrete and fast fourier transforms} math::rationalfunctions {Polynomial functions} math::optimize {Optimisation routines} math::polynomials {Polynomial functions} math {Tcl Math Library} math::complexnumbers {Straightforward complex number package} math::constants {Mathematical and numerical constants} math::linearalgebra {Linear Algebra} math::statistics {Basic statistical functions and procedures} math::roman {Tools for creating and manipulating roman numerals} math::fuzzy {Fuzzy comparison of floating-point numbers} math::special {Special mathematical functions} math::bigfloat {Arbitrary precision floating-point numbers} math::calculus {Integration and ordinary differential equations} math::combinatorics {Combinatorial functions in the Tcl Math Library} math::bignum {Arbitrary precision integer numbers} mime {Manipulation of MIME body parts} smtp {Client-side tcl implementation of the smtp protocol} ncgi {Procedures to manipulate CGI values.} nmea {Process NMEA data} nntp {Tcl client for the NNTP protocol} page_util_norm_lemon {page AST normalization, LEMON} page_util_peg {page PEG transformation utilities} page_intro {page introduction} page_pluginmgr {page plugin manager} page_util_quote {page character quoting utilities} page_util_norm_peg {page AST normalization, PEG} page_util_flow {page dataflow/treewalker utility} pop3 {Tcl client for POP3 email protocol} SASL {Implementation of SASL mechanisms for Tcl} sha256 {SHA256 Message-Digest Algorithm} sha1 {SHA1 Message-Digest Algorithm} snitfaq {Snit Frequently Asked Questions} snit {Snit's Not Incr Tcl} term::send {General output to terminals} term::ansi::code::attr {ANSI attribute sequences} term::ansi::send {Output of ANSI control sequences to terminals} term::interact::menu {Terminal widget, menu} term::ansi::ctrl::unix {Control operations and queries} term {General terminal control} term::ansi::code::macros {Macro sequences} term::ansi::code::ctrl {ANSI control sequences} term::receive {General input from terminals} term::receive::bind {Keyboard dispatch from terminals} term::ansi::code {Helper for control sequences} term::interact::pager {Terminal widget, paging} tiff {TIFF reading, writing, and querying and manipulation of meta data} uuid {UUID generation and comparison} yaml {YAML Format Encoder/Decoder} huddle {Create and manipulate huddle object} multiplexer {One-to-many communication with sockets.} control {Procedures for control flow structures.} counter {Procedures for counters and histograms} htmlparse {Procedures to parse HTML strings} md5crypt {MD5-based password encryption} bench::in {bench::in - Reading benchmark results} bench::out::text {bench::out::text - Formatting benchmark results as human readable text} bench_lang_intro {bench language introduction} bench_intro {bench introduction} bench {bench - Processing benchmark suites} bench_lang_spec {bench language specification} bench::out::csv {bench::out::csv - Formatting benchmark results as CSV} cache::async {Asynchronous in-memory cache} ident {Ident protocol client} pop3d::udb {Simple user database for pop3d} pop3d {Tcl POP3 server implementation} pop3d::dbox {Simple mailbox database for pop3d} smtpd {Tcl SMTP server implementation} units {unit conversion} S3 {Amazon S3 Web Service Interface} xsxp {eXtremely Simple Xml Parser} mapproj {Map projection routines} fileutil::multi::op {Multi-file operation, scatter/gather} fileutil {Procedures implementing some file utilities} fileutil::multi {Multi-file operation, scatter/gather, standard object} fileutil_traverse {Iterative directory traversal} soundex Soundex unicode::data {unicode data tables, generated, internal} stringprep {Implementation of stringprep} stringprep::data {stringprep data tables, generated, internal} unicode {Implementation of Unicode normalization} textutil::tabify {Procedures to (un)tabify strings} textutil::trim {Procedures to trim strings} textutil::expander {Procedures to process templates and expand text.} textutil::repeat {Procedures to repeat strings.} textutil::string {Procedures to manipulate texts and strings.} textutil::split {Procedures to split texts} textutil::adjust {Procedures to adjust, indent, and undent paragraphs} textutil {Procedures to manipulate texts and strings.} base32 {base32 standard encoding} base32::hex {base32 extended hex encoding} base32::core {Expanding basic base32 maps} yencode {Y-encode/decode binary data} base64 {base64-encode/decode binary data} uuencode {UU-encode/decode binary data} bibtex {Parse bibtex files} blowfish {Implementation of the Blowfish block cipher} javascript {Procedures to generate HTML and Java Script structures.} grammar::fa::dexec {Execute deterministic finite automatons} grammar::fa::op {Operations on finite automatons} grammar::fa::dacceptor {Create and use deterministic acceptors} grammar::fa {Create and manipulate finite automatons} grammar::me::tcl {Virtual machine implementation I for parsing token streams} grammar::me::cpu::core {ME virtual machine state manipulation} grammar::me_ast {Various representations of ASTs} grammar::me::util {AST utilities} grammar::me_intro {Introduction to virtual machines for parsing token streams} grammar::me::cpu {Virtual machine implementation II for parsing token streams} grammar::me::cpu::gasm {ME assembler} grammar::me_vm {Virtual machine for parsing token streams} deleg_proc {Creation of comm delegates (procedures)} deleg_method {Creation of comm delegates (snit methods)} interp {Interp creation and aliasing} fileutil::magic::rt {Runtime core for file type recognition engines written in pure Tcl} fileutil::magic::filetype {Procedures implementing file-type recognition} fileutil::magic::cfront {Generator core for compiler of magic(5) files} fileutil::magic::cgen {Generator core for compiler of magic(5) files} fileutil::magic::mimetype {Procedures implementing mime-type recognition} report {Create and manipulate report objects} ripemd128 {RIPEMD-128 Message-Digest Algorithm} ripemd160 {RIPEMD-160 Message-Digest Algorithm} stooop {Object oriented extension.} struct::skiplist {Create and manipulate skiplists} struct::pool {Create and manipulate pool objects (of discrete items)} struct::record {Define and create records (similar to 'C' structures)} struct::matrix {Create and manipulate matrix objects} struct::tree {Create and manipulate tree objects} struct::list {Procedures for manipulating lists} struct::matrix {v1 Create and manipulate matrix objects} struct::set {Procedures for manipulating sets} struct::stack {Create and manipulate stack objects} struct::graph {Create and manipulate directed graph objects} struct::disjointset {Disjoint set data structure} struct::prioqueue {Create and manipulate prioqueue objects} struct::tree {v1 Create and manipulate tree objects} struct::graph {v1 Create and manipulate directed graph objects} struct::queue {Create and manipulate queue objects} struct::graph::op {Operation for (un)directed graph objects} treeql {Query tree objects} simulation::random {Pseudo-random number generators} simulation::annealing {Simulated annealing} simulation::montecarlo {Monte Carlo simulations} grammar::peg {Create and manipulate parsing expression grammars} grammar::peg::interp {Interpreter for parsing expression grammars} profiler {Tcl source code profiler} inifile {Parsing of Windows INI files} docstrip {Docstrip style source code extraction} docstrip_util {Docstrip-related utilities} doctools::cvs {Processing text in 'cvs log' format} doctoc_lang_cmdref {doctoc language command reference} doctools_lang_syntax {doctools language syntax} doctools::toc {doctoc - Processing tables of contents} docidx_lang_cmdref {docidx language command reference} docidx_lang_intro {docidx language introduction} doctools_plugin_apiref {doctools plugin API reference} doctoc_plugin_apiref {doctoc plugin API reference} docidx_intro {docidx introduction} doctools {doctools - Processing documents} doctoc_lang_syntax {doctoc language syntax} doctools::changelog {Processing text in Emacs ChangeLog format} mpexpand {Markup processor} docidx_lang_syntax {docidx language syntax} doctoc_lang_intro {doctoc language introduction} doctools::idx {docidx - Processing indices} doctools_lang_intro {doctools language introduction} doctools_intro {doctools introduction} doctools_lang_faq {doctools language faq} docidx_plugin_apiref {docidx plugin API reference} docidx_lang_faq {docidx language faq} doctoc_lang_faq {doctoc language faq} doctoc_intro {doctoc introduction} doctools_lang_cmdref {doctools language command reference} pluginmgr {Manage a plugin}]


# 2) create it
mlbnb .nb \
    -nb 3\
    -0 {
        -text {Commandes Tcl} 
        -nbcols 3
        -listvariable ::TclCommands
        -titlefont {-family Helvetica -size 15}
        -font {-family Helvetica -size 11}
        -href {
            exec -- firefox.exe \
                [regsub %% {http://wiki.tcl.tk/_/search?S=%%&_charset_=UTF-8} [%%MW column0 do get [%%MW column0 do curselection]]] &
        }
        -mref {
            destroy .m0
            %%MW column0 do selection clear 0 end
            %%MW column0 do selection set @$x,$y
            set index [%%MW column0 do curselection]
            %%MW column1 do selection clear 0 end
            %%MW column2 do selection clear 0 end
            %%MW column1 do selection set $index
            %%MW column2 do selection set $index
            menu .m0 -tearoff false 
            .m0 add command \
                -label [regsub %% {Aide active Tcl : %%} [%%MW column0 do get [%%MW column0 do curselection]]]\
                -command {
                exec -- hh.exe [dict get $::ActiveHelp [%%MW column0 do get [%%MW column0 do curselection]]] &
                destroy .m0
            }
            tk_popup .m0 $X $Y
        }
        -0 {-text {Commande} -weight 1} 
        -1 {-text {Catégorie} -weight 2}
        -2 {-text {Description} -weight 38}
    } \
    -1 {
        -text {Commandes Tk}
        -nbcols 3
        -listvariable ::TkCommands
        -titlefont {-family Helvetica -size 15}
        -font {-family Helvetica -size 11}
        -href {
            exec -- firefox.exe \
                [regsub %% {http://wiki.tcl.tk/_/search?S=%%&_charset_=UTF-8} [%%MW column0 do get [%%MW column0 do curselection]]] &
        }
        -mref {
            destroy .m0
            %%MW column0 do selection clear 0 end
            %%MW column0 do selection set @$x,$y
            set index [%%MW column0 do curselection]
            %%MW column1 do selection clear 0 end
            %%MW column2 do selection clear 0 end
            %%MW column1 do selection set $index
            %%MW column2 do selection set $index
            menu .m0 -tearoff false 
            .m0 add command \
                -label [regsub %% {Aide active Tcl : %%} [%%MW column0 do get [%%MW column0 do curselection]]]\
                -command {
                exec -- hh.exe [dict get $::ActiveHelp [%%MW column0 do get [%%MW column0 do curselection]]] &
                destroy .m0
            }
            tk_popup .m0 $X $Y
        }
        -0 {-text {Commande} -weight 1}
        -1 {-text {Catégorie} -weight 2}
        -2 {-text {Description} -weight 38}
    } \
    -2 {
        -text {Tcl lib}
        -nbcols 2
        -titlefont {-family Helvetica -size 15}
        -font {-family Helvetica -size 11}
        -listvariable ::TclLib
        -href {
            exec -- firefox.exe \
                [regsub %% {http://wiki.tcl.tk/_/search?S=%%&_charset_=UTF-8} [%%MW column0 do get [%%MW column0 do curselection]]] &
        }
        -mref {
            destroy .m0
            %%MW column0 do selection clear 0 end
            %%MW column0 do selection set @$x,$y
            set index [%%MW column0 do curselection]
            %%MW column1 do selection clear 0 end
            %%MW column1 do selection set $index
            menu .m0 -tearoff false 
            .m0 add command \
                -label [regsub %% {Aide active Tcl : %%} [%%MW column0 do get [%%MW column0 do curselection]]]\
                -command {
                exec -- hh.exe [dict get $::ActiveHelp [%%MW column0 do get [%%MW column0 do curselection]]] &
                destroy .m0
            }
            tk_popup .m0 $X $Y
        }
        -0 {-text {Librairie} -weight 1} 
        -1 {-text {Description} -weight 38}
    }

pack [.nb rootpath] -expand 1 -fill both

An editor

package require megawidget

megawidget create ScrollText {
    {*}[package require stext; set res []] \
        > \
             [widget frame \
                  [@ \
                       [widget scrollbar \
                            [wOptions -orient v -command {%MW text do yview}]\
                            [gmPack -expand 0 -fill y -padx 0 -pady 0 -side right]\
                            [handler sy]\
                           ]\
                       [widget scrollbar \
                            [handler sx]\
                            [wOptions -orient h -command {%MW text do xview}]\
                            [gmPack -expand 0 -fill x -side bottom]\
                           ]\
                       [widget text\
                            [wOptions -yscrollcommand {%MW sy do set} -xscrollcommand {%MW sx do set}]\
                            [handler text]\
                            [gmPack -expand 1 -fill both]\
                           ]]]}

megawidget create Editeur {
    v \
        [widget frame \
             [handler toolbar \
                  [hMethods \
                       add {} {
                       }]]\
             [gmPack -expand 0 -fill x -padx 5 -pady 5]\
             [> \
                  [widget ttk::button \
                       [handler bNew]\
                       [wOptions \
                            -text "New File" \
                            -image [image create photo -data {
                                iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
                                WXMAAAuHAAALhwGTQIdTAAAAB3RJTUUH1gcYDR0QxT0Z2QAAA3VJREFUSMe1lc1vG1UUxX9v7PFH
                                nXGdhFQhNG2RQShf7OAfQF1USKgrkFixAgkWSLBlh5CABUtEVwghdVHxL9BFFyxYIZIUqqYlxQoQ
                                Qm3L9sR27LmHhWdsJ5kipKojXenN03vn3K9zHzzhz/3fg2F7owxUQOeAeVAJ8IEBuBA4ALdTCjZb
                                qQSffv7J28C1NPBisUch36dcDglmQorFHr4/wPfzDAZ9Ll3Y+3J+vv0zuBqwWQq2asnd7BTOtVev
                                vEa1WqVYLI43pQ7S35jdYzi4j7QHOqC7+xUAtnCVv/aDdz0vvFEuRz9lMq4QttfDUrBVP0lAtVol
                                iiI6nU68M0Q6AN1jULtCbvkD4HeOat8xu9rFuQL1bcczSy/TaFRePzxs5oLABIRhe+NmKdgcZI+n
                                ojgGF0IKQXUc+wAc1b4AoPzCjzhXAGB2tUHj9iwVgD5XCVb3gQawAPzhpeVcEhKgAajJoPYWM899
                                T2Wlz9yayGZfmhTRVZhbE3NrInj+F3oPbr8DWgAWAbx0cCEzZH2kQ7LnP6az8wrOef/Zae27KxQu
                                rtwCyqBHEJghjcwkYBgb9HsfISkVfDjcTpa5uH2zqQQmYRIyIWWRMkgZ/OU3OLz/GbJ6KkHrzjr+
                                +VWAo5E2+CeVACURCFkGUwGpiGxmlHOv/MgUdbt5gCbQArefniJi7zFEHlkZswrSXFxUH6lLfdtR
                                33ZYdDC+2+nMAO7PkbF3SgcAZpoUWhngaTzvIc5aeEvvU98eiT9/YQPnBjR/PQdA4eJ7NO7ssrhY
                                3wV3sxRs9U4RtNttLIpiDQgkpAIWLaNMF0+GW/wQzz1kOAyBAd7SOrISprM0GmcBbpWCrd/SRsWk
                                TUkisJjoKSLLkfVyOK+Ec/M4QnARkoesiJ97lrs74vLl6z9M46UQxAU+JjghzXAUvQg08LwGnqsj
                                IiwKiKxMsbROq/3gVOETgnGx7Vh6JmvDQB7SHFFUAV2Kz4JMQD61s7KnIjGbAo+7Cpv8y0BTio/X
                                YZgMSDzAThLkAcKwM1JvcjlpWU1qAhPQUTo5qe4C0EtIEgJ/orPE4zj3HAcSk0gmZ2ya4EysZgFK
                                CKJxSH7ucZ9hb6zZqQj67Vb7+jfffv3m4yA3G80bU94fe5NdPAWD0ajlTFyXTJy+TOyMiz3UlPWA
                                zmj+jC2aJnmi378NICLymcn25wAAAABJRU5ErkJggg==            
                            }] -compound top \
                            -command {
                                set F [tk_getSaveFile]
                                %MW tab add $F 
                            }\
                            -style Toolbutton] \
                       [gmPack -ipadx 2 -ipady 5 -expand 0 -fill none]\
                      ]\
                  [widget ttk::button \
                       [handler bOpen]\
                       [gmPack -ipadx 2 -ipady 5 -expand 0 -fill none]\
                       [wOptions \
                            -text "Open File" \
                            -image [image create photo -data {
                                iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
                                WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1gkWFgcxduV2nwAAAwBJREFUSMfVlb9vHFUQxz9vbw8d
                                CRQ+h6soaVKALJEGUVlIB1VACiFuUlFESFDkD6AIJTUddEHCJjH5YUCiCL8khA1FLBpLjiNFCrax
                                Te6H7853+/bNDMXuHWcO+2wQBU9a7dt535nvznd2duD/vlx/c/7CuXeB9w7BXrx1c+ETn3j5pwQ2
                                M3OWSuXUCGh7+3dmZ28DXLw2N//xcQji4YdK5RQrK7+MgE6ffo7yRIlavXf1/IVzV8fE/ODa3Pw7
                                f0sAsLvbGfFYWvqR6svVsW/74MFDFhfvvg0cTNDpdAHY2HhErdYaIlk5NHi5/CTV6jSLi3cPlmh4
                                1WotPp29fmSt35h5HTM7vAbACKhefzQ2+MTEJACqOuIf/zW4qqL6J2h5eXkswfT0S+O/on5wCYqh
                                A8DU1NSRZYqi6GAC5xzOOdT2p3ncDJxzB0vknCOEsI/gOBmMbTQgJ8j2vV6XS29dOnKwubmFwV8h
                                hPDMjflb911u+EhE3hzW0AzK5UlefOEMz595Fu/bdHseVclqpZrXTFAR0tRTevwEnXbK/Gdf0Gw2
                                n/789pfrcfamydkrVy5TjIs4QCxzNjW899RqvxFESNOAiqL5uaoiIogoqfcUCkUazSYhiEVRnA4k
                                iiJnIkq320Akk0hyAlUFM9SM1HtEBDXLziUnUCVJPE+o0unsoSobqsEP16BhZpVeL8Esc8oyyHpC
                                zRARfOIJIplN83tOkiQJVp5k/ddNut3unSTxyYBA1dppGggh0OvtAW4gQV+SIEqaeEQNs9w+JJH3
                                CQa0O3vsNtute6v3ikA3zodCc2HhDq+9+gqNxmrWdGK51jYI5H2KSNYn/eyybIU0FVSgXm+wtbW1
                                vrOz8xhAAaDVbn1bKpWqJ0+eeMpFjtQLIShpyDpbBIIYqg6IcESYRTgX4aICkYuJ4yLffb9Eo95c
                                +2np5w9F5CGQxAAb65ubW1vbl7/+5oev/u0MXlu7/76IrALtfSMzz6aY29zQSB3e9xtFAcuv4bMC
                                EIBOjvnv1x9cqSJ+BVI3zAAAAABJRU5ErkJggg==
                            }] -compound top \
                            -command {
                                if {[set F [tk_getOpenFile]] ne {}} {
                                    set Hand [%MW tab add $F]
                                    set fid [open $F r]
                                    [%MW $Hand obj] text do delete 0.0 end
                                    [%MW $Hand obj] text do insert end [read $fid]
                                    close $fid
                                }
                            }\
                            -style Toolbutton]\
                      ]\
                  [widget ttk::separator \
                       [wOptions -orient v]\
                       [gmPack -expand 0 -fill y -padx 5]
                  ]\
                  [widget ttk::button \
                       [handler bSave]\
                       [gmPack -ipadx 2 -ipady 5 -expand 0 -fill none]\
                       [wOptions \
                            -text "Save File" \
                            -image [image create photo -data {
                                iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
                                WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1gkHFy8F42t2TQAAAtpJREFUSMe1lktoFEEQhr/unpnd
                                mWRjVKJBEyQaFRVEMV4UQUEvgiCexXfQqyKCIsHHQcSDCiKCEREvIuhFRb0LHtSDHkQPAR9Bo0GN
                                uMluZna7PMzu7CZxIVlMwzDdRVN//fVXdTdM81AAndsv9BbCaD8o7s86XrezHT/PgSgxjr7R9+BY
                                N4ADUIiKe6+e3snA4BArRx/XDbD71waamxrU5ZtP9gEVAES077mcufKIzddu0diYmbLzbPYPtw7d
                                4fCBrSDost1JcqVg07oVAGit62KwvmsJVmSMrQpA8f7TDwAGBr8SFcJJO3YdjyAV8O7DD9asXPRv
                                ABSoWHMWtHVMOfrBwW+gFHYsgQqAVgqlYgBjnPpKUlEboLwB4MPnPkbD/KQdp7w0aTeNUgqppQFU
                                GHR2LJ1y9P39H2OAUpqTzJQngiQM6u5aRW0GIqCUTqKpZ2ilsOMYJABFgZY5s9h1/hmVIASRmB1S
                                CWTMumrePHtGbQbWCm3trbS1t5YclZyLYEXitRUE4n+1vWqvqFoMSvU19PYh2c+vJ5eTmcvJNq0C
                                AeMYGjI+kKnBoEQt2/+Gkz0nCPxGXNfFczxc18V1XAShUCxSLBQZ+j1ET08Pnau3JeIOfP+F1OoD
                                aytJ9tMBb96+4s7te8nGs2fPkM/nyOVzjIYhc1taEbFxY1mhMXBJpdyJwlcYVIzGOPhpP2a0cA8A
                                URQSlr8wxIotHYwKbRS+5/yzinS1BrokkGMM6VQAQOvcZoDEcRhGOI5JqkVrjdEG3zNorcp32ESA
                                /u+/WTIvM5HB80sxQBhHL2JJeankYNRaobXGcw1aa8ZJEGtgFAev3Hx6sXvnliAGMCxetIze6zeI
                                ooj8aI6R3AjDw8OAYLRJ7ox5M30sQlPg0jLDp1gUUMqOuZMB2jceOWqClgtrMy+n1L0v/nSNPzDE
                                SP5u3+NT+4CR6oTNBxr+02PCAl+Akel+tfAX6lA0Aw08di8AAAAASUVORK5CYII=
                            }] -compound top \
                            -command {
                            }\
                            -style Toolbutton]]\
                  [widget ttk::button \
                       [handler bSaveAs]\
                       [gmPack -ipadx 2 -ipady 5 -expand 0 -fill none]\
                       [wOptions \
                            -text "Save File As" \
                            -image [image create photo -data {
                                iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
                                WXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH1gkHFy81xbJG4QAAA4ZJREFUSMe1ll9oHFUUxn/33pnd
                                zCabJjExoSaCtqZUodh/LxVFxT5YLIovCqYxTZuq1P+IWNFg2kKQCFqoErDNEgxShPiiUgWfoiJY
                                FQ1SLVJt00VqY9Mt3WQ3s9l7fJjN7G62K1XshWHmXs583/nOOfeeC1d5KICVDwwdWvBzO0DxYdOe
                                /wz24MwgiBLj6MMnP3qxD8ABWMjlt78z0MXZ6RRr5o9eEdjk+AQAHRtX0Xh9KwCPXridhvpadSDx
                                aS9QJEBEexGXvQc/4Z7hUerq4v8IfurpZla9BNFf72ByfAKz7SvS6UuMPn6E53ZuAUEv2jphrBTc
                                tekWALTWVcF/e7IpBJ//ZqLM/rYNnViRMvsSAsWJqfMAPPHMs2zvfrgCvDmxpQz8xBmYXdvFrt1P
                                8cbgfn45dZ71a1ZcngAFKsg5I8PDFeA/98UqwJvvf5XV9+1hFJie/hOUwpYLKBJopVAqIDDGKTP6
                                qTdSAd6+M0HDpkcQkfA/pahOsGgA0LOrj55tDxVDQzl4ausB/sq3whefIyKMJN5naHA/SimkWg6g
                                qGBsJBGu/tCtWTcGu3NZdrjQOXCM2A3rC8UXeL/57ntJJk8HBIUwVxAIEiooHevG4Psu6Bx4OwQu
                                LYylEaiqQASUCsotmTwdGkxN/Q7ADDBTsg5grS0raa0UtpqCvEDLtU10v/4lRScEkUAdUnSkbF7y
                                3XDNsuoKrBXaO9po72gL4ysSvK1IMLeCQPAuXS+xFVVNQaG+Usc/Jn3mxys73RpvJl1/KwgYx1Ab
                                94B4FQUFaenkJK/0v0zMq8N1XSJOBNd1cR0XQVjI58kv5EldTNHf38/KtVvD5J49dwGptg+sLQbZ
                                q4kxefw7jrw3Hhru27eXbDZDJpth3vdpbWlDxAYbywp1MZdo1K0QqYsKiovGOHg1XqDoxh4Acjkf
                                f/HxfazYwkGn0EbhRZzLVpEuzYEuJMgxhppoDIC21gaAENj3cziOCatFa43RBi9i0Fot9rBKguS5
                                i3Quj1cq+PqtgMAPvBexRCPR8GDUWqG1JuIatNYsSUGQA6N47GDiszf7ujbHAgLDTStWc+jdw+Ry
                                ObLzGeYyc8zOzgKC0SbcYMsbPSxCfcylZZlHPi+glC3ryQAddz7/gom1DG2Mf/uv+vCxSxuWtnkx
                                kv3g5NHXeoG50oBdB9T+T5cJC/wBzF3tWwt/A+V/iLv19HhJAAAAAElFTkSuQmCC
                            }] -compound top \
                            -command {
                            }\
                            -style Toolbutton]\
                      ]]]\
        \
        [widget ttk::separator \
             [wOptions -orient h]\
             [gmPack -expand 0 -fill x]]\
        \
        [widget ttk::notebook \
             [wOptions -padding 5]\
             [gmPack -expand 1 -fill both -padx 5 -pady 5]\
             [handler tab \
                  [hVars Files [hVal {}] NumTab [hVal 1]]\
                  [hMethods add {name} {
                      variable Files
                      variable NumTab
                      if {$Files eq ""} {
                          %MW tab do tab 0 -text [file tail $name]
                          set Files $name
                          return text1
                      } else {
                          %MW tab do add [[set mPath [ScrollText [%MW tab path].scrollText[incr NumTab]]] rootpath] -text [file tail $name]
                          lappend Files $name
                          return [%O createHandler text$NumTab $mPath]
                      }
                  }]]\
             [> \
                  [mwidget ScrollText\
                       [handler text1]\
                       [gmNotebook -text {}]
                  ]]]}

pack [[Editeur [toplevel .top16].edit] rootpath] -expand 1 -fill both