scrollable canvas, how to scroll to show item

10 views
Skip to first unread message

Eric Taylor

unread,
Nov 26, 2001, 9:32:47 PM11/26/01
to
With a scrollable text widget, one can use something like this:

$text insert end "$text\n"
$text see end


And the frame will automatically scroll to show the newly
inserted text.

Is there something similar to this for a canvas?

I have lots of tagged items in a canvas. Can I somehow
ask that an item with a certain tag show in the window and
have it auto scroll so that it appears.

Or is there a simple few lines of code to do this?

Actually, I only scroll in the y dimension, if that
makes it easier.

thanks
eric


Mark G. Saye

unread,
Nov 26, 2001, 10:11:50 PM11/26/01
to
Eric Taylor wrote:
>
> With a scrollable text widget, one can use something like this:
>
> $text insert end "$text\n"
> $text see end
>
> And the frame will automatically scroll to show the newly
> inserted text.
>
> Is there something similar to this for a canvas?
>
> I have lots of tagged items in a canvas. Can I somehow
> ask that an item with a certain tag show in the window and
> have it auto scroll so that it appears.
>
> Or is there a simple few lines of code to do this?

I picked up this snippet of code somewhere (can't remember where, and it
doesn't have copyright info - if anyone knows who wrote this, please let
me know). I haven't reaaly used it much either, so can't vouch for it's
robustness. Here it is anyway ...

proc canvas:see {c item} {

set box [$c bbox $item]

if { [string match {} $box] } { return }

if { [string match {} [$c cget -scrollregion]] } {
# People really should set -scrollregion you know...
foreach {x y x1 y1} $box {
set x [expr round(2.5 * ($x1+$x) / [winfo width $c])]
set y [expr round(2.5 * ($y1+$y) / [winfo height $c])]
}
$c xview moveto 0
$c yview moveto 0
$c xview scroll $x units
$c yview scroll $y units
} else {
# If -scrollregion is set properly, use this
foreach {x y x1 y1} \
$box {top btm} \
[$c yview] {left right} \
[$c xview] {p q xmax ymax} \
[$c cget -scrollregion] \
{
set xpos [expr (($x1+$x) / 2.0) / $xmax - ($right-$left) / 2.0]
set ypos [expr (($y1+$y) / 2.0) / $ymax - ($btm-$top) / 2.0]
}
$c xview moveto $xpos
$c yview moveto $ypos
}

}

# Basic demo code example ...
set canvas [canvas .canvas -bg white -scrollregion [list 0 0 1000 1000]]
pack $canvas -expand 1 -fill both
set id [$canvas create rectangle 500 500 600 600 -fill blue]
canvas:see $canvas $id

Good luck.

Mark /

--
Mark G. Saye
mark...@yahoo.com

Eric Taylor

unread,
Nov 27, 2001, 2:44:35 AM11/27/01
to
Geez, you guys are going to spoil me. Boy does that snipit
hit the spot!!

Thanks Mark!

Eric

Reply all
Reply to author
Forward
0 new messages