Updated 2015-07-06 05:03:57 by RLE

ulis, 2002-11-24

I gave this explanation on comp.lang.tcl and saw a new related question. The first subject was : scrolling to an item.

Here are some explanations about scrolling.
```    sx1           vx1    ix1    ix2    vx2            sx2
|             |      |      |      |              |
+-------------------------------------------------+
|                                                 |
|             +--------------------+              |
|             |                    |              |
|             |      +------+      |              |
|             |      | item |      |              |
|             |      +------+      |              |
|             |                    |              |
|             |    visible area    |              |
|             +--------------------+              |
|                                                 |
|                  scroll region                  |
+-------------------------------------------------+

The scroll region is where are all your items.

For a canvas generally you set the scroll region with:
.cnv config -scrollregion [.cnv bbox all]
sx1 & sx2 are the x coordinates of the scroll region.
sx1, the beginning, sx2, the end.
You get sx1 & sx2 with .cnv cget -scrollregion.

The visible area is the visible surface of the canvas displayed on screen.
vx1 & vx2 are the x coordinates of the visible area.
vx1, the beginning, vx2, the end.
You know vx1 & vx2 because vx1 is 0
and you fixed vx2 with -width \$vx2.

ix1 & ix2 are the x coordinates of the item.
ix1, the beginning, ix2, the end.
You can get ix1 & ix2 with [.cnv bbox item_tag].

Scrolling is varying the position of the visible area within the scroll region.
If you want to see the beginning of your item you need to have ix1 between vx1 & vx2.
For a canvas, the operation to use is:
.cnv xview moveto \$fraction
where \$fraction is (\$vx1 - \$sx1) / (\$sx2 - \$sx1)
(the percent of the scroll region before the visible area).

So, if you want ix1 == vx1
(the beginning of the item at the beginning of the visible area)
for a canvas you need to do:
.cnv xview moveto [expr {double(\$ix1 - \$sx1) / (\$sx2 - \$sx1)}]```

A canvas example:
```  # create the canvas & the item
canvas .c -width 100 -height 100 \
-scrollregion {-400 -400 400 400} -bg white -bd 1 -relief sunken
.c create text 200 200 -text hidden -tags hidden
# the 'view' proc
proc view {tag} \
{
foreach {x1 y1 x2 y2} [.c bbox \$tag] break
foreach {s1 t1 s2 t2} [.c cget -scrollregion] break
.c xview moveto [expr {double(\$x1 - \$s1) / (\$s2 - \$s1)}]
.c yview moveto [expr {double(\$y1 - \$t1) / (\$t2 - \$t1)}]
}
# some stuff for the demo
proc hide {} \
{
.c xview moveto 0.0
.c yview moveto 0.0
}
button .v -text view -command {view hidden}
button .h -text hide -command {hide}
grid .c -columnspan 2
grid .v .h```