#!/usr/bin/perl -w use strict; use Gtk2 -init; my $image = Gtk2::Image->new_from_file ($ARGV[0]); my $window = Gtk2::Window->new; my $eventbox = Gtk2::EventBox->new; $eventbox->signal_connect_after (realize => sub { my ($widget) = @_; warn "realize\n"; $widget->{drag_gc} = Gtk2::Gdk::GC->new ($widget->window); $widget->{drag_gc}->set_function ('xor'); $widget->{drag_gc}->set_foreground ($widget->style->white); }); $eventbox->signal_connect_after (unrealize => sub { my ($widget) = @_; delete $widget->{drag_gc}; }); sub min { $_[0] < $_[1] ? $_[0] : $_[1] } sub draw_rubber_band_box { my ($widget) = @_; my $x = min ($widget->{draginfo}{x1}, $widget->{draginfo}{x2}); my $y = min ($widget->{draginfo}{y1}, $widget->{draginfo}{y2}); my $w = abs ($widget->{draginfo}{x2} - $widget->{draginfo}{x1}); my $h = abs ($widget->{draginfo}{y2} - $widget->{draginfo}{y1}); $widget->window->draw_rectangle ($widget->{drag_gc}, 1, $x, $y, $w, $h); } $eventbox->signal_connect (button_press_event => sub { my ($widget, $event) = @_; if ($event->button == 1) { $widget->{draginfo} = { x1 => $event->x, y1 => $event->y, x2 => $event->x, y2 => $event->y, }; # Draw... draw_rubber_band_box ($widget); } return 0; }); $eventbox->signal_connect (motion_notify_event => sub { my ($widget, $event) = @_; if ($widget->{draginfo}) { # Erase... draw_rubber_band_box ($widget); $widget->{draginfo}{x2} = $event->x; $widget->{draginfo}{y2} = $event->y; # Draw new... draw_rubber_band_box ($widget); } return 0; }); $eventbox->signal_connect (button_release_event => sub { my ($widget, $event) = @_; if ($widget->{draginfo}) { # Erase... draw_rubber_band_box ($widget); } # Step out of rubber-band mode. delete $widget->{draginfo}; return 0; }); $eventbox->add ($image); $window->add ($eventbox); $window->show_all (); $window->signal_connect (destroy => sub { Gtk2->main_quit () }); Gtk2->main ();