1#----------------------------------------------------- 2# Magic/TCL general-purpose toolkit procedures 3#----------------------------------------------------- 4# Tim Edwards 5# February 11, 2007 6# Revision 0 7#-------------------------------------------------------------- 8# Sets up the environment for a toolkit. The toolkit must 9# supply a namespace that is the "library name". For each 10# parameter-defined device ("gencell") type, the toolkit must 11# supply three procedures: 12# 13# 1. ${library}::${gencell_type}_params {gname} {...} 14# 2. ${library}::${gencell_type}_check {gname} {...} 15# 3. ${library}::${gencell_type}_draw {gname} {...} 16# 17# The first defines the parameters used by the gencell, and 18# declares default parameters to use when first generating 19# the window that prompts for the device parameters prior to 20# creating the device. The second checks the parameters for 21# legal values. The third draws the device. 22#-------------------------------------------------------------- 23 24# Initialize toolkit menus to the wrapper window 25 26global Opts 27 28#---------------------------------------------------------------- 29# Add a menu button to the Magic wrapper window for the toolkit 30#---------------------------------------------------------------- 31 32proc magic::add_toolkit_menu {framename button_text} { 33 menubutton ${framename}.titlebar.mbuttons.toolkit \ 34 -text $button_text \ 35 -relief raised \ 36 -menu ${framename}.titlebar.mbuttons.toolkit.toolmenu \ 37 -borderwidth 2 38 39 menu ${framename}.titlebar.mbuttons.toolkit.toolmenu -tearoff 0 40 pack ${framename}.titlebar.mbuttons.toolkit -side left 41} 42 43#---------------------------------------------------------------- 44# Add a menu item to the toolkit menu 45#---------------------------------------------------------------- 46 47proc magic::add_toolkit_button {framename button_text gencell_type library} { 48 set m ${framename}.titlebar.mbuttons.toolkit.toolmenu 49 $m add command -label "$button_text" -command \ 50 "magic::gencell_params {} $gencell_type $library" 51} 52 53#----------------------------------------------------- 54# Device selection 55#----------------------------------------------------- 56 57proc magic::gen_params {} { 58 59 # Find selected item (to-do: handle multiple selections) 60 set wlist [what -list] 61 set clist [lindex $wlist 2] 62 set ccell [lindex $clist 0] 63 set cdef [lindex $ccell 1] 64 if {[regexp {^(.*_[0-9]*)$} $cdef valid gname] != 0} { 65 set library [cellname property $gname library] 66 if {$library == {}} { 67 error "Gencell has no associated library!" 68 } else { 69 regexp {^(.*)_[0-9]*$} $cdef valid gencell_type 70 magic::gencell_params $gname $gencell_type $library 71 } 72 } else { 73 # Error message 74 error "No gencell device is selected!" 75 } 76} 77 78#----------------------------------------------------- 79# Add "Ctrl-P" key callback for device selection 80#----------------------------------------------------- 81 82magic::macro ^P magic::gen_params 83 84#------------------------------------------------------------- 85# gencell_setparams 86# 87# Go through the parameter window and collect all of the 88# named parameters and their values, and generate the 89# associated properties in celldef "$gname". 90#------------------------------------------------------------- 91 92proc magic::gencell_setparams {gname} { 93 set slist [grid slaves .params.edits] 94 foreach s $slist { 95 if {[regexp {^.params.edits.(.*)_ent$} $s valid pname] != 0} { 96 set value [$s get] 97 cellname property $gname $pname $value 98 } 99 } 100} 101 102#------------------------------------------------------------- 103# gencell_getparam 104# 105# Go through the parameter window, find the named parameter, 106# and return its value. 107#------------------------------------------------------------- 108 109proc magic::gencell_getparam {gname pname} { 110 set slist [grid slaves .params.edits] 111 foreach s $slist { 112 if {[regexp {^.params.edits.(.*)_ent$} $s valid ptest] != 0} { 113 if {$pname == $ptest} { 114 return [$s get] 115 } 116 } 117 } 118} 119 120#------------------------------------------------------------- 121# gencell_change 122# 123# Redraw a gencell with new parameters. 124#------------------------------------------------------------- 125 126proc magic::gencell_change {gname gencell_type library} { 127 if {[cellname list exists $gname] != 0} { 128 if {[eval "${library}::${gencell_type}_check $gname"]} { 129 suspendall 130 pushstack $gname 131 select cell 132 erase * 133 magic::gencell_draw $gname $gencell_type $library 134 popstack 135 resumeall 136 } else { 137 error "Parameter out of range!" 138 } 139 } else { 140 error "Cell $gname does not exist!" 141 } 142} 143 144#------------------------------------------------------------- 145# gencell_create 146# 147# Instantiate a new gencell called $gname. If $gname 148# does not already exist, create it by calling its 149# drawing routine. 150# 151# Don't rely on pushbox/popbox since we don't know what 152# the drawing routine is going to do to the stack! 153#------------------------------------------------------------- 154 155proc magic::gencell_create {gname gencell_type library} { 156 suspendall 157 if {[cellname list exists $gname] == 0} { 158 cellname create $gname 159 set snaptype [snap list] 160 snap internal 161 set savebox [box values] 162 pushstack $gname 163 magic::gencell_draw $gname $gencell_type $library 164 popstack 165 eval "box values $savebox" 166 snap $snaptype 167 } 168 getcell $gname 169 expand 170 resumeall 171} 172 173#------------------------------------------------------------- 174#------------------------------------------------------------- 175 176proc magic::gencell_check {gname gencell_type library} { 177 return [eval "${library}::${gencell_type}_check $gname"] 178} 179 180#------------------------------------------------------------- 181#------------------------------------------------------------- 182 183proc magic::gencell_draw {gname gencell_type library} { 184 185 # Set the parameters passed from the window text entries 186 magic::gencell_setparams $gname 187 188 # Call the draw routine 189 eval "${library}::${gencell_type}_draw $gname" 190 191 # Find the namespace of the draw procedure and set propery "library" 192 cellname property $gname library $library 193} 194 195#----------------------------------------------------- 196# Add a standard parameter to the gencell window 197#----------------------------------------------------- 198 199proc magic::add_param {gname pname ptext default_value} { 200 201 # Check if the parameter exists. If so, override the default 202 # value with the current value. 203 204 set value {} 205 if {[cellname list exists $gname] != 0} { 206 set value [cellname property $gname $pname] 207 } 208 if {$value == {}} {set value $default_value} 209 210 set numrows [lindex [grid size .params.edits] 0] 211 label .params.edits.${pname}_lab -text $ptext 212 entry .params.edits.${pname}_ent -background white 213 grid .params.edits.${pname}_lab -row $numrows -column 0 214 grid .params.edits.${pname}_ent -row $numrows -column 1 215 .params.edits.${pname}_ent insert end $value 216} 217 218#----------------------------------------------------- 219# Update the properties of a cell 220#----------------------------------------------------- 221 222proc magic::update_params {gname ptext default_value} { 223} 224 225#------------------------------------------------------------- 226# gencell_params --- 227# 1) If gname is NULL and gencell_type is set, then we 228# create a new cell of type gencell_type. 229# 2) If gname is non-NULL, then we edit the existing 230# cell of type $gname. 231# 3) If gname is non-NULL and gencell_type or library 232# is NULL or unspecified, then we derive the gencell_type 233# and library from the existing cell's property strings 234#------------------------------------------------------------- 235 236proc magic::gencell_params {gname {gencell_type {}} {library {}}} { 237 238 if {$gname == {}} { 239 set pidx 1 240 while {[cellname list exists ${gencell_type}_$pidx] != 0} { 241 incr pidx 242 } 243 set gname ${gencell_type}_$pidx 244 245 set ttext "New device" 246 set btext "Create" 247 set bcmd "magic::gencell_create $gname $gencell_type $library" 248 } else { 249 if {$gencell_type == {}} { 250 set gencell_type [cellname property ${gname} gencell] 251 } 252 if {$library == {}} { 253 set library [cellname property ${gname} library] 254 } 255 256 set ttext "Edit device" 257 set btext "Apply" 258 set bcmd "magic::gencell_change $gname $gencell_type $library" 259 } 260 261 catch {destroy .params} 262 toplevel .params 263 label .params.title -text "$ttext $gname" 264 frame .params.edits 265 frame .params.buttons 266 pack .params.title 267 pack .params.edits 268 pack .params.buttons 269 270 button .params.buttons.apply \ 271 -text "$btext" \ 272 -command [subst { $bcmd ; \ 273 .params.buttons.apply configure -text Apply}] 274 button .params.buttons.close -text "Close" -command {destroy .params} 275 276 pack .params.buttons.apply -padx 10 -side left 277 pack .params.buttons.close -padx 10 -side right 278 279 # Invoke the callback procedure that creates the parameter entries 280 281 eval "${library}::${gencell_type}_params $gname" 282} 283 284#------------------------------------------------------------- 285