I worked on that awhile back, and this is what I came up with for centering on waypoints ..... it may not be perfect, but it works, and also incorporates scale....which you really need to deal with.. I just came up with the algorithm by guessing. :-) .... so there may be a better way. HTH..... I'm fading out of this stuff...of course I was tempted to use my Goo Canvas and transparent images to simulate the flight of that typo dong 2 missle. Would work perfect. :-)

See

#!/usr/bin/perl -w use strict; use warnings; use Goo::Canvas; use Gtk2 '-init'; use Glib qw(TRUE FALSE); # slower than Gnome2::Canvas with long drags my $draw_flag = 0; my %lines; # way to store multiple continuous lines my $count = 0; my $window = Gtk2::Window->new('toplevel'); $window->signal_connect('delete_event' => sub { Gtk2->main_quit; }); $window->set_default_size(640, 600); my $vbox = Gtk2::VBox->new; $vbox->set_border_width(4); $vbox->show; my $hbox = Gtk2::HBox->new(FALSE, 4); $vbox->pack_start($hbox, FALSE, FALSE, 0); $hbox->show; $window->add($vbox); my $swin = Gtk2::ScrolledWindow->new; $swin->set_shadow_type('in'); $vbox->pack_start($swin, 1, 1, 0); my $cwidth = 4000; my $cheight = 2000; my $canvas = Goo::Canvas->new(); $canvas->set_size_request(900, 600); # size on screen $canvas->set_bounds(0, 0, $cwidth, $cheight); # scrollregion $swin->add($canvas); my $root = $canvas->get_root_item(); ##################################################### # if you want to underlay an image my $im = Gtk2::Gdk::Pixbuf->new_from_file("USA.gif"); my $w = $im->get_width; my $h = $im->get_height; my $image = Goo::Canvas::Image->new( $root, $im, 0, 0, 'width' => $w, 'height' => $h); ###################################################### $canvas->signal_connect (event => \&event_handler); # Zoom my $z = Gtk2::Label->new("Zoom:"); $hbox->pack_start($z, FALSE, FALSE, 0); $z->show; my $adj = Gtk2::Adjustment->new(1, 0.05, 100, 0.05, 0.5, 0.5); my $sb = Gtk2::SpinButton->new($adj, 0, 2); $adj->signal_connect("value-changed", \&zoom_changed, $canvas); $sb->set_size_request(60, -1); $hbox->pack_start($sb, FALSE, FALSE, 10); $sb->show; # Create PDF + my $bpdf = Gtk2::Button->new_with_label('Write PDF'); + $hbox->pack_start($bpdf, FALSE, FALSE, 0); + $bpdf->show; + $bpdf->signal_connect("clicked", \&write_pdf_clicked, $canvas); + $window->show_all(); Gtk2->main; sub event_handler{ my ( $widget, $event ) = @_; # print $widget ,' ',$event->type,"\n"; my $scale = $adj->get_value; # print "scale->$scale\n"; if ( $event->type eq "button-press" ) { $draw_flag = 1; #start a new line curve $count++; my ($x,$y) = ($event->x,$event->y); # print "$x $y\n"; $lines{$count}{'points'} = [$x/$scale,$y/$scale,$x/$scale,$y/$ +scale]; #need at least 2 points my $points = Goo::Canvas::Points->new($lines{$count}{'points'} +); $lines{$count}{'line'} = Goo::Canvas::Polyline->new( $root, FALSE, undef, # points need to be set after creation 'stroke-color' => 'black', 'line-width' => 3, ); #setting after line creation, sets the 'points' property by name $lines{$count}{'line'}->set(points => $points); } if ( $event->type eq "button-release" ) { $draw_flag = 0; } if ( $event->type eq "focus-change" ) { return 0; } if ( $event->type eq "expose" ) { return 0; } if($draw_flag){ #left with motion-notify if ( $event->type eq "motion-notify"){ my ($x,$y) = ($event->x,$event->y); # print "$x $y\n"; push @{$lines{$count}{'points'}},$x/$scale,$y/$scale; my $points = Goo::Canvas::Points->new( $lines{$count}{'points'} ) +; $lines{$count}{'line'}->set(points => $points); } } Gtk2->main_iteration while Gtk2->events_pending; return 1; } sub write_pdf_clicked { my ($but, $canvas) = @_; print "Write PDF...\n"; my $scale = $adj->get_value; print "scale->$scale\n"; my $surface = Cairo::PdfSurface->create("$0-$scale.pdf", $scale*$cwidth, $scale*$cheight); my $cr = Cairo::Context->create($surface); # needed to save scaled version $cr->scale($scale, $scale); $canvas->render($cr, undef, 1); $cr->show_page; print "done\n"; return TRUE; } sub zoom_changed { my ($adj, $canvas) = @_; $canvas->set_scale($adj->get_value); }

Also of interest to centering would be:

#!/usr/bin/perl -w use strict; use warnings; use Goo::Canvas; use Gtk2 '-init'; use Glib qw(TRUE FALSE); use Gtk2::Gdk::Keysyms; # Z and z zoom in and out my $scale = 1; my $window = Gtk2::Window->new('toplevel'); $window->signal_connect('delete_event' => sub { Gtk2->main_quit; }); #$window->set_size_request(600, 400); my $swin = Gtk2::ScrolledWindow->new; $swin->set_shadow_type('in'); $window->add($swin); my ($cwidth,$cheight)= (2400,2400); my ($cx,$cy) = ($cwidth/2,$cheight/2); my $canvas = Goo::Canvas->new(); my ($cw,$ch) = (600,400); $canvas->set_size_request($cw, $ch); $canvas->set_bounds(0,0, $cwidth, $cheight); #$canvas->set_bounds( 0, 0,2*$cwidth,2* $cheight); my $black = Gtk2::Gdk::Color->new (0x0000,0x0000,0x0000); my $white = Gtk2::Gdk::Color->new (0xFFFF,0xFFFF,0xFFFF); $canvas->modify_base('normal',$white ); $swin->add($canvas); my $root = $canvas->get_root_item(); #my ($margin_x,$margin_y) = (100,100); #my $g = Goo::Canvas::Group->new($root); #$g->scale(1,-1); #reverse direction of y axis, so graphing will be no +rmal cartesian #$g->translate( $margin_x, $margin_y); #notice translations are revers +ed my $ha1 = $swin->get_hadjustment; my $va1 = $swin->get_vadjustment; my $vupper = $va1->upper; my $hupper = $ha1->upper; my $hadjc = $ha1->value; my $vadjc = $va1->value; print "uppers $vupper $hupper\n"; $va1->signal_connect( value_changed => sub { my $adj = shift; #print 'vchanged ',$adj-> +get_value,"\n"; #$manual = 1; return 0; } ); $ha1->signal_connect( value_changed => sub { my $adj = shift; #print 'hchanged ',$adj-> +get_value,"\n"; #$manual = 1; return 0; } ); my $hbr = $swin->get_hscrollbar; my $vbr = $swin->get_vscrollbar; #print "$hbr $vbr\n"; $hbr->signal_connect(move_slider => sub{ #print "moving slider @_\n" }); $vbr->signal_connect(move_slider => sub{ #print "moving slider @_\n" }); $hbr->signal_connect(event_after => sub{ #print "after slider @_\n"; my($bar,$event) = @_; #print $bar,' ',$event->type,"\n"; }); $vbr->signal_connect(event_after => sub{ # print "after slider @_\n"; my($bar,$event) = @_; #print $bar,' ',$event->type,"\n"; }); $canvas->scroll_to( $cx - $cw/2 ,$cy - $ch/2 ); print $canvas->get_bounds,"\n"; my @points1 = (0,$cy,$cwidth,$cy); my $poly1 = Goo::Canvas::Polyline->new( $root, FALSE, \@points1, 'stroke-color' => 'black', 'line-width' => 1, ); my @points2 = ($cx,0,$cx,$cheight); my $poly2 = Goo::Canvas::Polyline->new( $root, FALSE, \@points2, 'stroke-color' => 'black', 'line-width' => 1, ); $canvas->signal_connect('button-press-event', \&on_can_button_press); $canvas->signal_connect_after('key_press_event', \&on_key_press); $canvas->can_focus(TRUE); $canvas->grab_focus($root); #&set_axis(); #&plot(); $window->signal_connect(event_after => \&event_after); $window->show_all(); Gtk2->main; sub on_can_button_press { #print "@_\n"; my ($widget, $event ) = @_; #print $widget ,' ',$event->type, ' ','button',' ',$event->butto +n,"\n"; my ($x,$y) = ($event->x,$event->y); print "$x $y\n"; return 0; } sub on_key_press { # print "@_\n"; my ( $canvas, $event ) = @_; # print $event->type,"\n"; if ( $event->keyval == $Gtk2::Gdk::Keysyms{Z} ) { $scale += .1; $canvas->set_scale($scale); print "$scale\n"; # $canvas->scroll_to($cx - $cw/2,$cy- $ch/2); # $canvas->scroll_to( $cx + $scale*$cx - $cw/2 ,$cy + $scale* +$cy - $ch/2 ); #$canvas->scroll_to( 0 - $cw/2 ,0 - $ch/2 ); # $ha1->upper($hupper * $scale); # $hupper = $ha1->upper; # print "new hupper $hupper\n"; # $ha1->clamp_page(0,$hupper); $hadjc = $ha1->value; print "$hadjc\n"; # $va1->upper($vupper * $scale); # $vupper = $va1->upper; # print "new vupper $vupper\n"; # $va1->clamp_page(0,$vupper); $vadjc = $va1->value; print "$vadjc\n"; #$canvas->scroll_to( $cx + $scale*$cx - $cw/2 ,$cy + $scale*$cy + - $ch/2 ); #$canvas->scroll_to( $hupper/2 , $vupper/2 ); } if ( $event->keyval == $Gtk2::Gdk::Keysyms{z} ) { $scale -= .1; $canvas->set_scale($scale); #canvas->scroll_to(0,$cheight); #$canvas->scroll_to( 0 - $cw/2 ,0 - $ch/2 ); #$canvas->scroll_to( $cx + $scale*$cx - $cw/2 ,$cy + $scale* +$cy - $ch/2 ); } if ( $event->keyval == $Gtk2::Gdk::Keysyms{s} ) { write_pdf($canvas); } if ( $event->keyval == $Gtk2::Gdk::Keysyms{c} ) { #$canvas->scroll_to( 0 - $cw/2, 0 - $ch/2); # $canvas->scroll_to( $cx - $cw/2 ,$cy - $ch/2 ); # print $cx * $scale,' ',$cy * $scale,"\n"; # $canvas->scroll_to( $cx - $cw/2 , $cy - $ch/2 ); # $canvas->scroll_to( $cx , $cy ); $canvas->scroll_to( $cx - $cw/(2*$scale) , $cy - $ch/(2*$scal +e) ); # my $current = $ha1->get_value; # my $increment = $ha1->step_increment; # my $new = $current ;#+ $increment ; # $ha1->set_value( $new ); } # print "key was ", chr( $event->keyval ), "\n"; return 0; } sub write_pdf { #print "@_\n"; my $canvas = shift; print "Write PDF...\n"; my $scale = $canvas->get_scale; print "scale->$scale\n"; my $surface = Cairo::PdfSurface->create("$0-$scale.pdf", $scale*$cwidth, $scale*$cheight); my $cr = Cairo::Context->create($surface); # needed to save scaled version $cr->scale($scale, $scale); $canvas->render($cr, undef, 1); $cr->show_page; print "done\n"; return TRUE; } sub event_after { my ($mw, $event) = @_; # print "\t",'canvas ',$event->type,"\n"; # if( ($event->type eq 'configure') or ($event->type eq 'expose' ) ){ # $resize_flag = 1 # }else{ $resize_flag = 0 } # return FALSE if $resize_flag; # if ($manual){ $manual = 0; return FALSE} my $rect = $canvas->allocation; $cw = $rect->width; $ch = $rect->height; # print "$cw $ch\n"; # my ($x, $y) = $mw->get_size; # print "$x $y\n";; # $va1->set_value( ($vupper - $y)/2 + 5); # $ha1->set_value( ($hupper - $x)/2 + 5); #$canvas->scroll_to( 0 - $cw/2 ,0 - $ch/2 ); return FALSE; } __END__

I'm not really a human, but I play one on earth.
Old Perl Programmer Haiku

In reply to Re: Goo::Canvas zoom correction by zentara
in thread Goo::Canvas zoom correction by deadpickle

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.