| John Wallace 2007-08-27, 8:35 pm |
| Thank you, marvellous answers, not bad holiday, back to work tomorrow (boo)
but at least this will enable me to get the real app one steb closer to
Working Properly (hurrah).
Aric, thanks but I'm saving grid for later.
Bruce, many thanks. I had actually tried expand and fill in some of the
dozen or more non-working variants of my example which I didn't post, but
seeing them now work is very helpful indeed, your other two points are duly
noted also, and hopefully reflected in the code below.
The improved version is shorter (which is good) and feels more elegant (also
good). As with most (all?) software, it's probably no more than 80%
finished, but it is "good enough" for now, subject to the Quality
Improvement Opportunities noted in the code+comments, so I post it in case
anyone else in the same situation on another occasion may one day find it
useful. Improvements still welcome, especially ones which might help me
better understand the "first time round" window size thing (if you want to
*see* the "oddness", you'll need to remove the doContents from newsize).
Many thanks once again,
John
# Simple example of canvases and resizes.
# Appears to mostly work, has Quality Improvement Opportunities (QIOs).
# (1) "First redraw" issue (not sure about this)
# (2) Config message redraw optimisation (simply omitted from here for
brevity)
proc main { } {
bind . <Configure> newsize
# Initial default sizes
set xpixels [expr [winfo screenwidth .] / 4]
set ypixels [expr [winfo screenheight .] / 4]
# Do canvas, *then* do contents
canvas .c -background white -width $xpixels -height $xpixels
pack .c -expand 1 -fill both
puts "x: $xpixels y: $ypixels"
doContents $xpixels $ypixels 1 ;# 1 => first time (special treatment)
# There's still a "first time round" problem, to do with the initial size of
# the canvas (set to screen/4 above) vs the initial size of the toplevel
window.
# Run prog, a wide/flat oval is drawn in a square window. Click redraw, the
square
# is unchanged, but oval becomes circular. See "puts" log below. Note that a
# doContents 0 0 0 from here *doesn't* fix the size, whereas doContents 0 0
0 on
# pressing ReDraw does fix it, as does a doContents 0 0 0 in the "newsize"
proc.
# If only I had a clue... maybe something to do with what's mapped (or not)?
# Log (with no doContents in newsize):
# x: 320 y: 256
# x: 320 y: 256 first: 1 resizes: 0
# <click redraw, without touching window>
# x: 324 y: 347 first: 0 resizes: 6
# <manual resize+redraw behaves as expected>
# x: 543 y: 347 first: 0 resizes: 11
}
######################################
proc doContents { xpixels ypixels first } {
global resizes
if { $first == 0} {
set xpixels [winfo width .]
set ypixels [winfo height .]
.c delete all
}
puts "x: $xpixels y: $ypixels first: $first resizes: $resizes"
.c create oval 50 50 [expr $xpixels - 50] [expr $ypixels - 50] -fill green
}
#######################################
proc newsize { } {
# Note that this proc is invoked for *any* Configure message, not just
resize.
# A bit of tbd logic could separate true resizes from other events.
global resizes
incr resizes
# Horribly inefficient to *always* invoke doContents here, but for
demonstration...
# Remove this doContents to see the first-time-round window-size-weirdness
doContents 0 0 0
}
# following code belongs in main, here for historical/laziness reasons
only...
# (ie I haven't (yet) tested moving it to main)
frame .f1
button .f1.drawplot -command {doContents 0 0 0} -text "ReDraw"
pack .f1.drawplot -side left
pack .f1
set resizes 0
main
|