# This module has some routines that deal with resizing things. global bm set bm 2 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # Get size info for a window or widget. proc GetWinfo w { global V me Winw WinW Winh WinH CC RR WW HH if {$V>1} {set id "$me/GetWinfo"} set CC [$w cget -width] set RR [$w cget -height] set WW [set Winw($w) [winfo width $w]] set HH [set Winh($w) [winfo height $w]] if {$V>2} {puts "\n$id: $w is $CC x $RR chars ($WW x $HH pixels)."} set WinW($w) $WW set WinH($w) $HH if {$V>2} {puts "$id: $w is now WinW=$WinW($w) pixels wide x WinH=$WinH($w) pixels high."} } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # At present, ResizeText is triggered when the top-level text widget, .d.t # gets resized. What we have to do is hunt down any tables within the page, # and resize each of them to fit into the new width. For each of them, we in # turn need to resize any contained cells, some of which may contain tables. proc ResizeText {w} { global B V me Winw WinW Winh WinH Tn2b Tf2c Tn2f N opt global TW TH Tw Th CW CH Cw Ch bm CC RR WW HH set id "$me/ResizeText" update idletasks if ![winfo exists $w] { Msg "ResizeText: $w doesn't exist!" return } GetWinfo $w if {$WW <= 1 || $HH <= 1} { if {$V>1} {puts "$id: Resize $w to ${WW}x${HH} pixels ignored."} return } if {$V>2} {puts "$id: WinW($w)=$WinW($w) WinH($w)=$WinH($w)"} switch $opt(TABLE) { 1 { if {$V>2} {puts "$id: tk $N(TABLE) ..."} if [info exists Tf2c($w)] { if {[set tbls $Tf2c($w)] < 1} { if {$V>1} {puts "$id: $w contains no tables."} return } if {$V>1} {puts "$id: $w contains tables {$tbls}"} foreach tn $tbls { set left {$WW-4*$Tn2b($tn)-2*$B} set tw [expr $left] if {$V>2} {puts "$id: Resize table $tn to width $tw = $left."} # if {[set bd [lindex [$w config -bd] end]] > 0} { # if {$V>2} {puts "$id: $w has $bd-pixel border."} # if {$bd > 0} { # set tw [expr {$tw - (2 * $bd)}] # if {$V>2} {puts "$id: $w width decreased to $tw."} # } # } if [info exists Tn2f($tn)] { set tt $Tn2f($tn) if {$V>2} {puts "$id: Table $tn is \"$tt\""} if [winfo exists $tt] { if {$V>2} {puts "$id: Table $tn $tt resize to -width $tw ..."} ResizeTbl $tn $tw $tt config -width $tw if {$V>2} {puts "$id: Table $tn=$tt resized to -width $tw."} } else { if {$V>1} {puts "$id: ### Table $tn=$Tn2f($tn) does not exist ###"} } } else { if {$V>1} {puts "$id: ### Table $tn Tn2f($tn) not defined ###"} } } } else { puts "$id: $w contains no tables." } } 2 { if {$V>1} {puts "$id: tkTable $N(TABLE) ..."} if {!$N(tkTable)} {tkTableLib} Msg "$id: Resize not implemented yet for tkTable." } default { if {$V>1} {puts "$id: Ignored for opt(TABLE)=$opt(TABLE)."} } } if {$V>1} {puts "$id: Done\n"} } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # This routine runs around in a text widget measuring things, and leaves # behind a set of hints about how the text would like to be sized. We get a # widget name, which should have values in PicMinW, TxtMinW and TxtMaxW. proc MeasureTxt {tn txt} { global B V me PicMinw PicMinW PicMaxw PicMaxW curT Tf2c Tcols Trows Tn2b Tn2f \ TxtFont TxtFnt0 TxtLen TxtMinw TxtMinW TxtMaxw TxtMaxW TxtMin WinW WinH global TW TH Tw Th CW CH Cw Ch bm set id "$me/MeasureTxt" if {$V>1} {puts "$id: $txt <==========================="} if ![info exists PicMinw($txt)] {set PicMinw($txt) 0} if ![info exists PicMaxw($txt)] {set PicMaxw($txt) 0} if ![info exists PicMinW($txt)] {set PicMinW($txt) 0} if ![info exists PicMaxW($txt)] {set PicMaxW($txt) 0} if ![info exists TxtMinw($txt)] {set TxtMinw($txt) 0} if ![info exists TxtMaxw($txt)] {set TxtMaxw($txt) 0} if ![info exists TxtMinW($txt)] {set TxtMinW($txt) 0} if ![info exists TxtMaxW($curT)] {set TxtMaxW($curT) 0} if [info exists PicMinW($txt)] { if {$V>2} {puts "$id: $txt needs $PicMinW($txt) pixels for an image."} } else { if {$V>2} {puts "$id: $txt contains no images."} set PicMinW($txt) 0 } set bd [lindex [$txt config -bd] end] if {$V>2} {puts "$id: $txt has TxtLen=$TxtLen($txt) chars and PicMinW=$PicMinW($txt) bd=$bd."} set TxtFont($txt) [lindex [$txt config -font] end] set TxtFnt0($txt) [font measure $TxtFont($txt) 0] if {$V>1} {puts "$id: Font TxtFont=\"$TxtFont($txt)\" width TxtFnt0=$TxtFnt0($txt) pixels."} set TxtMinw($txt) [Max $TxtFnt0($txt) $PicMinW($txt)] set TxtMinW($txt) [expr {$TxtMinw($txt) + (2 * $bd)}] # set TxtMaxw($txt) [expr {($TxtLen($txt) * $TxtFnt0($txt)) + $PicMaxW($txt)}] set TxtMaxW($txt) [expr {$TxtMaxw($txt) + (2 * $bd)}] if {$V>1} {puts "$id: $txt TxtMinw=$TxtMinw($txt) TxtMaxw=$TxtMaxw($txt) without border."} if {$V>1} {puts "$id: $txt TxtMinW=$TxtMinW($txt) TxtMaxW=$TxtMaxW($txt) with border <-----------------."} } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # This routine runs around in a table measureing things, and leaves behind a # set of hints about how the table would like to be sized. We get a table # number and a suggested total width. proc MeasureTbl {tn} { global B V me curT Tf2c Tcols Trows Tn2b Tn2f TxtFont TxtFnt0 global PicMinw PicMinW TxtLen TxtMinw TxtMaxw TxtMinW TxtMaxW TxtMin WinW WinH global ColMinw ColMaxw ColMinW ColMaxW global TW TH Tw Th CW CH Cw Ch bm set id "$me/MeasureTbl" if {$V>2} {puts "$id: Measuring table $tn ======================="} if {$V>2} {puts "$id: $curT contains TxtLen($curT)=$TxtLen($curT) chars."} set cols $Tcols($tn) set rows $Trows($tn) if {$V>2} {puts "$id: Table $tn has $cols cols $rows rows."} if {$cols < 1} {set cols 1} if {$rows < 1} {set rows 1} for {set c 1} {$c <= $cols} {incr c} { set ColMinw($c) 0; set ColMaxw($c) 0 set ColMinW($c) 0; set ColMaxW($c) 0 } if [info exists Tn2f($tn)] { if [winfo exists [set capt $Tn2f($tn).caption]] { if {$V>1} {puts "$id: Table $tn has a caption $capt"} grid config $capt -columnspan $cols if {$V>1} {puts "$id: Table $tn caption $capt now spans $cols columns."} } for {set r 1} {$r <= $rows} {incr r} { if {$V>1} {puts "$id: Measure row $r ..."} for {set c 1} {$c <= $cols} {incr c} { if {$V>2} {puts "$id: Measure row $r col $c."} set txt $Tn2f($tn).r${r}c${c}.t if ![winfo exists $txt] { if {$V>1} {puts "$id: $txt does not exist."} continue } set bd [lindex [$txt config -bd] end] set b2 [expr {2 * $bd}] if {$V>2} {puts "$id: Measure row $r col $c bd=$bd b2=$b2."} if ![info exists TxtLen($txt)] {set TxtLen($txt) 0} if {$V>2} {puts "$id: $txt now contains TxtLen($txt)=$TxtLen($txt) chars."} if ![info exists TxtMin($txt)] {set TxtMin($txt) 0} if ![info exists TxtMinw($txt)] {set TxtMinw($txt) 0} if ![info exists TxtMaxw($txt)] {set TxtMaxw($txt) 0} if ![info exists TxtMinW($txt)] {set TxtMinW($txt) [expr {$TxtMinw($txt)+$b2}]} if ![info exists TxtMaxW($txt)] {set TxtMaxW($txt) [expr {$TxtMaxw($txt)+$b2}]} if {$V>2} {puts "$id: Cell $txt has TxtLen=$TxtLen($txt) TxtMin=$TxtMin($txt)"} if {$V>2} {puts "$id: Cell $txt has TxtMinw=$TxtMinw($txt) TxtMaxw=$TxtMaxw($txt)"} if {$V>2} {puts "$id: Cell $txt has TxtMinW=$TxtMinW($txt) TxtMaxW=$TxtMaxW($txt)"} if [winfo exists $txt] { if {$V>2} {puts "$id: Row $r Col $c has ColMinw=$ColMinw($c) ColMaxw=$ColMaxw($c)"} if {$V>2} {puts "$id: Row $r Col $c has ColMinW=$ColMinW($c) ColMaxW=$ColMaxW($c)"} MeasureTxt $tn $txt if {$V>2} {puts "$id: Row $r Col $c has ColMinw=$ColMinw($c) TxtMinw=$TxtMinw($txt)"} if {$V>2} {puts "$id: Row $r Col $c has ColMaxw=$ColMaxw($c) TxtMaxw=$TxtMaxw($txt)"} if {$V>2} {puts "$id: Row $r Col $c has ColMinW=$ColMinW($c) TxtMinW=$TxtMinW($txt)"} if {$V>2} {puts "$id: Row $r Col $c has ColMaxW=$ColMaxW($c) TxtMaxW=$TxtMaxW($txt)"} if {$ColMinw($c) < $TxtMinw($txt)} {set ColMinw($c) $TxtMinw($txt)} if {$ColMaxw($c) < $TxtMaxw($txt)} {set ColMaxw($c) $TxtMaxw($txt)} if {$ColMinW($c) < $TxtMinW($txt)} {set ColMinW($c) $TxtMinW($txt)} if {$ColMaxW($c) < $TxtMaxW($txt)} {set ColMaxW($c) $TxtMaxW($txt)} if {$V>2} {puts "$id: Row $r Col $c has ColMinw=$ColMinw($c) ColMaxw=$ColMaxw($c)"} if {$V>2} {puts "$id: Row $r Col $c has ColMinW=$ColMinW($c) ColMaxW=$ColMaxW($c)"} } else { if {$V>1} {puts "$id: $txt does not exist."} } } } } else { if {$V>1} {puts "$id: Tn2f($tn) not defined."} } } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # # Resize a table tn to width Tw($tn) pixels. We apportion the width among the # # columns of the table, and tell each of the column widgets to resize # # themselves to their fair share. At present, our apportioning scheme is # # rather simple minded. # # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # proc ResizeTbl {tn tw} { global B V me ColMinW ColMaxW Tf2c Tcols Trows Tn2b Tn2f \ TxtFont TxtFnt0 TxtLen TxtMin TxtMinW TxtMaxW WinW WinH global TW TH Tw Th CW CH Cw Ch bm set id "$me/ResizeTbl" set tt $Tn2f($tn) set bd [lindex [$tt config -bd] end] if {$V>2} {puts "$id: Table $tn $tt resize to -width $tw -bd $bd"} set TW($tn) $tw set Tw($tn) [expr {$tw-(2*$bd)}] if {$V>1} {puts "$id: Table $tn $tt resize to TW=$TW($tn), Tw=$Tw($tn) with $bd-pixel border."} MeasureTbl $tn if {$V>1} {puts "$id: Table $tn $tt resize to TW=$TW($tn), Tw=$Tw($tn) with $bd-pixel border."} if {$V>1} {puts "$id: Resizing table $tn to tw=$tw TW=$TW($tn) Tw=$Tw($tn) pixels wide."} if [info exists Tcols($tn)] {set cols $Tcols($tn)} else {set cols 1} if [info exists Trows($tn)] {set rows $Trows($tn)} else {set rows 1} if [info exists Tn2b($tn) ] {set brdr $Tn2b($tn) } else {set brdr 0} if {$V>1} {puts "$id: Table $tn has cols=$cols rows=$rows brdr=$brdr."} if {$cols < 1} {set cols 1} if {$rows < 1} {set rows 1} if {$brdr < 0} {set brdr 1} if {$V>2} {puts "$id: Border width $Tn2b($tn) for table $tn."} if {$V>1} {puts "$id: Table $tn has $cols cols $rows rows $brdr border."} if ![info exists Tn2f($tn)] { if {$V>1} {Msg "$id: ### Tn2f($tn) not defined ###"} return } if {$brdr>0 && $cols>0} { incr Tw($tn) [expr -($cols)*$brdr] if {$V>2} {puts "$id: Total width decremented to Tw($tn)=$Tw($tn) for $cols cols $brdr border."} } set capt $Tn2f($tn).caption if [winfo exists $capt] { if {$V>1} {puts "$id: Table $tn has a caption $capt"} grid config $capt -columnspan $cols if {$V>1} {puts "$id: Table $tn caption $capt now spans $cols columns."} } set wtotal 0; # Width pixels allocated so far. set paddable 0; # Number of columns that can be widened. for {set c 1} {$c <= $cols} {incr c} { set min($c) $ColMinW($c); # Min width of this column, without borders. set wid($c) $ColMinW($c); # Width allocated so far. set max($c) $ColMaxW($c); # Max width of this column, without borders. incr wtotal $wid($c) if {$wid($c) < $max($c)} {incr paddable} if {$V>1} {puts "$id: Col $c min=$min($c) wid=$wid($c) max=$max($c) wtotal=$wtotal paddable=$paddable."} } set slop [expr $tw-$wtotal] if {$V>1} {puts "$id: Table $tn $tt wtotal=$wtotal paddable=$paddable."} while {$wtotal < $tw && $paddable > 0} { if {$V>1} {puts "$id: wtotal=$wtotal paddable=$paddable slop=$slop extra pixels to allocate."} set ppc [expr {($tw - $wtotal) / $paddable}] if {$V>1} {puts "$id: Allocated only $wtotal of $tw pixels, adding $ppc to each of $paddable columns."} set paddable 0 for {set c 1} {$c <= $cols} {incr c} { set n [Min [expr {$max($c) - $wid($c)}] $ppc] if {$n > 0} { incr paddable if {$V>1} {puts "$id: Col $c min=$min($c) wid=$wid($c) max=$max($c) paddable=$paddable."} incr wid($c) $n incr wtotal $n incr slop -$n if {$V>1} {puts "$id: Col $c min=$min($c) wid=$wid($c) max=$max($c) slop=$slop wtotal=$wtotal."} } } } # for {set r 1} {$r <= $rows} {incr r} { # for {set c 1} {$c <= $cols} {incr c} { # if {$V>1} {puts "$id: row $r col $c."} # set cell $Tn2f($tn).r${r}c${c}.t # if [info exists TxtMinW($cell)] {set min($c) [Max $TxtMinW($cell) $min($c)]} # if [info exists TxtMaxW($cell)] {set max($c) [Max $TxtMaxW($cell) $max($c)]} # set bd [lindex [$cell config -bd] end] # set b2 [expr {$bm * $bd}] # if {$V>1} {puts "$id: row $r col $c min=$min($c) wid=$wid($c) max=$max($c) b2=$b2."} # } # } for {set r 1} {$r <= $rows} {incr r} { for {set c 1} {$c <= $cols} {incr c} { if {$V>1} {puts "$id: Resize row $r col $c to $wid($c) pixels."} set cell $Tn2f($tn).r${r}c${c}.t if ![winfo exists $cell] {Msg "$id: Cell $cell does not exist."; continue} if {$V>1} {puts "$id: Cell $cell resize to $wid($c) pixels."} if {$V>2} {puts "$id: Cell $cell has TxtLen=$TxtLen($cell) TxtMin=$TxtMin($cell)"} set cp [expr {$wid($c)-$bm*$Tn2b($tn)}] if {$V>1} {puts "$id: Resize width is $cp = {$wid($c)-$bm*$Tn2b($tn)}"} if [winfo exists $cell] { if {$V>1} {puts "$id: cell=\"$cell\" exists."} if {$V>1} {puts "$id: font is \"$TxtFont($cell)\" char width $TxtFnt0($cell)"} set chw [expr {$cp/$TxtFnt0($cell)+1}] if {$V>1} {puts "$id: char count is $chw = {$cp/$TxtFnt0($cell)}"} $cell config -width $chw if {$V>1} {puts "$id: cell=\"$cell\" reconfigured to -width $chw."} } else { if {$V>1} {puts "$id: $cell does not exist."} } after [expr {$V * 100 * ($r + ($c * $cols))}] "ResizeY $cell" } } } # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # global resizebyincr set resizebyincr 0; # Resize text cells by incrementing their size. # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # proc ResizeY {cell} { global V me resizebyincr set id "$me/ResizeY" if ![winfo exists $cell] {Msg "$id: ### $cell disappeared!!! ###"; return} $cell config -height 1 if {$resizebyincr > 0} { if {$V>1} {puts "$id: $cell by increments."} update set cellhlim 100 set cellhght 1 if ![winfo exists $cell] {Msg "$id: ### $cell disappeared!! ###"; return} $cell config -height $cellhght for {set n 0} {$n < $cellhlim} {incr n} { if ![winfo exists $cell] {Msg "$id: ### $cell gone!!! ###"; return} set e0 [$cell bbox end] set e1 [$cell bbox end-1c] set e2 [$cell bbox end-2c] if {$V>1} {puts "$id: cellhght={$cellhght} e0={$e0} e1={$e1} e2={$e2}"} if {($e2 != {}) || ($e1 != {}) || ($e0 != {})} { if {$V>1 && $e0 != {}} {puts "$id: e0={$e0} ends expansion."} if {$V>1 && $e1 != {}} {puts "$id: e1={$e1} ends expansion."} if {$V>1 && $e2 != {}} {puts "$id: e2={$e2} ends expansion."} break } incr cellhght if ![winfo exists $cell] {Msg "$id: ### $cell gone!! ###"; return} $cell config -height $cellhght if {$V>1} {puts "$id: $cell config -height $cellhght"} update } } else { if {$V>1} {puts "$id: $cell via yview."} update if ![winfo exists $cell] {Msg "$id: ### $cell gone!!! ###"; return} set yv [$cell yview] set ch [lindex [$cell config -height] end] set top [lindex $yv 0] set bot [lindex $yv 1] if {$V>1} {puts "$id: $cell yview is now {$yv} top=$top bot=$bot height=$ch."} # if {$top == 0} { # if {$V>1} {puts "$id: Ignore invisible $cell has top=$top."} # return # } set n 0 set newh 1 while {$bot < 1.0} { if ![winfo exists $cell] {Msg "$id: ### $cell gone!! ###"; return} if {$V>1} {puts "$id: $cell adjust height because bot=$bot (expand)"} if {[incr n] >= 1000} { if {$V>1} {puts "$id: Abandon $cell with n=$n newh=$newh."} return } set hght [lindex [$cell config -height] end] if {$bot < 0.01} {set bot 0.90}; # Kludge for image bug if {$V>1} {puts "$id: $cell hght=$hght bot=$bot."} set newh [expr {int(($hght / $bot) + 0.95)}] if {$V>1} {puts "$id: $cell adjust height from $hght to $newh."} $cell config -height $newh update update idletasks if ![winfo exists $cell] {Msg "$id: ### $cell disappeared!! ###"; return} set yv [$cell yview] set top [lindex $yv 0] set bot [lindex $yv 1] if {$V>1} {puts "$id: $cell yview is now {$yv} top=$top bot=$bot."} } while {$bot >= 1.0} { if {$V>1} {puts "$id: $cell decr height because bot=$bot (decr)."} set hght [lindex [$cell config -height] end] if {$V>1} {puts "$id: $cell hght=$hght bot=$bot."} incr newh -1 if {$newh < 1} {break} if {$V>1} {puts "$id: $cell adjust height from $hght to $newh."} $cell config -height $newh update update idletasks if ![winfo exists $cell] {Msg "$id: ### $cell disappeared! ###"; return} set yv [$cell yview] set top [lindex $yv 0] set bot [lindex $yv 1] if {$V>1} {puts "$id: $cell yview is now {$yv} top=$top bot=$bot."} } while {$bot < 1.0} { if {$V>1} {puts "$id: $cell incr height because bot=$bot (incr)."} set hght [lindex [$cell config -height] end] if {$V>1} {puts "$id: $cell hght=$hght bot=$bot."} incr newh if {$V>1} {puts "$id: $cell adjust height from $hght to $newh."} $cell config -height $newh update update idletasks if ![winfo exists $cell] {Msg "$id: ### $cell disappeared ###"; return} set yv [$cell yview] set top [lindex $yv 0] set bot [lindex $yv 1] if {$V>1} {puts "$id: $cell yview is now {$yv} top=$top bot=$bot."} } } if {$V>1} {puts "$id: $cell resized.\n"} }