#! perl use strict; use warnings; use Tk; # Main window with a stretchy canvas... my $mw = new MainWindow( -title => "Tk Canvas Item Drag" ); my $c = $mw->Canvas( -width => 600, -height => 300, -bg => 'beige', )->pack( -expand => '1', -fill => 'both' ); # Some rectangle items... $c->createRectangle( 100, 100, 200, 200, -fill => 'orange', -activefill => 'darkorange', -outline => 'red', -activeoutline => 'green', -width => 1, -activewidth => 2, -tags => ['draggable'], ); $c->createRectangle( 210, 110, 260, 160, -fill => 'red', -activefill => 'darkred', -tags => ['draggable'], ); # This one is not draggable... $c->createRectangle( 410, 90, 510, 160, -fill => 'blue', -activefill => 'navy', ); # An image of a playing card - loaded from a a pixmap with the playing_card_xpm sub - see below... $c->Pixmap( 'card', -data => playing_card_xpm() ); $c->createImage( 300, 100, -image => 'card', -anchor => 'nw', -tags => [ 'draggable', 'card' ], ); my $description = <<'EOF'; The orange and red rectangles can be moved - the blue one can't. When the playing card is dragged it leaves a vector behind! Take a look at the info that goes to STDOUT. EOF $c->createText( 300, 20, -anchor => 'n', -justify => 'center', -text => $description ); # add bindings for draggable objects... $c->bind( 'draggable', '<1>' => \&drag_start ); $c->bind( 'draggable', '' => \&drag_during ); $c->bind( 'draggable', '' => \&drag_end ); # the enter and leave events could be used to show and hide highlight type objects... $c->bind( 'draggable', '' => undef ); $c->bind( 'draggable', '' => undef ); # Dragging item info hash to be kept during a drag... my %draginfo; MainLoop(); sub drag_start { print "drag_start:\n"; my ($c) = @_; my $e = $c->XEvent; # get the screen position of the initial button press... my ( $sx, $sy ) = ( $e->x, $e->y,,, ); print "\t screen: $sx, $sy\n"; # get the canvas position... my ( $cx, $cy ) = ( $c->canvasx($sx), $c->canvasy($sy) ); print "\t canvas: $cx, $cy\n"; # get the clicked item... my $id = $c->find( 'withtag', 'current' ); print "\t item id: $id\n"; my ( $x1, $y1, $x2, $y2 ) = $c->bbox($id); print "\t obj has bbox: $x1, $y1, $x2, $y2.\n"; # set up the draginfo... $draginfo{id} = $id; $draginfo{startx} = $draginfo{lastx} = $cx; $draginfo{starty} = $draginfo{lasty} = $cy; } sub drag_during { print "drag_during:\n"; my ($c) = @_; my $e = $c->XEvent; # get the screen position of the move... my ( $sx, $sy ) = ( $e->x, $e->y,,, ); print "\t screen: $sx, $sy\n"; # get the canvas position... my ( $cx, $cy ) = ( $c->canvasx($sx), $c->canvasy($sy) ); print "\t canvas: $cx, $cy\n"; # get the amount to move... my ( $dx, $dy ) = ( $cx - $draginfo{lastx}, $cy - $draginfo{lasty} ); print "\t dx, dy = $dx, $dy\n"; # move it... $c->move( $draginfo{id}, $dx, $dy ); # update last position $draginfo{lastx} = $cx; $draginfo{lasty} = $cy; my ( $x1, $y1, $x2, $y2 ) = $c->bbox( $draginfo{id} ); print "\t obj has bbox: $x1, $y1, $x2, $y2.\n"; } sub drag_end { print "drag_end: \n"; # upon drag end, check for valid position and act accordingly... # was it the card? my @tags = $c->gettags( $draginfo{id} ); if ( grep /^card$/, @tags ) { # did it move anywhere? If so draw a vector... if ( $draginfo{startx} - $draginfo{lastx} or $draginfo{starty} - $draginfo{lasty} ) { my $line = $c->createLine( $draginfo{startx}, $draginfo{starty}, $draginfo{lastx}, $draginfo{lasty}, -arrow => 'last', -width => 3, -capstyle => 'round', -fill => 'navy', ); } } %draginfo = (); } # return the source of a nice playing card pixmap... sub playing_card_xpm { return <<'EOXPM'; /* XPM */ static char *j[] = { /* width height num_colors chars_per_pixel */ " 73 97 8 1", /* colors */ "` c #000000", ". c #808080", "# c #c0c0c0", "a c None", "b c #ffffff", "c c #000000", "d c #000000", "e c #000000", /* pixels */ "a#`````````````````````````````````````````````````````````````````````#a", "#.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.#", "`bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbb````bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbb.``.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbb``bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbb``bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbb``bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbb``bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbb``bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbb``bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbb`#bb``bbbbbbbbbbbbbbbbbbbbb#.`````..#bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbb``bb``bbbbbbbbbbbbbbbbbbb#.```````````#bbbbbbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbb.````.bbbbbbbbbbbbbbbbbb.``````````````.bbbbbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbb.``.bbbbbbbbbbbbbbbbbb#`````````````.```bbbbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbb#`````````````..```.bbbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbb.`````````````...```#bbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbb````````````````````.bbbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbb#`````````````````````#bbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbb#`````````````````````.bbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbb.``````````````````````bbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbb.````````````...```````bbbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbb#``.#.``````..##.``````#bbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbb.``##b#````##b#b.``````#bbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbb#`.#.#b.```#b..#b.`````.bbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbb#`.``.#.``.b.``.##`````#bbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbb#`..`..#```#.```#b`````.bbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbb#``.``.....#````#b`````#bbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbb``#.`######..`.##`````.bbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbb``..############``````.bbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbb``..####b#######.``````bbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbb`..#######b#####.``````bbbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbb``.####b######.#.``````#bbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbb``..###########..``.```.bbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbb``...#######.....``...``bbbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbb.`#....#.#....###```..``.bbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbb.`##........##bbb.```.```bbbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbb.``###.....####bbb#```````.bbbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbb#```bb#########bbbbb.```````#bbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbb```#bb#######bbbbbbbb````````bbbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbb.``.bbbb####bbbbbbbbbb.```````.bbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbb#```bbbbbbb#bbbbbbbbbbb#````````bbbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbb```.bbbbbbbbbbbbbbbbbbbb.````````bbbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbbb.```bbbbbbbbbbbbbbbbbbbbb.`````````bbbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbbb.```.##bbbbbb#bbbbbbbb#b#b#`````````.bbbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbb.````..b#bbb#b#bbbb#b######b``````````#bbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbbb`````.#b#bbbbbbbbbbbbb#b###b#``````````bbbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbb#````.#bbbbbbb#bbbbbbbbbbbb##b.`````````#bbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbb.````##bbbbbbbbbbbbbbbbbbbbb###``````````bbbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbb````.#bbbbbbbbbbbbbbbbbbbbbbbb#.`````````#bbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbbb````#bbbbbbbbbbbbbbbbbbbbbbbbbb#``.``````.bbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbb.```.#bbbbbbbbbbbbbbbbbbbbbbbbbbb`.``.`````bbbbbbbbbbbb`", "`bbbbbbbbbbbbbbbb````.bbbbbbbbb#bbbbbbbbbbbbbbbbbb.`````````#bbbbbbbbbbb`", "`bbbbbbbbbbbbbbb.````bbbbbbbbbb#bbbbbbbbbbbbbbbbbb.`````````.bbbbbbbbbbb`", "`bbbbbbbbbbbbbbb.```.bbbbbbbbb#bbbbbbbbbbbbbbbbbbb.``````````bbbbbbbbbbb`", "`bbbbbbbbbbbbbb#````#bbbbbbbbb#bbbbbbbbbbbbbbbbbbb.``````````#bbbbbbbbbb`", "`bbbbbbbbbbbbbb.````#bbbbbbbbb#bbbbbbbbbbbbbbbbbbb#``````````.bbbbbbbbbb`", "`bbbbbbbbbbbbb.````.bbbbbbbbbb#bbbbbbbbbbbbbbbbbbb#``````````.bbbbbbbbbb`", "`bbbbbbbbbbbbb``````#bbbbbbbbb#bbbbbbbbbbbbbbbbbbbb```````````bbbbbbbbbb`", "`bbbbbbbbbbbb.```.`.bbbbbbbbbb#bbbbbbbbbbbbbbbbbbb#```````````bbbbbbbbbb`", "`bbbbbbbbbbbb#````..#bbbbbbbbb#bbbbbbbbbbbbbbbbbbbb``````````.bbbbbbbbbb`", "`bbbbbbbbbbbb.````..bbbbbbbbbb#bbbbbbbbbbbbbbbbbbb#``````````.bbbbbbbbbb`", "`bbbbbbbbbbbb#`.#.`.bbbbbbbbbb#bbbbbbbbbbbbbbbbbbb#```````.``.bbbbbbbbbb`", "`bbbbbbbbbbbbb####.`##bbbbbbbb#bbbbbbbbbbbbbbbb###.``````````.bbbbbbbbbb`", "`bbbbbbbbbbbb######.`.#bbbbbbb#bbbbbbbbbbbbbbbb###b`````````.bbbbbbbbbbb`", "`bbbbbbbbbbb#.######.`.#bbbbbbbbbbbbbbbbbbbbbbb####````````.##bbbbbbbbbb`", "`bbbbbbbbbb#..#######```#bbbbbb#bbbbbbbbbbbbbbb###..``````.###bbbbbbbbbb`", "`bbbbbbbb##.##########```#bbbbbbbbbbbbbbbbbbb#####..`````..###bbbbbbbbbb`", "`bbbbb###.#.##########.```#bbbbbbbbbbbbbbbbbb#####........####bbbbbbbbbb`", "`bbbb#.################````.#bbbbbbbbbbbbbbbb##.##.#.....######bbbbbbbbb`", "`bbbb##################.````.bbbbbbbbbbbbbbbb##..##.#...########bbbbbbbb`", "`bbbb###################`````bbbbbbbbbbbbbbbbb#..################bbbbbbb`", "`bbbb###################.````#bbbbbbbbbbbbbbb##...################bbbbbb`", "`bbbb#.##################.``#bbbbbbbbbbbbbbbb#`..##################bbbbb`", "`bbbb#.####################bbbbbbbbbbbbbbbbb#``..###################bbbb`", "`bbbb#####################.#bbbbbbbbbbbbbb#.```..###################bbbb`", "`bbbb#.####################.bbbbbbbbbbbbb#`````..##################bbbbb`", "`bbbb#####################...#bbbbbbbb##.``````.##################bbbbbb`", "`bbbb..####################.``..#....``````````..#.##############bbbbbbb`", "`bbbb#..#.################...`````````````````...###########.##bbbbbbbbb`", "`bbbb#.........##########.#..``````````````````...##.#####..#bbbbbbbbbbb`", "`bbbbbb#..........####.#....``````````````````..#..###.....#bbbbbbbbbbbb`", "`bbbbbbbbbb#.................``..###########..`...#..#....bbbbbb.``.bbbb`", "`bbbbbbbbbbbbb#........#...`.#bbbbbbbbbbbbbbbb.`.........bbbbbb.````.bbb`", "`bbbbbbbbbbbbbbbbb#......`..bbbbbbbbbbbbbbbbbb#.`.......bbbbbbb``bb``bbb`", "`bbbbbbbbbbbbbbbbbbb#..``.#bbbbbbbbbbbbbbbbbbbb#.```..#bbbbbbbb``bb#`bbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb``bbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb``bbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb``bbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb``bbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb``bbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb``bbbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.``.bbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb````bbbbbb`", "`bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb`", "#.bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.#", "a#`````````````````````````````````````````````````````````````````````#a" }; EOXPM }