1#!/usr/bin/wish 2 3# Utility to create scanned synthesis matrices 4# John ffitch 2000 Jun 3 5 6# The basic drawing area. Size is a guess! 7canvas .c -width 13c -height 13c 8pack .c 9 10#Creation of nodes and lines; driven my bindings later 11proc mkNode {x y} { 12 # Create new node at (x,y) 13 global nodeX nodeY edgeFirst edgeSecond allNodes 14 set new [.c creat oval [expr $x-5] [expr $y-5] \ 15 [expr $x+5] [expr $y+5] -outline black \ 16 -fill yellow -tags node] 17 set nodeX($new) $x 18 set nodeY($new) $y 19 set edgeFirst($new) {} 20 set edgeSecond($new) {} 21 lappend allNodes $new 22} 23 24proc mkEdge {first second} { 25 # Create edge between nodes 26 global nodeX nodeY edgeFirst edgeSecond connect 27 set x1 $nodeX($first) 28 set y1 $nodeY($first) 29 set x2 $nodeX($second) 30 set y2 $nodeY($second) 31 set edge [.c create line $x1 $y1 $x2 $y2 -arrow last -arrowshape {10 20 5}] 32 .c lower $edge 33 lappend edgeFirst($first) $edge 34 lappend edgeSecond($second) $edge 35 lappend connect [list $first $second] 36} 37 38########## LEFT BUTTON CREATION 39# Create node with left button 40bind .c <Button-1> {mkNode %x %y} 41 42.c bind node <Any-Enter> { 43 .c itemconfigure current -fill red 44} 45.c bind node <Any-Leave> { 46 .c itemconfigure current -fill yellow 47} 48 49######### FIRST EDGE DRAWING METHOD 50# Line drawing with 1 and 2 -- must be a better way! 51 52set secondNode "" 53set firstNode "" 54bind .c 1 { 55 global firstNode secondNode 56 set firstNode [.c find withtag current] 57 if {($firstNode != "") && ($secondNode != "")} { 58 mkEdge $firstNode $secondNode 59 set firstNode "" 60 set secondNode "" 61 } 62} 63 64bind .c 2 { 65 global firstNode 66 set curNode [.c find withtag current] 67 if {($firstNode != "") && ($curNode != "")} { 68 mkEdge $firstNode $curNode 69 set firstNode "" 70 } else { 71 set secondNode $curNode 72 } 73} 74 75####### SECOND WAY 76# Second way of drawing links using Button 2 77bind .c <Button-2> { 78 global newLine curX curY 79 set firstNode [.c find withtag current] 80 if {$firstNode != ""} { 81 set newLine [.c create line %x %y %x %y -fill blue] 82 set curX %x 83 set curY %y 84 } 85} 86 87bind .c <B2-Motion> { 88 global newLine curX curY 89 .c coords $newLine [lindex [.c coords $newLine] 0] \ 90 [lindex [.c coords $newLine] 1] %x %y 91 set curX %x 92 set curY %y 93 foreach node $allNodes { 94 set pts [.c coords $node] 95 set diffx [expr $curX-[lindex $pts 0]] 96 set diffy [expr $curY-[lindex $pts 1]] 97 if {($diffx < 10) && ($diffx > 0) && ($diffy < 10) && ($diffy > 0)} { 98 set curNode $node 99 } 100 } 101 if {($firstNode != "") && ($curNode != "") && ($firstNode != $curNode)} { 102 mkEdge $firstNode $curNode 103 set firstNode "" 104 .c delete $newLine 105 set newLine "" 106 } 107} 108 109bind .c <ButtonRelease-2> { 110 # Delete any dangling rubber line 111 if {$newLine != ""} { 112 .c delete $newLine 113 set newLine "" 114 } 115} 116 117####### REORGANISATION OF LAYOUT 118# Node mobility, with attached lines 119proc moveNode {node xDist yDist} { 120 global nodeX nodeY edgeFirst edgeSecond 121 .c move $node $xDist $yDist 122 incr nodeX($node) $xDist 123 incr nodeY($node) $yDist 124 foreach edge $edgeFirst($node) { 125 .c coords $edge $nodeX($node) $nodeY($node) \ 126 [lindex [.c coords $edge] 2] \ 127 [lindex [.c coords $edge] 3] 128 } 129 foreach edge $edgeSecond($node) { 130 .c coords $edge [lindex [.c coords $edge] 0] \ 131 [lindex [.c coords $edge] 1] \ 132 $nodeX($node) $nodeY($node) 133 } 134} 135 136.c bind node <Button-3> { 137 set curX %x 138 set curY %y 139} 140 141.c bind node <B3-Motion> { 142 moveNode [.c find withtag current] [expr %x-$curX] [expr %y-$curY] 143 set curX %x 144 set curY %y 145} 146 147######## DELETIONS OF ERRORS 148#Removal of unwanted nodes 149proc deleteNode {node} { 150 global allNodes edgeFirst edgeSecond connect 151 if {[info exists $edgeFirst($node)]} { 152 foreach edge $edgeFirst($node) { 153 .c delete $edge 154 } 155 } 156 if {[info exists $edgeSecond($node)]} { 157 foreach edge $edgeSecond($node) { 158 .c delete $edge 159 } 160 } 161 unset edgeFirst($node) 162 unset edgeSecond($node) 163 set indx [lsearch $allNodes $node] 164 set allNodes [lreplace $allNodes $indx $indx] 165 while {[set indx [lsearch -regexp $connect "$node \[0-9\]*"]] != -1} { 166 set connect [lreplace $connect $indx $indx] 167 } 168 while {[set indx [lsearch -regexp $connect "\[0-9\]* $node"]] != -1} { 169 set connect [lreplace $connect $indx $indx] 170 } 171 .c delete $node 172} 173 174bind .c r { 175 deleteNode [.c find withtag current] 176} 177 178bind .c k { 179 deleteNode [.c find withtag current] 180} 181 182# Removal of unwanted lines 183proc deleteLink {node} { 184 global edgeFirst edgeSecond connect mode 185 if {[info exists $edgeFirst($node)]} { 186 bind .c y { 187 unset edgeFirst($node) 188 while {[set indx [lsearch -regexp $connect "$node \[0-9\]*"]] != -1} { 189 set connect [lreplace $connect $indx $indx] 190 } 191 .c delete $mode 192 set mode -1 193 } 194 bind .c n { 195 set mode -1 196 .c itemconfigure mode -fill black -outline black 197 } 198 foreach edge $edgeFirst($node) { 199 .c itemconfigure edge -fill yellow -outline yellow -stipple -. 200 set mode $edge 201 tkwait variable mode 202 } 203 } 204 if {[info exists $edgeSecond($node)]} { 205 bind .c y { 206 .c delete $mode 207 unset edgeSecond($node) 208 while {[set indx [lsearch -regexp $connect "\[0-9\]* $node"]] != -1} { 209 set connect [lreplace $connect $indx $indx] 210 } 211 } 212 bind .c n { 213 set mode -1 214 .c itemconfigure mode -fill black -outline black 215 } 216 foreach edge $edgeSecond($node) { 217 .c itemconfigure edge -fill yellow -outline yellow -stipple -. 218 set mode $edge 219 tkwait variable mode 220 } 221 } 222 bind .c y {} 223 bind .c n {} 224} 225 226bind .c d { 227 set node [.c find withtag current] 228 if {$node != ""} { 229 deleteLink $node 230 } 231} 232 233focus .c 234 235###### GENERATE OUTPUT TABLE 236set connect "" 237set allNodes "" 238set outname "matrix.dat" 239 240proc makeTable {} { 241 # Construct the matrix 242 global allNodes connect outname 243 set n 0 244 set map "" 245# puts "allNodes=$allNodes" 246# puts "connections $connect" 247 foreach node $allNodes { 248 # Construct a set of link tables 249# puts "Node $n" 250 set links($n) "" 251 while {[set indx [lsearch -regexp $connect "$node \[0-9\]*"]] != -1} { 252# puts "Indx = $indx; lindex connect indx = [lindex $connect $indx]" 253 set links($n) [lappend links($n) [lindex [lindex $connect $indx] 1]] 254 set connect [lreplace $connect $indx $indx] 255 } 256# puts "Links $n $links($n)" 257# puts $connect 258 set map [lappend map $node] 259# puts "map for $n is $map" 260 set n [incr n 1] 261 } 262 set l 1 263 while {$l < $n} { 264 set l [expr $l+$l] 265 } 266 puts "*********************Table size is $l" 267 set ff [open $outname w] 268 # l is power-of-two version 269 for {set i 0} {$i < $l} {incr i 1} { 270 for {set j 0} {$j < $l} {incr j 1} { 271 if {($i<$n) || ($j<$n)} { 272 set k [lindex $map $j] 273 if {([lsearch $links($i) $k] != -1)} { 274 puts -nonewline $ff "1 " 275 } else { 276 puts -nonewline $ff "0 " 277 } 278 } else { puts -nonewline $ff "0 " } 279 } 280 puts $ff "" 281 } 282 puts "Ends" 283} 284 285button .ok -text Build -command makeTable 286button .xit -text EXIT -command exit 287set hlpShowing 0 288proc doHelp {} { 289 if {helpShowing==0} { 290 toplevel .hlp 291 wm title .hlp "Help" 292 text .hlp.t -relief raised -bd 2 -yscrollcommand ".hlp.s set" 293 scrollbar .hlp.s -command ".hlp.t yview" 294 button .hlp.k -text OK -command endHelp 295 pack .hlp.s -side right -fill y 296 pack .hlp.t -side left 297 pack .hlp.k 298 set f [open "matrix.hlp"] 299 while {![eof $f]} { 300 .hlp.t insert end [read $f 1000] 301 } 302 close $f 303 set helpShowing 1 304 } 305} 306 307proc endHelp {} { 308 destroy .hlp 309} 310 311button .help -text Help -command doHelp 312label .label -text "File Name:" 313entry .entry -width 20 -relief sunken -bd 2 -textvariable outname 314pack .xit .ok .help .label .entry -side left -padx 1m -pady 2m 315