Version 5 of Getting the Canvas View Area in Pixels

Updated 2006-01-08 12:26:59

GPS Fri Oct 26, 2001: I had some trouble trying to figure out how to get the canvas view area in pixels for a game I'm writing called The Adventures of Baldo the Alien, so I devised the code below. Now it seems so obvious, but at the time it definitely wasn't. I guess I expected the canvas to have a builtin command that would tell me stuff like this, but I couldn't find a command to do it, so I wrote my own.

Enjoy!


  #!/usr/local/bin/wish8.3

  proc getCanvasViewArea {win} {

        # This foreach is used only as a "list assign", and has an empty body.
        foreach {junk junk totalXArea totalYArea} [$win cget -scrollregion] {break}
        set xview  [$win xview]
        set yview  [$win yview]

        set xstart [expr {int([lindex $xview 0] * $totalXArea)}]
        set xend   [expr {int([lindex $xview 1] * $totalXArea)}] 

        set ystart [expr {int([lindex $yview 0] * $totalYArea)}]
        set yend   [expr {int([lindex $yview 1] * $totalYArea)}] 


        return [concat $xstart $xend $ystart $yend]
  }

  #Just some simple demonstration code
  proc main {} {
        pack [canvas    .c -scrollregion {0 0 5000 500} -xscrollcommand ".s set"]
        pack [scrollbar .s -command ".c xview" -orient horizontal] -fill x

        pack [label  .l -text [getCanvasViewArea .c]]
        pack [button .b -text "Get View Area" -command {
                .l config -text [getCanvasViewArea .c]
        }]
  }
  main

This Only works if the scrollregion is always {0 0 $X $Y} which is not neccessarily true. (If I'm plotting geographic data I might have a scroll region of {-180 -90 180 90}

so I would replace

       foreach {junk junk totalXArea totalYArea} [$win cget -scrollregion]{break}

with the following:

       foreach {x1 y1 x2 y2} [$win cget -scrollregion]{break}
       set totalXArea [expr $x2 - $x1]
       set totalYArea [expr $y2 - $y1]

--bbh


GAF -- Yes, but the scrollregion is not the viewable area that the user can see right now. How do you find that? For instance:

 canvas .c  -height 100 -width 100 -bd 1
 pack .c
 .c create rectangle 4 5 103 104 -outline blue
 .c create rectangle 2 2 101 101 -outline green

In this example, on the Mac 10.4.3 ActiveState Tcl/Tk, the blue rectangle is the largest that shows all its lines. Under X windows on the _same machine_ the green rectangle is the largest completely visible rectangle. What gives? Is there any way to really know the actual visible area of a canvas? -- GAF


Category Graphics