Version 0 of Adding User Data to Widgets the Megawidget Way

Updated 1999-07-16 09:47:59

Some people have been asking (on news:comp.lang.tcl ) for the Tk core to be modified so that widgets all carry with them some additional user data. This is not necessary. The following script illustrates how you can do this without all that paraphanalia in pure Tcl...

  proc substvars {varlist script} {
      foreach varname $varlist {
          upvar $varname var
          regsub -all %%${varname}%% $script [list $var] script
      }
      return $script
  }
  foreach class {
      button checkbutton radiobutton menubutton menu label message
      frame toplevel scrollbar scale text canvas
  } {
      rename $class userdata'enabled'$class
      proc $class {pathname args} [substvars class {
          set class %%class%%
          set w [eval [list userdata'enabled'$class $pathname] $args]
          rename $w userdata'enabled'$w
          upvar #0 ::userdata'data ary
          set ary($w) {}
          proc $w {subcommand args} [substvars w {
              set w %%w%%
              if {![string compare $subcommand "setUserData"]} {
                  upvar #0 ::userdata'data ary
                  switch [llength $args] {
                      0 {
                          return $ary($w)
                      }
                      1 {
                          set ary($w) [lindex $args 0]
                          return
                      }
                      default {
                          return -code error "wrong # args: should be\
                                  \"$w setUserData ?value?\""
                      }
                  }
              } else {
                  return [uplevel userdata'enabled'$w $subcommand $args]
              }
          }]
          return $w
      }]
  }

I'll leave adding the finishing flourishes (like making the error messages take account of the new command, and deleting the user data and the proc when the widget is destroyed) up to others for now. DKF