Visual menus

if 0 {Richard Suchenwirth 2002-04-14 - The following code evolved after discussions in the Tcl Chatroom with dkf and others - an experiment in "visual coding" of menus, so the source code approximates the look of the final product in ASCII graphics.

A maybe surprising feature is how the | command is frequently redefined, with interp alias, to provide the pathname context that is obviously not given explicitly. This works well over sub- and "subsub" menus.

This quick sketch still leaves much to be desired (check- and radiobuttons, shortcuts, for instance) - please feel free to comment and improve!

WikiDbImage visualmenus.jpg }


 proc L args {
    if {[. cget -menu]==""} {
        . config -menu [menu .m]
    }
    set name [join $args]
    .m add cascade -label $name -menu [menu .m.m$name -tearoff 0]
    interp alias {} | {} addsubmenu .m.m$name
 }
 proc addsubmenu {menu args} {
    set name [join [lrange $args 0 end-1]]
    set cmd [lindex $args end]
    if {[lindex $cmd 0]=="|"} {
        set subsub [menu $menu.m[clock clicks] -tearoff 0]
        $menu add cascade -label $name -menu $subsub
        interp alias {} | {} addsubmenu $subsub
        eval $cmd
        interp alias {} | {} addsubmenu $menu
    } elseif [regexp {^[-]+} $args] {
        $menu add separator
    } else {
        $menu add command -label $name -command $cmd 
    }
 }

#-------------------------- Sample code, which also shows one cascaded submenu:

 L File
 | Open      openFile
 | Save      {saveAs known}
 | Save As.. saveAs
 | ---
 | Quit      exit

 L Edit
 | Cut       doCut
 | Copy      {
    | foo      {puts foo}
    | bar      {puts bar}
    | grill    {puts grill}
 }
 | Paste     doPaste

See also m+ for a very simple solution without cascading.


Category GUI - Arts and crafts of Tcl-Tk programming