sizepanel

19. Feb 2003 / MSW.


The question on Ask, and it shall be given. was how to allow people resizing windows to do this exactly, preferrably by a label which displays the exact dimensions on the window being resized:

When a user resizes a toplevel window I want to get a continuous feedback about the window's dimensions, so that I am able to display that on a label and user can set the exact size. The problem with <Configure> event bind is that it is fired at the end of the resizing operation.I want dimensions 'live' during resizing.

Well, I digged some but could not find a fitting binding for use with bind, nor the fitting protocol thing for use with wm protocol.

So I suggested to use a little panel instead, well, this is my shot at it.


MSW(2005-02-26): Some grooming taken place.

sizepanel now also allows setting of the x & y offset part of [wm geometry], is wrapped up in its namespace, and allows multiple instances of itself (might be interesting for apps with multiple toplevel-windows -- I tested it with a sizepanel resizing a sizepanel resizing . ... Could still use a lot of grooming, keybindings...


 proc here {} {uplevel {namespace current}}

 namespace eval szpan {
   variable szwin 0
   variable vals
   array set vals {}
   namespace export size*

   proc sizepanel {toplvl} {
     variable szwin
     variable vals

     set top [toplevel .szpan[incr szwin]]
     wm title $top "Sizing $toplvl"
     sizeframe $toplvl $top
   }

   proc sizeframe {toplvl top} {
     if {$top == {.}} then { set top [frame .f] }

     foreach {minx miny} [wm minsize $toplvl] {}
     foreach {maxx maxy} [wm maxsize $toplvl] {}
     set maxXOffset [winfo screenwidth $toplvl]
     set maxYOffset [winfo screenheight $toplvl]
     scan [wm geometry $toplvl] {%dx%d+%d+%d} w h x y

     entry $top.w -textvar [here]::vals($toplvl,width) -width 4
     label $top.lw -text "Width : " -width 11
     scale $top.sw -variable [here]::vals($toplvl,width) -from $minx \
       -to $maxx -orient h -showvalue 0

     entry $top.h -textvar [here]::vals($toplvl,height) -width 4
     label $top.lh -text "Height : " -width 11
     scale $top.sh -variable [here]::vals($toplvl,height) -from $miny \
       -to $maxy -orient h -showvalue 0

     entry $top.x -textvar [here]::vals($toplvl,xOffset) -width 4
     label $top.lx -text "x-offset : " -width 11
     scale $top.sx -variable [here]::vals($toplvl,xOffset) -from 0 \
       -to $maxXOffset -orient h -showvalue 0

     entry $top.y -textvar [here]::vals($toplvl,yOffset) -width 4
     label $top.ly -text "y-offset : " -width 11
     scale $top.sy -variable [here]::vals($toplvl,yOffset) -from 0 \
       -to $maxYOffset -orient h -showvalue 0

     button $top.k -text "Done" -command \
       "catch {array unset [here]::vals $toplvl,*} ; destroy $top"

     grid $top.lw $top.w $top.sw
     grid $top.lh $top.h $top.sh
     grid $top.lx $top.x $top.sx
     grid $top.ly $top.y $top.sy
     grid $top.k -columnspan 3
     if {[winfo toplevel $top] != $top} then {
       pack $top -expand 1 -fill both
     }

     set szpan::vals($toplvl,height) $h
     set szpan::vals($toplvl,width) $w
     set szpan::vals($toplvl,xOffset) $x
     set szpan::vals($toplvl,yOffset) $y

     if {![llength [trace info variable szpan::vals]]} then {
       trace add variable [here]::vals write [namespace code sztrace]
     }
   }  

   proc sztrace {var1 var2 op} {
     variable vals
     scan $var2 {%[^,],%s} win opt

     catch {
       wm geometry $win [join [list \
          "$vals($win,width)"\
         "x$vals($win,height)"\
         "+$vals($win,xOffset)"\
         "+$vals($win,yOffset)"] ""]
     }
   }
 }

Use with sizepanel <toplevel-window>, e.g.

 % namespace import szpan::*
 % sizeframe . .
 % sizepanel .

See also sizeinfo.


MSW: Both these solutions are not really what was asked for, but in the one way or another they both are satisfying I guess...


Category GUI Category Example