/usr/local/CPAN/Tk-SlideShow/Tk/SlideShow/Link.pm
use strict;
package Tk::SlideShow::Link;
@Tk::SlideShow::Link::ISA = qw(Tk::SlideShow::Placeable);
sub New {
my ($class,$from,$to,$titre,@options) = @_;
$from = Tk::SlideShow::Dict->Get($from) or die unless ref($from);
# print "from =$from\n";
$to = Tk::SlideShow::Sprite->point($from->id."-to") unless $to;
$to = Tk::SlideShow::Dict->Get($to) or die unless ref($to);
my $id = sprintf("%s-%s",$from->id,$to->id);
my $s = bless {'from'=>$from, 'to'=>$to, 'id'=> $id, 'titre' => $titre || "",
'tpos' => 0, 'fpos' => 0, -options => [], -arrowoptions => []};
if (@options>0) {$s->{-options} = [@options]};
$class->Set($id,$s);
$from->addLink($s);
$to->addLink($s);
$s->show;
$s->bind;
$s->trace_link(-100,-100,0,0);
$s->cursor('hand1');
return $s;
}
sub bind {
my $s = shift;
my $c = Tk::SlideShow->canvas ;
my $id = $s->id;
my $movepos = sub {
my $e = (shift)->XEvent;
my ($id,$incr) = @_;
$c->raise($id);
my ($x,$y) = ($c->canvasx($e->x),$c->canvasy($e->y));
if ((abs($s->fx - $x)+abs($s->fy-$y)) >
(abs($s->tx - $x)+abs($s->ty-$y))) {
$s->{'tpos'} += $incr;
my ($x,$y) = $s->to->pos($s->tpos);
Tk::SlideShow::warppointer($x,$y);
} else {
$s->{'fpos'} += $incr;
my ($x,$y) = $s->from->pos($s->fpos);
Tk::SlideShow::warppointer($x,$y);
}
$s->show;
};
$c->bind($id,"<1>", [$movepos, $id, 1]);
$c->bind($id,"<3>", [$movepos, $id,-1]);
}
sub from { return (shift)->{'from'} }
sub to { return (shift)->{'to'} }
sub titre { return (shift)->{'titre'} }
sub id { return (shift)->{'id'} }
sub fpos { return (shift)->var_getset('fpos',(shift))}
sub tpos { return (shift)->var_getset('tpos',(shift))}
sub ftpos {
my ($s,$f,$t) = @_;
$s->{'fpos'}=$f;
$s->{'tpos'}=$t;
$s->show;
return $s;
}
sub fx { return (shift)->{'fx'} }
sub fy { return (shift)->{'fy'} }
sub tx { return (shift)->{'tx'} }
sub ty { return (shift)->{'ty'} }
sub show {
my $s = shift;
my $from = $s->from;
my $to = $s->to;
my $can = Tk::SlideShow->canvas;
my ($w,$h) = (Tk::SlideShow->w,Tk::SlideShow->h);
my $id = $s->id;
my $fpos = $s->fpos % 8;
my ($fx,$fy) = $from->pos($fpos);
$s->{'fpos'} = $fpos;
$s->{'fx'} = $fx;
$s->{'fy'} = $fy;
my $tpos = $s->tpos % 8;
my ($tx,$ty) = $to->pos($tpos);
$s->{'tpos'} =$tpos;
$s->{'tx'} = $tx;
$s->{'ty'} = $ty;
return if $fx < 0 or $fx > $w or $fy < 0 or $fy > $h;
return if $tx < 0 or $tx > $w or $ty < 0 or $ty > $h;
# print "redraw ($fx,$fy,$tx,$ty) (fpos=$fpos,tpos=$tpos)\n";
$s->redraw($fx,$fy,$tx,$ty);
return $s;
}
sub trace_link {
my ($s,$fx,$fy,$tx,$ty) = @_;
my $id = $s->id;
my $can = Tk::SlideShow->canvas;
$can->delete($s->id);
$s->{'lineid'} = $can->createLine($fx,$fy,$tx,$ty,-tags,$id,
@{$s->{-arrowoptions}},
@{$s->{-options}},
);
# print "Arrow Option of ".ref($s)."($id) = ".join(',',@{$s->{-arrowoptions}})."\n";
if ($s->titre) {
my $wid = $can->createText(($fx+$tx)/2,($fy+$ty)/2,'-text',$s->titre, -tags,$id);
my $rectid = $can->createRectangle($can->bbox($wid),-fill,'lightYellow',-outline,'red',-tags,$id);
$can->raise($wid);
$s->{'titleid'} = $wid;
$s->{'rectid'} = $rectid;
}
}
sub redraw {
my ($s,$fx,$fy,$tx,$ty) = @_;
my $id = $s->id;
my $c = Tk::SlideShow->canvas;
my $lineid = $s->{'lineid'};
$c->coords($lineid,$fx,$fy,$tx,$ty);
if ($s->titre) {
my $wid = $s->{'titleid'};
$c->coords($wid,($fx+$tx)/2,($fy+$ty)/2);
$c->coords($s->{'rectid'},$c->bbox($wid));
}
}
sub hide {(shift)->redraw(-100,-100,-10,-10);}
sub evalplace {
my $s = shift;
return sprintf("ftpos(%d,%d)",$s->fpos,$s->tpos);
}
1;