1 ############################################################
3 # Copyright (C) 1998 William F. Schelter #
4 # For distribution under GNU public License. See COPYING. #
6 # Modified by Jaime E. Villate #
7 # Time-stamp: "2022-04-02 10:25:09 villate" #
8 ############################################################
10 proc makeFrame
{ w type
} {
11 # If the plot was produced by Xmaxima's console, it will be in a frame
12 # inserted in the console. Otherwise it will be a toplevel window
13 global writefile doExit fontSize buttonfont maxima_priv
19 if { [regexp {^
\.
(plot|versust
)} $w] } {
25 # hide the parent window and destroy it when the canvas is destroyed
26 set dismiss
"destroy $win"
27 catch { set parent
[winfo parent
$w]
28 if { "$parent" == "." } {
29 set dismiss
"destroy ."
31 if { [regexp {^
\.
(plot|versust
)} [winfo toplevel $win]] } {
32 set top
[winfo parent
$win]
33 set dismiss
"destroy $top"
37 if { "$doExit" != "" } {set dismiss
$doExit }
38 set dismiss
[concat $dismiss "; clearLocal $win "]
40 # Win is the name of the window and w its name without a final period
45 set buttonFont
$buttonfont
46 oset
$win buttonFont
$buttonfont
48 # widgets for the menu buttons and (x, y) coordinates label
49 if { $type == {df
} } {
50 set ltext
[mc
"Click on the graph to trace a curve"]
52 set ltext
[mc
"Pointer Coordinates"]
54 ttk
::label $w.position
-text $ltext -background white
-font $buttonFont
55 set mb
[frame $w.menubar
]
57 ttk
::button $mb.
close -text [mc
"Close"] -command $dismiss
58 ttk
::button $mb.config
-text [mc
"Config"] -command "doConfig$type $win"
59 ttk
::button $mb.save
-text [mc
"Save"] \
60 -command "mkPrintDialog .dial -canvas $c -buttonfont $buttonFont "
61 pack $mb.
close $mb.config
$mb.save
-side left
64 # c is the canvas where the plot will be drawn
65 tk::canvas $c -cursor arrow
-background white
\
66 -width [oget
$win width
] -height [oget
$win height
]
67 pack $c -side top
-expand 1 -fill both
68 bind $c <Motion
> "showPosition $w %x %y"
69 bind $c <Configure
> "reConfigure %W %w %h"
71 $w.position config
-background [$c cget
-background]
72 place $w.position
-in $w.c
-relx 0.03 -rely 0.99 -anchor sw
76 if { [regexp {^
\.
(plot|versust
)} [winfo toplevel $win]] } {
77 pack [ttk
::sizegrip $w.szgr
] -side bottom
-anchor se
78 bind $win <Control-w
> $dismiss
79 wm protocol
$w WM_DELETE_WINDOW
$dismiss
84 proc mkentry
{ newframe textvar
text buttonFont
} {
89 set parent
[winfo parent
$parent]
90 if { "$parent" == "" } { break }
91 if { ![catch { set type
[oget
$parent type
] } ] } {
92 global plot
[set type
]Options
93 foreach v
[set plot
[set type
]Options
] {
94 if { "[oloc $parent [lindex $v 0]]" == "$textvar" } {
95 setBalloonhelp
$parent $newframe [lindex $v 2]
104 label $newframe.lab
-text "$text:" -font $buttonFont -width 0
105 entry $newframe.e
-width 20 -textvariable $textvar -font $buttonFont
106 pack $newframe.lab1
-side left
-expand 1 -fill x
107 pack $newframe.lab
-side left
108 pack $newframe.e
-side right
-padx 3 -fill x
109 # pack $newframe.lab $newframe.e -side left -padx 3 -expand 1 -fill x
112 proc pushBind
{ win key action
} {
113 pushl
[bind $win $key] [list $win $key ]
114 bind $win $key $action
117 proc popBind
{ win key
} {
118 set binding
[popl
[list $win $key] {}]
120 bind $win $key $binding
123 # exit if not part of openmath browser
124 proc maybeExit
{ n
} {
125 if { "[info proc OpenMathOpenUrl]" != "" } {
132 proc showPosition
{ win x y
} {
135 # we catch so that in case have no functions or data..
137 $win.position config
-text \
138 "[format {(%.6g,%.6g)} [storx$win [$c canvasx $x]] [story$win [$c canvasy $y]]]"
142 proc reConfigure
{ c width height
} {
143 set win
[winfo parent
$c]
144 set w
[oget
$win width
]
145 set h
[oget
$win height
]
146 set wscale
[expr double
($width)/$w]
147 set hscale
[expr double
($height)/$h]
148 $c scale all
0 0 $wscale $hscale
149 oset
$win width
$width
150 oset
$win height
$height
151 set_xy_transforms
$win
154 proc writePostscript
{ win
} {
155 global printOption argv
156 makeLocal
$win c transform transform0 xmin ymin xmax ymax
157 set rtosx rtosx
$win ; set rtosy rtosy
$win
158 drawPointsForPrint
$c
159 if { "[$c find withtag printrectangle]" == "" } {
160 $c create rectangle
[$c canvasx
0] [$c canvasy
0] \
161 [$c canvasx
[$c cget
-width ]] [$c canvasy
[$c cget
-height ]] \
162 -tags printrectangle
-outline white
165 set bbox
[eval $c bbox
[$c find withtag printrectangle
]]
166 desetq
"x1 y1 x2 y2" $bbox
167 # set title "unknown plot"
168 # catch { set title [eval $printOption(maintitle)] }
169 # $c create text [expr {($x1 + $x2)/2}] [expr {$y1 + .04 * ($y2 - $y1)}] \
170 # -anchor center -text $title -tag title
173 #set diag [vectorlength [expr {$y1-$x1}] [expr {$y2-$x2}]]
174 # get rid of little arrows that creep onto the outside, ie let
175 # the blank rectangle cover them.
176 #set x1 [expr {$x1+.01 * $diag}]
177 #set x2 [expr {$x2-.01 * $diag}]
178 #set y1 [expr {$y1+.01 * $diag}]
179 #set y2 [expr {$y2-.01 * $diag}]
181 # Set up font replacement list
182 catch {set fontMap
([font create
-family {BitstreamVeraSansMono
} -size 10]) [list Courier
14]}
183 catch {set fontMap
([font create
{helvetica
16 normal
}]) [list Helvetica
16]}
184 set com
"$c postscript \
185 -x [expr {($x1 - 35)}] -y [expr {($y1 -25)}] \
186 -width [expr {($x2 - $x1 + 60)}] \
187 -height [expr {($y2 - $y1 + 45)}] \
189 [getPageOffsets [expr {($x2 - $x1 + 55)/(1.0*($y2 - $y1 + 45))}] ]"
192 set output
[eval $com]
193 set fi
[open $printOption(psfilename
) w
]
200 #-----------------------------------------------------------------
202 # ftpDialog -- open up a dialog to send ftpInfo(data) to a file
203 # via http and ftp. The http server can be specified.
209 #----------------------------------------------------------------
212 proc ftpDialog
{ win args
} {
213 global ftpInfo buttonFont fontSize
215 set usefilename
[assoc
-filename $args 0]
216 if { "$usefilename" != "0"} {
217 set ftpInfo
(filename) $usefilename
220 catch { destroy $fr }
221 set ftpInfo
(percent
) 0
223 frame $fr -borderwidth 2 -relief raised
224 if { [catch { set ftpInfo
(directory
) } ] } { set ftpInfo
(directory
) homework
}
225 label $fr.title
-text [mc
"Ftp Dialog Box"]
226 mkentry
$fr.host ftpInfo
(host
) [mc
"host to write file on"] $buttonFont
227 mkentry
$fr.viahost ftpInfo
(viahost
) [mc
"host to write to via"] $buttonFont
228 mkentry
$fr.username ftpInfo
(username
) [mc
"Your User ID on host"] $buttonFont
229 mkentry
$fr.password ftpInfo
(password
) [mc
"Your password on host"] $buttonFont
230 $fr.password.e config
-show *
231 mkentry
$fr.directory ftpInfo
(directory
) [mc
"remote subdirectory for output"] $buttonFont
233 if { $usefilename } {
234 mkentry
$fr.
filename ftpInfo
(filename) [mc
"filename "] $buttonFont
236 mkentry
$fr.chapter ftpInfo
(chapter
) [mc
"chapter "] $buttonFont
237 mkentry
$fr.section ftpInfo
(section
) [mc
"section"] $buttonFont
238 mkentry
$fr.problemnumber ftpInfo
(number
) [mc
"Problem number"] $buttonFont
240 scale $fr.
scale -orient horizontal
-variable ftpInfo
(percent
) -length 100
241 button $fr.doit
-text [mc
"Send it"] -command "doFtpSend $fr" -font $buttonFont
242 button $fr.cancel
-text [mc
"Cancel"] -command "destroy $fr" -font $buttonFont
243 set ftpInfo
(message) ""
244 label $fr.
message -width 30 -height 3 -textvariable ftpInfo
(message) -font $buttonFont
245 eval pack [winfo children
$fr] -side top
247 place $fr -in $win -relx .5 -rely .5 -anchor center
250 proc doFtpSend
{ fr
} {
251 global ftpInfo om_ftp
254 if { [winfo exists
$fr.
filename] } {
255 set filename $ftpInfo(filename)
256 set check
"host username directory filename"
258 set check
"host username directory chapter section number"
261 if { $ftpInfo($v) == "" } {
262 if { "$error" == "" } { set error [concat [mc
"Failed to specify"] "$v " } else {
266 if { "$error" != "" } {
267 set ftpInfo
(message) $error
270 if { [winfo exists
$fr.chapter
] } {
271 set filename "$ftpInfo(chapter).$ftpInfo(section)-$ftpInfo(number).ps"
275 set res
[submitFtp
$ftpInfo(viahost
) $ftpInfo(host
) $ftpInfo(username
) $ftpInfo(password
) $ftpInfo(directory
) $filename]
277 after 1000 "destroy $fr"
281 # set counter [ ftp $ftpInfo(host) $ftpInfo(username) $ftpInfo(password)]
282 # if { $counter < 0 } {
283 # set ftpInfo(message) [concat "Failed:" $om_ftp($counter,log)]
287 # if { [ftpDoCd $counter $ftpInfo(directory)] < 0 &&
288 # [ftpDoMkdir $counter $ftpInfo(directory)] > -10 &&
289 # [ftpDoCd $counter $ftpInfo(directory)] < 0 } {
290 # set ftpInfo(message) [concat "Failed:" $om_ftp($counter,log)]
295 # set res [ftpDoStore $counter $ftpInfo(chapter).$ftpInfo(section)-$ftpInfo(number).ps $ftpInfo(data)]
297 # set ftpInfo(message) "Failed: $om_ftp($counter,log)"
300 # set ftpInfo(message) "Wrote $ftpInfo(directory)/$ftpInfo(chapter).$ftpInfo(section)-$ftpInfo(number).ps"
301 # after 1000 destroy $fr
306 proc vectorlength
{ a b
} {
307 return [expr {sqrt
($a*$a + $b * $b)} ]
310 proc setupCanvas
{ win
} {
311 makeLocal
$win xcenter xradius ycenter yradius
313 oset
$win xmin
[expr {$xcenter - $xradius}]
314 oset
$win xmax
[expr { $xcenter + $xradius}]
315 oset
$win ymin
[expr { $ycenter - $yradius}]
316 oset
$win ymax
[expr { $ycenter + $yradius} ]
322 #-----------------------------------------------------------------
324 # compose -- A and B are transformations of the form "origin scalefac"
325 # and composing them means applying first b then a, as in a.b.x
326 # "o s" . x ==> (x-o)*s + o
327 # Results: the "origin scalefac" which corresponds to the composition.
331 #----------------------------------------------------------------
333 proc compose
{ a b
} {
334 return "[expr {-[lindex $a 1]*[lindex $b 0]*[lindex $b 1] \
335 +[lindex $a 1]*[lindex $b 0]-[lindex $a 0]*[lindex $a 1] \
336 +[lindex $a 0]}] [expr {[lindex $a 1]*[lindex $b 1]}]"
339 proc sparseListWithParams
{ form variables paramlist
} {
340 set tem
[parseConvert
$form -doall 1]
342 set params
[splitParams
$paramlist]
343 if { [catch {set res
[substParams
[lindex $tem 0] $variables $params] }\
345 set vars
[lindex $tem 1]
347 foreach { v val
} $params { lappend all
$v}
348 foreach v
$vars { if { [lsearch $all [string range
$v 1 end
]] < 0 } {
349 error [M
[mc
"The variable %s appeared in %s but was not in allowed variables: %s or in parameters: %s"] "`[string range $v 1 end]'" "$form" "{$variables}" "{$paramlist}" ]
352 error [M
[mc
"The form %s may involve variables other than %s or the parameters %s, or the latter may have invalid expressions: %s"] "$form" "{$variables}" "{$paramlist}" "$err" ]
357 proc sparseWithParams
{ form variables params
} {
358 set tem
[sparseListWithParams
$form $variables $params]
359 if { [llength $tem ] > 1 } { error [concat [mc
"only wanted one function:"] "$form"]}
364 #-----------------------------------------------------------------
366 # myVarSubst -- into FORM substitute where
367 # listVarsVals where each element of this list may mention
368 # the previous values eg "k 7 ll sin(k+8)"
370 #myVarSubst [lindex [parseConvert "k*x+l" -doall 1] 0] {x $x k 27+4 l 93+k^3}
371 # ==> {((31 * $x) + 29884.0)}
373 # Results: FORM with the substitutions done
377 #----------------------------------------------------------------
379 proc myVarSubst
{ form listVarsVals
} {
380 foreach {_u _v
} $listVarsVals {
381 if { "\$$_u" == "$_v" } {
384 set _f1
[lindex [parseConvert
$_v -doall 1] 0]
385 set $_u [expr [lindex $_f1 0]]
386 # puts "$_u = [set $_u]"
389 subst -nobackslashes -nocommands $form
393 proc splitParams
{ paramlist
} {
395 foreach v
[split $paramlist ,] {
397 if { [llength $tem] == 2 } {
398 lappend params
[lindex $tem 0] [lindex $tem 1]
404 #-----------------------------------------------------------------
406 # substParams -- substitute into FORM keeping VARIABLES as they are
407 # and the PARAMLIST (of the form k=23, l=k+7,...) into FORM
409 # Results: substituted FORM
413 #----------------------------------------------------------------
415 proc substParams
{ form variables params
} {
416 foreach v
$variables { lappend params
$v \$$v}
417 set res
[myVarSubst
$form $params]
421 #-----------------------------------------------------------------
423 # set_xy_region -- set up the bounds of the x and y coordinates
424 # that will appear on the plot and the part of the window that will
425 # be filled by the plot (fac, a number between 0 and 1).
427 #----------------------------------------------------------------
429 proc set_xy_region
{ win fac
} {
430 makeLocal
$win xcenter ycenter xradius yradius c
432 set xmin
[expr {$xcenter - $xradius}]
433 set xmax
[expr {$xcenter + $xradius}]
434 set ymin
[expr {$ycenter - $yradius}]
435 set ymax
[expr {$ycenter + $yradius}]
444 #-----------------------------------------------------------------
446 # set_xy_transforms -- set up transformations for the canvas of WINDOW
447 # so that the plot is a fraction of the window (fac).
448 # these transformations are used to convert from real values of x and y
449 # to screen coordinates in pixels and vice versa.
451 # Side Effects: transform functions rtosx$win rtosy$win storx$win story$win
454 #----------------------------------------------------------------
456 proc set_xy_transforms
{ win
} {
457 makeLocal
$win xmin ymin xmax ymax width height fac
458 if { [oget
$win type
] == {3d
} } {
459 set f1
[expr {(1 - $fac)/2.0}]
460 set x1
[expr {$f1 *$width}]
462 set f1
[expr {(1 - $fac)/3.0}]
463 set x1
[expr {2* $f1 *$width}]
465 set y1
[expr {$f1 *$height}]
466 set x2
[expr {$x1 + $fac*$width}]
467 set y2
[expr {$y1 + $fac*$height}]
469 set transform
[makeTransform
"$xmin $ymin $x1 $y2" "$xmin $ymax $x1 $y1 " \
470 "$xmax $ymin $x2 $y2"]
471 oset
$win transform
$transform
472 oset
$win transform0
$transform
474 getXtransYtrans
$transform rtosx
$win rtosy
$win
475 getXtransYtrans
[inverseTransform
$transform] storx
$win story
$win
478 proc inputParse
{ in
} {
479 if { [regexp -indices \
480 {D
\[([a-zA-Z
][0-9a-zA-Z
]*[ ]*),([a-zA-Z
][0-9a-zA-Z
]*[ ]*)\] *=} \
482 set v1
[getOneMatch
$in $i1]
483 set v2
[getOneMatch
$in $i2]
484 set s1
[string range
$in [lindex $all1 1] end
]
486 if { [regexp -indices {,[ \n]*D
\[([a-zA-Z
][0-9a-zA-Z
]*[ ]*),([a-zA-Z
][0-9a-zA-Z
]*[ ]*)\] *=} \
488 set v3
[getOneMatch
$s1 $i1]
489 set v4
[getOneMatch
$s1 $i2]
490 set end
[string first
\} $s1 ]
491 set form2
[string range
$s1 [expr {1 + [lindex $all2 1]}] [expr {$end -1}]]
492 if { "$v4" != "$v2" } {error [concat [mc
"different variables"] "$v2" [mc
"and"] "$v4"]}
494 set form1
[string range
$in [expr {1 + [lindex $all1 1]}] [expr {[lindex $all2 0] + -1 + [lindex $all1 1]}]]
495 return [list $v2 $v1 $v3 $form1 $form2]
496 # puts "v1=$v1,form1=$form1,form2=$form2"
501 proc composeTransform
{ t1 t2
} {
502 desetq
"a11 a12 a21 a22 e1 e2" $t1
503 desetq
"b11 b12 b21 b22 f1 f2" $t2
505 [expr {$a11*$b11+$a12*$b21}] \
506 [expr {$a11*$b12+$a12*$b22}] \
507 [expr {$a21*$b11+$a22*$b21}] \
508 [expr {$a22*$b22+$a21*$b12}] \
509 [expr {$a11*$f1+$a12*$f2+$e1}] \
510 [expr {$a21*$f1+$a22*$f2+$e2}] ]
516 #-----------------------------------------------------------------
518 # makeTransform -- Given three points mapped to three other points
519 # write down the affine transformation (A.X+B) which performs this.
520 # the arguments are of the form "x1 y1 u1 v1" "x2 y2 u2 v2" "x3 y3 u3 v3"
521 # where (x1,y1) --> (u1,v1) etc.
522 # Results: an affine transformation "a b c d e f" which is
523 # [ a b ] [ x1 ] + [ e ]
524 # [ c d ] [ y1 ] [ f ]
527 #----------------------------------------------------------------
529 proc makeTransform
{ P1 P2 P3
} {
530 desetq
"X1 Y1 U1 V1" $P1
531 desetq
"X2 Y2 U2 V2" $P2
532 desetq
"X3 Y3 U3 V3" $P3
533 set tem
[expr {double
((($X2-$X1)*$Y3+($X1-$X3)*$Y2+($X3-$X2)*$Y1))}]
534 set A
[expr {(($U2-$U1)*$Y3+($U1-$U3)*$Y2+($U3-$U2)*$Y1) \
536 set B
[expr {-(($U2-$U1)*$X3+($U1-$U3)*$X2+($U3-$U2)*$X1) \
538 set E
[expr {(($U1*$X2-$U2*$X1)*$Y3+($U3*$X1-$U1*$X3)*$Y2+($U2*$X3-$U3*$X2)*$Y1) \
540 set C
[expr {(($V2-$V1)*$Y3+($V1-$V3)*$Y2+($V3-$V2)*$Y1) \
542 set D
[expr {-(($V2-$V1)*$X3+($V1-$V3)*$X2+($V3-$V2)*$X1) \
544 set F
[expr {(($V1*$X2-$V2*$X1)*$Y3+($V3*$X1-$V1*$X3)*$Y2+($V2*$X3-$V3*$X2)*$Y1) \
548 if { $B == 0 && $C == 0 } {
552 return [list $A $B $C $D $E $F]
557 #-----------------------------------------------------------------
559 # getXtransYtrans -- If the x coordinate transforms independently
560 # of the y and vice versa, give expressions suitable for building a
566 #----------------------------------------------------------------
568 proc getXtransYtrans
{ transform p1 p2
} {
569 desetq
"a b c d e f" $transform
570 if { $b == 0 && $c == 0 } {
571 proc $p1 { x
} "return \[expr {$a*\$x+$e}\]"
572 proc $p2 { y
} "return \[expr {$d*\$y+$f} \]"
580 #-----------------------------------------------------------------
582 # inverseTransform -- Find the inverse of an affine transformation.
588 #----------------------------------------------------------------
590 proc inverseTransform
{ transform
} {
591 desetq
"a b c d e f" $transform
592 set det
[expr {double
($a*$d - $b*$c)}]
593 return [list [expr {$d/$det}] [expr {- $b / $det }] [expr {- $c / $det}] [expr {$a / $det}] [expr {($b*$f-$d*$e)/ $det }] [expr {-($a*$f-$c*$e)/ $det}]]
599 #-----------------------------------------------------------------
601 # getTicks -- given an interval (a,b) subdivide it and
602 # calculate where to put the ticks and what to print there.
603 # we want DESIRED number of ticks, but we also want the ticks
604 # to be at points in the real coords of the form .2*10^i or .5*10^j
609 #----------------------------------------------------------------
612 proc getTicks
{ a b n
} {
613 set len
[expr {(($b - $a))}]
614 if { $len < [expr {pow
(10,-40)}] } { return ""}
616 foreach v
{ .1 .2 .5 } {
617 # want $len/(.1*10^i) == $n
618 set val
($v) [expr {ceil
(log10
($len/(double
($n)*$v)))}]
619 set use
[expr {$v*pow
(10,$val($v))}]
620 set fac
[expr {1/$use}]
621 set aa
[expr {$a * $fac}]
622 set bb
[expr {$b * $fac}]
623 set j
[expr {round
(ceil
($aa)) }]
624 set upto
[expr {floor
($bb) }]
625 if { $upto-$j > 14} {
631 while { $j <= $upto } {
632 set tt
[expr {$j / $fac}]
633 if { $j%$step == 0 } {
634 append ticks
" { $tt $tt }"
640 set answer
($v) $ticks
641 set this
[llength $ticks]
642 if { $this > $best } {
646 #puts "for $v [llength $ticks] ticks"
648 #puts "using $at [llength $answer($at)]"
653 proc axisTicks
{ win c
} {
655 if { ![catch {oget
$win noaxisticks
}] } { return }
656 set swid
[$c cget
-width]
657 set shei
[$c cget
-height]
658 set x1
[storx
$win [$c canvasx
0]]
659 set y1
[story
$win [$c canvasy
0]]
660 set x2
[storx
$win [$c canvasx
$swid]]
661 set y2
[story
$win [$c canvasy
$shei]]
662 #puts "x1=$x1,y1=$y1,y2=$y2,x2=$x2"
663 if { $y1 > 0 && $y2 < 0 } {
664 set ticks
[getTicks
$x1 $x2 [expr {$swid/50}] ]
666 set eps
[expr {.005 * abs
($y1 - $y2)}]
667 set neps
[expr {-.005 * abs
($y1 - $y2)}]
671 set text [lindex $v 1]
672 if { $donext } {set text [lindex $v 0] ; set donext
0 }
673 if { [lindex $v 0] == 0 } { set text "" ; set donext
1 }
674 #puts " drawTick $c $x 0 0 $neps 0 $eps $text axisTicks"
675 drawTick
$c $x 0 0 $neps 0 $eps $text axisTicks
678 if { 0 < $x2 && 0 > $x1 } {
679 set ticks
[getTicks
$y2 $y1 [expr {$shei/50}]]
680 set eps
[expr {.005 * ($x2 - $x1)}]
681 set neps
[expr {-.005 * ($x2 - $x1)}]
685 set text [lindex $v 1]
686 if { $donext } {set text [lindex $v 0] ; set donext
0}
687 if { [lindex $v 0] == 0 } { set text "" ; set donext
1}
689 drawTick
$c 0 $y $neps 0 $eps 0 $text axisTicks
697 #-----------------------------------------------------------------
699 # marginTicks -- draw ticks around the border of window
700 # x1,y1 top left x2,y2 bottom right.
706 #----------------------------------------------------------------
708 proc marginTicks
{ c x1 y1 x2 y2 tag
} {
710 set win
[winfo parent
$c]
712 if { ![catch {oget
$win noaxisticks
}] } { return }
713 $c delete marginTicks
714 set ticks
[getTicks
$x1 $x2 $printOption(xticks
)]
716 set eps
[expr {.008 * ($y1 - $y2)}]
717 set neps
[expr {-.008 * ($y1 - $y2)}]
720 set text [lindex $v 1]
721 drawTick
$c $x $y1 0 0 0 $eps $text $tag
722 drawTick
$c $x $y2 0 0 0 $neps {} $tag
726 set ticks
[getTicks
$y1 $y2 $printOption(yticks
)]
727 set eps
[expr {.005 * ($x2 - $x1)}]
728 set neps
[expr {-.005 * ($x2 - $x1)}]
732 set text [lindex $v 1]
733 drawTick
$c $x1 $y 0 0 $neps 0 $text $tag
734 drawTick
$c $x2 $y 0 0 $eps 0 {} $tag
738 proc drawTick
{c x y dx dy ex ey n tags
} {
739 global axisGray fontCourier8
740 set win
[winfo parent
$c]
741 set rtosx rtosx
$win ; set rtosy rtosy
$win
742 set it
[$c create line
[$rtosx [expr {$x +$dx}]] [$rtosy [expr {$y +$dy}]] [$rtosx [expr {$x +$ex}]] [$rtosy [expr {$y +$ey}]] -fill $axisGray -tags $tags]
746 if { $ey > 0 } { set anch s
747 } elseif
{ $ex > 0 } {set anch w
748 } elseif
{ $ex < 0 } {set anch e
749 } elseif
{ $ey < 0 } {set anch n
}
751 $c create
text [$rtosx [expr {$x +1.5*$ex}]] [$rtosy [expr {$y +1.5*$ey}]] \
752 -text [format "%.8g" $n] -font $fontCourier8 -tags $tags \
757 proc doConfig
{ win
} {
758 makeLocal
$win c buttonFont
759 $c delete configoptions
764 frame $w -borderwidth 2 -relief raised
766 label $w.msg
-wraplength 600 -justify left
-text [mc
"Plot Setup"] -font $buttonFont
768 pack $w.msg
-side top
773 pack $wb1 $wb2 -side left
-fill x
-pady 2m
774 set item
[$canv create window
[$canv canvasx
10] [$canv canvasy
10] -window $w -anchor nw
-tags configoptions
]
775 button $wb1.dismiss
-command "$canv delete $item; destroy $w " -text "ok" -font $buttonFont
776 # button $wb1.printoptions -text [mc "Print Options"] -command "mkPrintDialog .dial -canvas $c -buttonfont $buttonFont " -font $buttonFont
778 pack $wb1.dismiss
-side top
781 # mkentry { newframe textvar text }
783 # turn off the horrible show_balloons by default.
787 proc balloonhelp
{ win subwin msg
} {
790 if { $show_balloons == 0 } {return}
791 linkLocal
[oget
$win c
] helpPending
792 if { [info exists helpPending
] } {after cancel
$helpPending}
793 set helpPending
[after 1000 [list balloonhelp1
$win $subwin $msg]]
796 proc balloonhelp1
{ win subwin msg
} {
797 if { ![winfo exists
$win] } { return }
798 makeLocal
$win c buttonFont
799 set x0
[winfo rootx
$win]
800 set y0
[winfo rooty
$win]
803 set atx
[expr {[winfo rootx
$subwin] + [winfo width
$subwin] - $x0} ]
804 set aty
[expr {[winfo rooty
$subwin] + [winfo height
$subwin] - $y0} ]
806 set wid
[$c cget
-width]
807 set wid2
[expr {round
($wid /2.0)}]
808 set wid10
[expr {round
($wid /10.0)}]
810 if { $aty <=1 } { set aty
30 }
813 set atx
[$c canvasx
$atx]
814 set aty
[$c canvasy
$aty]
817 $c create
text $atx $aty -anchor nw
-text $msg -font $buttonFont -width $wid2 -fill white
-fill black
-tags "balloon btext"
818 desetq
"x1 y1 x2 y2" [$c bbox btext
]
820 set x1
[expr {$x1 - .3*($x2-$x1)}]
821 set x2
[expr {$x2 + .3*($x2-$x1)}]
823 set y1
[expr {$y1 - .3*($y2-$y1)}]
824 set y2
[expr {$y2 + .3*($y2-$y1)}]
826 eval $c create polygon
$x1 $y1 $x2 $y1 $x2 $y2 $x1 $y2 -fill beige
-tags balloon
-smooth 1
831 proc setBalloonhelp
{ win subwin msg
} {
833 bind $subwin <Enter
> "balloonhelp $win $subwin [list $msg]"
834 bind $subwin <Leave
> "deleteBalloon $c"
837 proc deleteBalloon
{ c
} {
838 linkLocal
$c helpPending
839 if { [info exists helpPending
] } {
840 after cancel
$helpPending
848 #-----------------------------------------------------------------
850 # minMax -- Compute the max and min of the arguments, which may
851 # be vectors or numbers
853 # Results: list of MIN and MAX
857 #----------------------------------------------------------------
859 proc minMax
{ args
} {
860 set max
[lindex [lindex $args 0] 0] ; set min
$max ;
863 if { $v > $max } {set max
$v }
864 if { $v < $min} {set min
$v }
867 return [list $min $max]
870 proc matrixMinMax
{ list } {
871 # compute the min max of the list
876 foreach v
[ldelete nam
$row] {
877 if { $v > $max } {catch { set max
[expr {$v + 0}] }}
878 if { $v < $min} {catch { set min
[expr {$v + 0}] }}
885 proc omPlotAny
{ data args
} {
886 # puts "data=<[lindex $data 0]>"
887 set command
[list [lindex [lindex $data 0] 0] -data [lindex $data 0] ]
888 if { "[lindex $command 0]" == "plot2d" } {
889 lappend command
-xfun {}
891 foreach v
$args { lappend command
$v }
893 #eval [lindex [lindex $data 0] 0] -xfun [list {}] -data [list [lindex $data 0]] $args
896 proc resizeSubPlotWindows
{ win wid height
} {
897 set at
[$win yview
"@0,0"]
898 foreach w
[winfo children
$win] {
899 if { [string match plot
* [lindex [split $w .
] end
]] } {
900 resizePlotWindow
$w [winfo width
$w] $height
903 if { "$at" != "" } { $win yview
$at}
906 proc resizePlotWindow
{ w width height
} {
907 if { [winfo width
$w.c
] <= 1 } {
910 if { ![catch { set tem
[oget
$w lastResize
] } ] && [expr {[clock seconds
] - $tem }] < 2 } { return
912 oset
$w lastResize
[clock seconds
]
914 #puts "resizePlotWindow $w $width $height"
917 set par
[winfo parent
$w]
920 set wid
[winfo width
$par]
921 set hei
[winfo height
$par]
923 if { "[winfo class $par]" == "Text" } {
926 set wid1
$wid ; set hei1
$hei
928 #set wid1 [getPercentDim [oget $w widthDesired] width $par]
929 catch {set wid1
[getPercentDim
[oget
$w widthDesired
] width
$par] }
930 catch {set hei1
[getPercentDim
[oget
$w heightDesired
] height
$par] }
931 set wid
[expr {($wid1 > $wid - 30 ?
$wid - 30 : $wid1 )}]
932 set hei
[expr {($hei1 > $hei - 30 ?
$hei - 30 : $hei1 )}]
938 # if { $width > $wid -20 || $wid > $width -20 }
939 if { (abs
($width-$wid) > $dif || abs
($height-$hei) > $dif)
940 && [winfo width
$w.c
] > 1 } {
941 set eps
[expr {2 * [$w.c cget
-insertborderwidth] + [$w.c cget
-borderwidth] }]
944 set extrawidth
[expr {([winfo width
$w] - [winfo width
$w.c
]) +$epsx}]
945 set extraheight
[expr {([winfo height
$w] - [winfo height
$w.c
]) +$epsy}]
946 set nwidth
[expr {$wid - ($extrawidth > 0 ?
$extrawidth : 0)}]
947 set nheight
[expr {$hei - ($extraheight > 0 ?
$extraheight : 0)}]
949 #puts "$w.c config -width $nwidth -height $nheight, extraheight=$extraheight,epsy=$epsy"
950 $w.c config
-width $nwidth -height $nheight
956 proc bboxToRadius
{ win
} {
958 if { "$bbox" != "" } {
959 linkLocal
$win xradius yradius xcenter ycenter
961 foreach v
{ x y z
} {
962 set min
[lindex $bbox $i]
963 set max
[lindex $bbox [expr {$i+2}]]
964 if { "$min" != "" } {
965 if { $min >= $max } {error "bad bbox $bbox since $min >= $max"}
966 set ${v
}radius
[expr { ($max - $min) /2.0}]
967 set ${v
}center
[expr { ($max + $min) /2.0}]
973 proc updateParameters
{ win var value
} {
974 linkLocal
$win parameters
975 # puts "$win $var $value"
979 foreach {v val
} [splitParams
$parameters] {
980 if { "$v" == "$var" } {
983 append ans
$comma $v=$val
986 # puts "parameters=$ans"
990 proc addSliders
{ win
} {
991 linkLocal
$win sliders c width parameters
993 if { "$sliders" == "" } { return }
994 catch { destroy $c.sliders
}
997 frame $c.sliders
-relief raised
-highlightthickness 2 -highlightbackground $trough
998 foreach v
[split $sliders ,] {
999 if { [regexp {([a-zA-Z0-9
]+)[ ]*=?
(([---0-9.
]+):([---0-9.
]+))?
} $v junk var junk x0 x1
] } {
1001 if { "$x0" == "" } { set x0
-5 ; set x1
5}
1003 set fr
$c.sliders.fr
$i
1004 frame $fr -background $bg
1005 label $fr.lab
-text $var: -background $bg
1006 label $fr.labvalue
-textvariable [oloc
$win slidevalue
$i] -background $bg -relief sunken
-justify left
1007 scale $fr.
scale -command "sliderUpdate $win $var" \
1008 -from "$x0" -to $x1 -orient horizontal
\
1009 -resolution [expr ($x1 - $x0) < 1 ?
($x1-$x0)/100.0 : .01] \
1010 -length [expr {$width/2}] -showvalue 0 -variable [oloc
$win slidevalue
$i] -background $bg -troughcolor "#22ccff" -highlightthickness 0
1011 pack $fr.lab
-side left
-expand 1 -fill x
1012 pack $fr.labvalue
$fr.
scale -side left
1013 pack $fr -side top
-expand 1 -fill x
1015 set val
[assoc
$var [splitParams
$parameters] no
]
1016 if { "$val" == "no" } {
1017 set val
[expr ($x1 + $x0)/2.0]
1018 if { "$parameters" != "" } { append parameters
, }
1019 append parameters
$var=$val
1025 place $c.sliders
-in $c -x 4 -rely 1.0 -y -4 -anchor sw
1030 proc sliderUpdate
{ win var val
} {
1031 linkLocal
$win sliderCommand parameters
1032 set params
$parameters
1033 updateParameters
$win $var $val
1034 if { "$params" != "$parameters" &&
1035 [info exists sliderCommand
] } {
1037 $sliderCommand $win $var $val
1044 ## endsource plotconf.tcl