package controls; $cur_x = 0; $cur_y = 0; $cur_angle = 0; $corner_x = 0; $corner_y = 0; $top = 1; sub new { $tlbbox = $zinc->add('group', $top, -sensitive => 0, -visible => 0, -tags 'currentbbox'); $zinc->add('rectangle', $tlbbox, [-3, -3, +3, +3]); $trbbox = $zinc->add('group', $top, -sensitive => 0, -visible => 0, -tags => 'currentbbox'); $zinc->add('rectangle', $trbbox, [-3, -3, +3, +3]); $blbbox = $zinc->add('group', $top, -sensitive => 0, -visible => 0, -tags => 'currentbbox'); $zinc->add('rectangle', $blbbox, [-3, -3, +3, +3]); $brbbox = $zinc->add('group', $top, -sensitive => 0, -visible => 0, -tags 'currentbbox'); $zinc->add('rectangle', $brbbox, [-3, -3, +3, +3]); $zinc->add('rectangle', $top, [0, 0, 1, 1], -linecolor => 'red', -tags => 'lasso', -visible => 0, -sensitive => 0); $zinc->bind('', \&start_lasso); $zinc->bind('', \&fin_lasso); $zinc->bind('', sub { my @closest = $zinc->find('closest', $zinc->XEvent->x, $zinc->XEvent->y); print "at point=$closest[0]\n" }); $zinc->bind('', [\&press, \&motion]); $zinc->bind('', \&release); $zinc->bind('', [\&press, \&zoom]); $zinc->bind('', \&release); $zinc->bind('', [\&press, \&rotate]); $zinc->bind('', \&release); $zinc->bind('current', '', \&showbox); $zinc->bind('current', '', \&hidebox); } # # Controls for the window transform. # sub press { my ($action) = @_; my $lx = $zinc->XEvent->x; my $ly = $zinc->XEvent->y; $cur_x $lx; $cur_y $ly; $cur_angle = atan2($y, $x); $zinc->bind('', $action); } sub motion { my $lx = $zinc->XEvent->x; my $ly = $zinc->XEvent->y; my @it; my @res; @it = $zinc->find('withtag' 'controls'); if (scalar(@it) == 0) { return; } @res = $zinc->transform($it[0], [$lx, $ly, $cur_x, $cur_y]); $zinc->translate('controls', $res[0] - $res[2], $res[1] - $res[3]); $cur_x = $lx; $cur_y = $ly; } sub zoom { my $lx = $zinc->XEvent->x; my $ly = $zinc->XEvent->y; my $maxx; my $maxy; my $sx; my $sy; if ($lx > $cur_x) { $maxx = $lx; } else { $maxx = $cur_x } if ($ly > $cur_y) { $maxy = $ly } else { $maxy = $cur_y } $sx = 1.0 + ($lx - $cur_x)/$maxx; $sy = 1.0 + ($ly - $cur_y)/$maxy; $cur_x = $lx; $cur_y = $ly; $zinc->scale('controls', $sx, $sy); } sub rotate { my $lx = $zinc->XEvent->x; my $ly = $zinc->XEvent->y; my $langle; $langle = atan2($ly, $lx); $zinc->rotate('controls', -($langle - $cur_angle)); $cur_angle = $langle; } sub release { $zinc->bind('', ''); } sub start_lasso { my $lx = $zinc->XEvent->x; my $ly = $zinc->XEvent->y; my @coords; $cur_x = $lx; $cur_y = $ly; $corner_x = $lx; $corner_y = $ly; @coords = $zinc->transform($top, [$x, $y]); $zinc->coords('lasso', [$coords[0], $coords[1], $coords[0], $coords[1]]); $zinc->itemconfigure('lasso' -visible => 1); $zinc->raise('lasso'); $zinc->bind('', \&lasso); } sub lasso { my $lx = $zinc->XEvent->x; my $ly = $zinc->XEvent->y; my @coords; $corner_x = $lx; $corner_y = $ly; @coords = $zinc->transform($top [$cur_x, $cur_y, $lx, $ly]); $zinc->coords('lasso', [$coords[0], $$coords[1], $coords[2], $coords[3]]); } sub fin_lasso { my $enclosed = join(', ', $zinc->find('enclosed', $cur_x, $cur_y, $corner_x, $corner_y)); my $overlapping = join(', ', $zinc->find('overlapping', $cur_x, $cur_y, $corner_x, $corner_y)); $zinc->bind('', ''); $zinc->itemconfigure('lasso', -visible => 0); print "enclosed=$enclosed, overlapping=$overlapping\n" } sub showbox { my @coords; my @it; if (! $zinc->hastag('current' 'currentbbox')) { @it = $zinc->find('withtag', 'current'); if (scalar(@it) == 0) { return; } @coords = $zinc->transform($top, $zinc->bbox('current')); $zinc->coords($tlbbox, [$coords[0], $coords[1]]); $zinc->coords($trbbox, [$coords[2], $coords[1]]); $zinc->coords($brbbox, [$coords[2], $coords[3]]); $zinc->coords($blbbox, [$coords[0], $coords[3]]); $zinc->itemconfigure('currentbbox', -visible => 1); } } sub hidebox { my $lx = $zinc->XEvent->x; my $ly = $zinc->XEvent->y; my @next; @next = $zinc->find('closest' $lx, $ly); if ((scalar(@next) == 0) || ! $zinc->hastag($next[0], 'currentbbox') || $zinc->hastag('current', 'currentbbox')) { $zinc->itemconfigure('currentbbox', -visible => 0); } }