Updated 2012-07-19 00:51:30 by RLE

This is a utility to assist adding keyboard acceleration to menus. It extracts most information from the menu's underlined character to accelerate it.

(formatting fixed a bit by FW)
 # Purpose -
 # turn all underlined menu entries into bindings
 # Assumes all underlines are unique
 # Todo 
 #   - if widget that is being bound to keyboard events already has that binding figure out what to do.
 #   - the UcharList dows not work on recursive calls so it will not catch duplicate characters
 #   - if something dynamically changes the menus this invoke system will break down.
 #   - fix so that topWin figured out from menuWidget. It seems that it is a toplevel
 #   - add somehow some generations of help informatin for application.
 # Notes -
 #  peculiar behavior when a keyboard focus is in a widget and both widget and topWin with bindings have same keybindings since they will 
 #  execute twice. Example is a entry widget and a ctrl-C operation which is also binded in the topwindow.
 # Assumptions - you only want these shortcuts to work when a topWin's widget has keyboard focus. plus the widget has the topwin in its bindtags list.

 proc accelerateMenu { menu {topWin .}  {modBase Control-Key} disableVarName } {
  set i 0
  set UCharsList {}
  while { $i <= [$menu index end] } {
   set type [ $menu type $i ]
   if { $type == "separator" } {incr i; continue}
   if { $type == "cascade"   } { accelerateMenu [$menu entrycget $i -menu]  $topWin $modBase $disableVarName; incr i ;continue} ; # Recursively follow cascades
   set label [ $menu entrycget $i -label]
   set underLineIndex [ $menu entrycget $i -underline]
   if {$underLineIndex < 0 } { incr i ;continue }
   set char [string index $label $underLineIndex]
   if { [lsearch $UCharsList $char] >= 0 } {
    puts "skipping $label"
    incr i
   bind $topWin <$modBase-$char> [format "if \{\$%s\} \{%s invoke %d\}"  $disableVarName $menu $i  ]
   $menu entryconfigure $i -accelerator <$modBase-$char>
   lappend UCharsList 
   incr i