285 lines
8.8 KiB
Tcl
285 lines
8.8 KiB
Tcl
#-----------------------------------------------------
|
|
# Magic/TCL general-purpose toolkit procedures
|
|
#-----------------------------------------------------
|
|
# Tim Edwards
|
|
# February 11, 2007
|
|
# Revision 0
|
|
#--------------------------------------------------------------
|
|
# Sets up the environment for a toolkit. The toolkit must
|
|
# supply a namespace that is the "library name". For each
|
|
# parameter-defined device ("gencell") type, the toolkit must
|
|
# supply three procedures:
|
|
#
|
|
# 1. ${library}::${gencell_type}_params {gname} {...}
|
|
# 2. ${library}::${gencell_type}_check {gname} {...}
|
|
# 3. ${library}::${gencell_type}_draw {gname} {...}
|
|
#
|
|
# The first defines the parameters used by the gencell, and
|
|
# declares default parameters to use when first generating
|
|
# the window that prompts for the device parameters prior to
|
|
# creating the device. The second checks the parameters for
|
|
# legal values. The third draws the device.
|
|
#--------------------------------------------------------------
|
|
|
|
# Initialize toolkit menus to the wrapper window
|
|
|
|
global Opts
|
|
|
|
#----------------------------------------------------------------
|
|
# Add a menu button to the Magic wrapper window for the toolkit
|
|
#----------------------------------------------------------------
|
|
|
|
proc magic::add_toolkit_menu {framename button_text} {
|
|
menubutton ${framename}.titlebar.mbuttons.toolkit \
|
|
-text $button_text \
|
|
-relief raised \
|
|
-menu ${framename}.titlebar.mbuttons.toolkit.toolmenu \
|
|
-borderwidth 2
|
|
|
|
menu ${framename}.titlebar.mbuttons.toolkit.toolmenu -tearoff 0
|
|
pack ${framename}.titlebar.mbuttons.toolkit -side left
|
|
}
|
|
|
|
#----------------------------------------------------------------
|
|
# Add a menu item to the toolkit menu
|
|
#----------------------------------------------------------------
|
|
|
|
proc magic::add_toolkit_button {framename button_text gencell_type library} {
|
|
set m ${framename}.titlebar.mbuttons.toolkit.toolmenu
|
|
$m add command -label "$button_text" -command \
|
|
"magic::gencell_params {} $gencell_type $library"
|
|
}
|
|
|
|
#-----------------------------------------------------
|
|
# Device selection
|
|
#-----------------------------------------------------
|
|
|
|
proc magic::gen_params {} {
|
|
|
|
# Find selected item (to-do: handle multiple selections)
|
|
set wlist [what -list]
|
|
set clist [lindex $wlist 2]
|
|
set ccell [lindex $clist 0]
|
|
set cdef [lindex $ccell 1]
|
|
if {[regexp {^(.*_[0-9]*)$} $cdef valid gname] != 0} {
|
|
set library [cellname property $gname library]
|
|
if {$library == {}} {
|
|
error "Gencell has no associated library!"
|
|
} else {
|
|
regexp {^(.*)_[0-9]*$} $cdef valid gencell_type
|
|
magic::gencell_params $gname $gencell_type $library
|
|
}
|
|
} else {
|
|
# Error message
|
|
error "No gencell device is selected!"
|
|
}
|
|
}
|
|
|
|
#-----------------------------------------------------
|
|
# Add "Ctrl-P" key callback for device selection
|
|
#-----------------------------------------------------
|
|
|
|
magic::macro ^P magic::gen_params
|
|
|
|
#-------------------------------------------------------------
|
|
# gencell_setparams
|
|
#
|
|
# Go through the parameter window and collect all of the
|
|
# named parameters and their values, and generate the
|
|
# associated properties in celldef "$gname".
|
|
#-------------------------------------------------------------
|
|
|
|
proc magic::gencell_setparams {gname} {
|
|
set slist [grid slaves .params.edits]
|
|
foreach s $slist {
|
|
if {[regexp {^.params.edits.(.*)_ent$} $s valid pname] != 0} {
|
|
set value [$s get]
|
|
cellname property $gname $pname $value
|
|
}
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
# gencell_getparam
|
|
#
|
|
# Go through the parameter window, find the named parameter,
|
|
# and return its value.
|
|
#-------------------------------------------------------------
|
|
|
|
proc magic::gencell_getparam {gname pname} {
|
|
set slist [grid slaves .params.edits]
|
|
foreach s $slist {
|
|
if {[regexp {^.params.edits.(.*)_ent$} $s valid ptest] != 0} {
|
|
if {$pname == $ptest} {
|
|
return [$s get]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
# gencell_change
|
|
#
|
|
# Redraw a gencell with new parameters.
|
|
#-------------------------------------------------------------
|
|
|
|
proc magic::gencell_change {gname gencell_type library} {
|
|
if {[cellname list exists $gname] != 0} {
|
|
if {[eval "${library}::${gencell_type}_check $gname"]} {
|
|
suspendall
|
|
pushstack $gname
|
|
select cell
|
|
erase *
|
|
magic::gencell_draw $gname $gencell_type $library
|
|
popstack
|
|
resumeall
|
|
} else {
|
|
error "Parameter out of range!"
|
|
}
|
|
} else {
|
|
error "Cell $gname does not exist!"
|
|
}
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
# gencell_create
|
|
#
|
|
# Instantiate a new gencell called $gname. If $gname
|
|
# does not already exist, create it by calling its
|
|
# drawing routine.
|
|
#
|
|
# Don't rely on pushbox/popbox since we don't know what
|
|
# the drawing routine is going to do to the stack!
|
|
#-------------------------------------------------------------
|
|
|
|
proc magic::gencell_create {gname gencell_type library} {
|
|
suspendall
|
|
if {[cellname list exists $gname] == 0} {
|
|
cellname create $gname
|
|
set snaptype [snap list]
|
|
snap internal
|
|
set savebox [box values]
|
|
pushstack $gname
|
|
magic::gencell_draw $gname $gencell_type $library
|
|
popstack
|
|
eval "box values $savebox"
|
|
snap $snaptype
|
|
}
|
|
getcell $gname
|
|
expand
|
|
resumeall
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
#-------------------------------------------------------------
|
|
|
|
proc magic::gencell_check {gname gencell_type library} {
|
|
return [eval "${library}::${gencell_type}_check $gname"]
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
#-------------------------------------------------------------
|
|
|
|
proc magic::gencell_draw {gname gencell_type library} {
|
|
|
|
# Set the parameters passed from the window text entries
|
|
magic::gencell_setparams $gname
|
|
|
|
# Call the draw routine
|
|
eval "${library}::${gencell_type}_draw $gname"
|
|
|
|
# Find the namespace of the draw procedure and set propery "library"
|
|
cellname property $gname library $library
|
|
}
|
|
|
|
#-----------------------------------------------------
|
|
# Add a standard parameter to the gencell window
|
|
#-----------------------------------------------------
|
|
|
|
proc magic::add_param {gname pname ptext default_value} {
|
|
|
|
# Check if the parameter exists. If so, override the default
|
|
# value with the current value.
|
|
|
|
set value {}
|
|
if {[cellname list exists $gname] != 0} {
|
|
set value [cellname property $gname $pname]
|
|
}
|
|
if {$value == {}} {set value $default_value}
|
|
|
|
set numrows [lindex [grid size .params.edits] 0]
|
|
label .params.edits.${pname}_lab -text $ptext
|
|
entry .params.edits.${pname}_ent -background white
|
|
grid .params.edits.${pname}_lab -row $numrows -column 0
|
|
grid .params.edits.${pname}_ent -row $numrows -column 1
|
|
.params.edits.${pname}_ent insert end $value
|
|
}
|
|
|
|
#-----------------------------------------------------
|
|
# Update the properties of a cell
|
|
#-----------------------------------------------------
|
|
|
|
proc magic::update_params {gname ptext default_value} {
|
|
}
|
|
|
|
#-------------------------------------------------------------
|
|
# gencell_params ---
|
|
# 1) If gname is NULL and gencell_type is set, then we
|
|
# create a new cell of type gencell_type.
|
|
# 2) If gname is non-NULL, then we edit the existing
|
|
# cell of type $gname.
|
|
# 3) If gname is non-NULL and gencell_type or library
|
|
# is NULL or unspecified, then we derive the gencell_type
|
|
# and library from the existing cell's property strings
|
|
#-------------------------------------------------------------
|
|
|
|
proc magic::gencell_params {gname {gencell_type {}} {library {}}} {
|
|
|
|
if {$gname == {}} {
|
|
set pidx 1
|
|
while {[cellname list exists ${gencell_type}_$pidx] != 0} {
|
|
incr pidx
|
|
}
|
|
set gname ${gencell_type}_$pidx
|
|
|
|
set ttext "New device"
|
|
set btext "Create"
|
|
set bcmd "magic::gencell_create $gname $gencell_type $library"
|
|
} else {
|
|
if {$gencell_type == {}} {
|
|
set gencell_type [cellname property ${gname} gencell]
|
|
}
|
|
if {$library == {}} {
|
|
set library [cellname property ${gname} library]
|
|
}
|
|
|
|
set ttext "Edit device"
|
|
set btext "Apply"
|
|
set bcmd "magic::gencell_change $gname $gencell_type $library"
|
|
}
|
|
|
|
catch {destroy .params}
|
|
toplevel .params
|
|
label .params.title -text "$ttext $gname"
|
|
frame .params.edits
|
|
frame .params.buttons
|
|
pack .params.title
|
|
pack .params.edits
|
|
pack .params.buttons
|
|
|
|
button .params.buttons.apply \
|
|
-text "$btext" \
|
|
-command [subst { $bcmd ; \
|
|
.params.buttons.apply configure -text Apply}]
|
|
button .params.buttons.close -text "Close" -command {destroy .params}
|
|
|
|
pack .params.buttons.apply -padx 10 -side left
|
|
pack .params.buttons.close -padx 10 -side right
|
|
|
|
# Invoke the callback procedure that creates the parameter entries
|
|
|
|
eval "${library}::${gencell_type}_params $gname"
|
|
}
|
|
|
|
#-------------------------------------------------------------
|