#!/usr/bin/perl -w
use strict;
use warnings;
use Goo::Canvas;
use Gtk2 '-init';
use Glib qw(TRUE FALSE);
use Gtk2::Gdk::Keysyms;
my $scale = 1;
my $window = Gtk2::Window->new('toplevel');
$window->signal_connect('delete_event' => sub { Gtk2->main_quit; });
$window->set_size_request(800, 600);
my $swin = Gtk2::ScrolledWindow->new;
$swin->set_shadow_type('in');
$window->add($swin);
my ($cwidth,$cheight)= (1200,1200);
my $canvas = Goo::Canvas->new();
$canvas->set_size_request(800, 650);
$canvas->set_bounds(0, 0, $cwidth, $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 normal cartesian
$g->translate(0 + $margin_x, -1200 + $margin_y); #notice translations are reversed
$canvas->scroll_to(0,$cheight);
# add a background rect filling $g, so button press will be detected
# otherwise $g will be invisible to button-press-event
my $rect = Goo::Canvas::Rect->new(
$g, 0, 0, $cwidth,$cheight,
'line-width' => 1,
'stroke-color' => 'white', #invisible on white bg
'fill-color' => 'white', # must be filled for mouse event sensitivity
);
# some key help
my $markup = " Keys: 'Z' zoom in, 'z' zoom out, 's' save a PDF ";
my $text = Goo::Canvas::Text->new(
$g,
$markup,
-80 , 80 , -1,
'w',
'use markup' => 1,
);
$text->scale(1,-1);
$g->signal_connect('button-press-event',
\&on_g_button_press);
$canvas->signal_connect_after('key_press_event', \&on_key_press);
$canvas->can_focus(TRUE);
$canvas->grab_focus($root);
&set_axis();
&plot();
$window->show_all();
Gtk2->main;
sub set_axis{
# x axis
my $xline = Goo::Canvas::Polyline->new(
$g, TRUE,
[0,0,900,0],
'stroke-color' => 'black',
'line-width' => 3,
);
#label
my $markup = " X axis Label ";
my $text = Goo::Canvas::Text->new(
$g,
$markup,
450 , 80 , -1,
'center',
'use markup' => 1,
);
$text->scale(1,-1);
for my $x (0..900){
if ($x % 100 == 0){
my $xtick = Goo::Canvas::Polyline->new(
$g, TRUE,
[$x,0,$x,-25],
'stroke-color' => 'black',
'line-width' => 3,
);
$markup = " $x ";
$text = Goo::Canvas::Text->new(
$g,
$markup,
$x-1 , 10 , 1,
'north-east',
'use markup' => 1,
'wrap' => 'char');
$text->scale(1,-1);
}elsif ($x % 10 == 0){
my $xtick = Goo::Canvas::Polyline->new(
$g, TRUE,
[$x,0,$x,-15],
'stroke-color' => 'red',
'line-width' => 1,
);
my $markup = " $x ";
my $text = Goo::Canvas::Text->new(
$g,
$markup,
$x-1 , 6 , 1,
'north-east',
'use markup' => 1,
'wrap' => 'char');
$text->scale(1,-1);
}
}
# y axis
my $yline = Goo::Canvas::Polyline->new(
$g, TRUE,
[0,0,0,900],
'stroke-color' => 'black',
'line-width' => 3,
);
#label
$markup = " Y axis Label ";
$text = Goo::Canvas::Text->new(
$g,
$markup,
-70 ,-450 , -1,
'center',
'use markup' => 1,
);
$text->scale(1,-1);
$text->rotate(-90,-70,-450);
for my $y (0..900){
if ($y % 100 == 0){
my $ytick = Goo::Canvas::Polyline->new(
$g, TRUE,
[0,$y,-25,$y],
'stroke-color' => 'black',
'line-width' => 3,
);
$markup = " $y ";
$text = Goo::Canvas::Text->new(
$g,
$markup,
-25 , -$y -8 , -1,
'north-east',
'use markup' => 1,
);
$text->scale(1,-1);
}elsif ($y % 10 == 0){
my $ytick = Goo::Canvas::Polyline->new(
$g, TRUE,
[0,$y,-15,$y],
'stroke-color' => 'red',
'line-width' => 1,
);
my $markup = " $y ";
my $text = Goo::Canvas::Text->new(
$g,
$markup,
-16 , -$y - 6 , -1,
'north-east',
'use markup' => 1,
);
$text->scale(1,-1);
}
}
}
sub plot{
my @points;
for my $x (0..900){
push @points,$x, 300 + 100*sin( $x /5);
}
my $poly = Goo::Canvas::Polyline->new(
$g, FALSE,
\@points,
'stroke-color' => 'green',
'line-width' => 2,
);
}
sub on_g_button_press {
#print "@_\n";
my ( $group, $widget, $event ) = @_;
print $widget ,' ',$event->type, ' ','button',' ',$event->button,"\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);
$canvas->scroll_to(0,$cheight);
}
if ( $event->keyval == $Gtk2::Gdk::Keysyms{z} ) {
$scale -= .1;
$canvas->set_scale($scale);
$canvas->set_scale($scale);
$canvas->scroll_to(0,$cheight);
}
if ( $event->keyval == $Gtk2::Gdk::Keysyms{s} ) {
write_pdf($canvas);
}
# 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;
}
__END__