From: Martin Mares Date: Fri, 26 Oct 2007 18:28:21 +0000 (+0200) Subject: Initial commit X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=e802563698389820eac93f5a5f261fdf0016f5ac;p=anim.git Initial commit --- e802563698389820eac93f5a5f261fdf0016f5ac diff --git a/AA.pm b/AA.pm new file mode 100644 index 0000000..f402f41 --- /dev/null +++ b/AA.pm @@ -0,0 +1,174 @@ +package AA; + +use overload '""' => 'ID'; + +our $PI = 3.1415926535; +our $TWOPI = 2*$PI; + +our %known_objs = ( ); +our $debug = 1; +our $record_dep_obj; +our $record_dep_attr; +our $record_deps; +our @pending_recalcs; + +sub new($$) { + my ($class, $id) = @_; + my $o = { + ID => $id, + }; + !defined $known_objs{$id} or die "Object $id already defined"; + $known_objs{$id} = $o; + print "Created object $id\n" if $debug; + return bless $o, $class; +} + +sub find($$) { + my ($class, $id) = @_; + defined $known_objs{$id} or die "Object $id not known"; + return $known_objs{$id}; +} + +sub calculate($) { + my ($class) = @_; + my $o; + while ($o = shift @pending_recalcs) { + print "Going to recalculate object $o\n" if $debug; + my $pend = $o->{PENDING}; + foreach my $a (keys %$pend) { + $o->Calc("$a"); + } + delete $o->{PENDING}; + } +} + +sub draw($$) { + my ($class, $cairo) = @_; + my @q = (); + print "Redrawing the scene...\n" if $debug; + foreach my $o (values %known_objs) { + push @q, $o if defined $o->{'a:d'}; + } + foreach my $o (sort { $a->{'a:d'} <=> $b->{'a:d'} } @q) { + print "Drawing $o at depth ", $o->{'a:d'}, "\n" if $debug; + $o->Draw($cairo); + } +} + +sub ID($) { + return (shift @_)->{ID}; +} + +sub Define($$) { + my ($o, $a) = @_; + !exists $o->{"a:$a"} or die "Redefining attribute $a of object $o"; + $o->{"a:$a"} = undef; # attribute value + # $o->{"f:$a"} = undef; # binding function + $o->{"d:$a"} = { }; # depends on (obj:attr => obj) + $o->{"n:$a"} = { }; # notify (obj:attr => obj) +} + +sub DefSet($$$) { + my ($o, $a, $v) = @_; + $o->Define($a); + $o->Set($a, $v); +} + +sub DefBind($$$) { + my ($o, $a, $v) = @_; + $o->Define($a); + $o->Bind($a, $v); +} + +sub DefDep($$$$) { + my ($o, $a, $v, $b) = @_; + $o->Define($a); + $o->Bind($a, sub { $v->Get($b); }); +} + +sub Exists($$) { + my ($o, $a) = @_; + return defined $o->{"a:$a"}; +} + +sub Get($$) { + my ($o, $a) = @_; + defined $o->{"a:$a"} or die "Getting undefined attribute $a of object $o"; + if ($record_deps) { + # record the dependency + my $did = "$o:$a"; + if (!defined $record_deps->{$did}) { + $record_deps->{$did} = $o; + my $rid = "$record_dep_obj:$record_dep_attr"; + $o->{"n:$a"}->{$rid} = $record_dep_obj; + print "Added automatic dependency $rid -> $did\n" if $debug; + } + } + return $o->{"a:$a"}; +} + +sub Set($$$) { + my ($o, $a, $v) = @_; + exists $o->{"a:$a"} or die "Setting undefined attribute $a of object $o"; + print "Setting $o:$a = $v\n" if $debug; + $o->{"a:$a"} = $v; + !defined $o->{"f:$a"} or $o->UnBind($a); + $o->Notify($a); +} + +sub Bind($$$) { + my ($o, $a, $f) = @_; + exists $o->{"a:$a"} or die "Binding undefined attribute $a of object $o"; + print "Binding $o:$a\n" if $debug; + $o->UnBind($a); + $o->{"f:$a"} = $f; + $o->Calc($a); +} + +sub Calc($$) { + my ($o, $a) = @_; + die if $record_deps; + $record_deps = $o->{"d:$a"}; + $record_dep_obj = $o; + $record_dep_attr = $a; + + $o->{"a:$a"} = undef; + $o->{"a:$a"} = &{$o->{"f:$a"}} ($o); + + $record_deps = undef; + $record_dep_obj = undef; + $record_dep_attr = undef; + + print "Recalculated $o:$a = ", $o->{"a:$a"}, "\n" if $debug; + $o->Notify($a); +} + +sub UnBind($$) { + my ($o, $a) = @_; + my $aid = "$o:$a"; + foreach my $dep (keys %{$o->{"d:$a"}}) { + my ($deponame, $depa) = split(/:/, $dep); + my $depo = $o->{"d:$a"}->{$dep}; + delete $depo->{"n:$depa"}->{$aid}; + print "Removed notify $aid -> $depo:$depa\n" if $debug; + } + $o->{"d:$a"} = { }; + delete $o->{"f:$a"}; +} + +sub Notify($$) { + my ($o, $a) = @_; + foreach my $dep (keys %{$o->{"n:$a"}}) { + my ($deponame, $depa) = split(/:/, $dep); + my $depo = $o->{"n:$a"}->{$dep}; + print "Sending notify $o:$a -> $deponame:$depa\n" if $debug; + if (!defined $depo->{PENDING}) { + $depo->{PENDING} = { }; + push @pending_recalcs, $depo; + print "\tPending object $deponame\n" if $debug; + } + $depo->{PENDING}->{$depa} = 1; + } +} + +1; diff --git a/AA/Graph.pm b/AA/Graph.pm new file mode 100644 index 0000000..4621062 --- /dev/null +++ b/AA/Graph.pm @@ -0,0 +1,127 @@ +package AA::Vertex; + +our @ISA = ('AA'); + +sub new($$) { + my ($class, $id) = @_; + my $v = AA::new($class, $id); + $v->DefSet('x', 100); + $v->DefSet('y', 100); + $v->DefSet('color', [ 0.7, 0, 0.7 ]); + $v->DefSet('gradient', 0.5); + $v->DefSet('r', 30); + $v->DefSet('rim', 2); + $v->DefSet('rim-color', [ 1, 1, 1 ]); + $v->Define('label'); + $v->DefSet('label-color', [ 1, 1, 1 ]); + $v->DefSet('label-size', 1.5); + $v->DefSet('d', 20); + return $v; +} + +sub Draw($$) { + my ($v, $cairo) = @_; + my ($x, $y, $r) = ($v->Get('x'), $v->Get('y'), $v->Get('r')); + my $grad = $v->Get('gradient'); + my @col = @{$v->Get('color')}; + + $cairo->arc($x, $y, $r, 0, $AA::TWOPI); + if ($grad) { + my $lg = Cairo::RadialGradient->create($x, $y, 0, $x, $y, $r); + $lg->add_color_stop_rgb(0, @col); + $col[0] *= $grad; + $col[1] *= $grad; + $col[2] *= $grad; + $lg->add_color_stop_rgb(1, @col); + $cairo->set_source($lg); + } else { + $cairo->set_source_rgb(@col); + } + $cairo->fill; + + $cairo->arc($x, $y, $r, 0, $AA::TWOPI); + $cairo->set_source_rgb(@{$v->Get('rim-color')}); + $cairo->set_line_width($v->Get('rim')); + $cairo->stroke; + + if ($v->Exists('label')) { + my $label = $v->Get('label'); + $cairo->set_source_rgb(@{$v->Get('label-color')}); + $cairo->set_font_size($r * $v->Get('label-size')); + my $xt = $cairo->text_extents($label); + $cairo->move_to($x - $xt->{'width'}/2 - $xt->{'x_bearing'}, + $y - $xt->{'height'}/2 - $xt->{'y_bearing'}); + $cairo->show_text($label); + } +} + +package AA::Edge; + +our @ISA = ('AA'); + +sub new($$$$) { + my ($class, $id, $v, $w) = @_; + my $e = AA::new($class, $id); + $e->DefSet('color', [1, 1, 1]); + $e->DefSet('width', 3); + $e->DefSet('arrow', 0); + $e->DefSet('arrow-dist', 20); + $e->DefSet('arrow-span', 6); + $e->DefBind('ends', sub { + my $x1 = $v->Get('x'); + my $y1 = $v->Get('y'); + my $r1 = $v->Get('r'); + my $x2 = $w->Get('x'); + my $y2 = $w->Get('y'); + my $r2 = $w->Get('r'); + my $dx = $x2 - $x1; + my $dy = $y2 - $y1; + my $d = sqrt($dx*$dx + $dy*$dy); + $x1 += $dx * $r1/$d; + $y1 += $dy * $r1/$d; + $x2 -= $dx * $r2/$d; + $y2 -= $dy * $r2/$d; + return [ $x1, $y1, $x2, $y2 ]; + }); + $e->DefBind('apos', sub { + my $type = $e->Get('arrow') or return undef; + my $span = $e->Get('arrow-span'); + my $dist = $e->Get('arrow-dist'); + my ($x1, $y1, $x2, $y2) = @{$e->Get('ends')}; + my $dx = $x2 - $x1; + my $dy = $y2 - $y1; + my $d = sqrt($dx*$dx + $dy*$dy); + my $ax = $x2 - $dx * $dist/$d; + my $ay = $y2 - $dy * $dist/$d; + my $adx = -$dy; + my $ady = $dx; + ($adx, $ady) = ($adx * $span/$d, $ady * $span/$d); + return [ $ax+$adx, $ay+$ady, + $ax-$adx, $ay-$ady ]; + }); + $e->DefSet('d', 10); + return $e; +} + +sub Draw($$) { + my ($v, $cairo) = @_; + + my ($x1, $y1, $x2, $y2) = @{$v->Get('ends')}; + $cairo->set_source_rgb(@{$v->Get('color')}); + + $cairo->move_to($x1, $y1); + $cairo->line_to($x2, $y2); + $cairo->set_line_width($v->Get('width')); + $cairo->stroke; + + if ($v->Get('arrow')) { + my ($ax1, $ay1, $ax2, $ay2) = @{$v->Get('apos')}; + $cairo->move_to($x2, $y2); + $cairo->line_to($ax1, $ay1); + $cairo->line_to($ax2, $ay2); + $cairo->close_path; + $cairo->fill; + } +} + +1; diff --git a/AA/Net.pm b/AA/Net.pm new file mode 100644 index 0000000..9c06d42 --- /dev/null +++ b/AA/Net.pm @@ -0,0 +1,15 @@ +package AA::NetV; + +our @ISA = ('AA::Vertex'); + +sub new($$$$) { + my ($class, $id) = @_; + my $v = AA::Vertex::new($class, $id); + $v->Set('x', 100); + $v->DefSet('y0', 100); + $v->DefSet('h', 0); + $v->Bind('y', sub { $v->Get("y0") + 100*$v->Get("h") }); + return $v; +} + +1; diff --git a/a.pl b/a.pl new file mode 100755 index 0000000..3c87c91 --- /dev/null +++ b/a.pl @@ -0,0 +1,116 @@ +#!/usr/bin/perl -W + +use strict; +use warnings; + +use Gtk2 -init; +use Cairo; + +use AA; +use AA::Graph; +use AA::Net; + +my $v = AA::NetV->new('v'); +$v->Set('x', 100); +$v->Set('y0', 100); +$v->Set('label', '1'); + +my $w = AA::NetV->new('w'); +$w->Set('x', 200); +$w->Set('y0', 100); +$w->Set('label', '2'); + +my $e = AA::Edge->new('e', $v, $w); +$e->Set('arrow', 1); + +$v->Set("h", 1); +$w->Set("h", 2); + +AA->calculate; + +### G T K ### + +my $area = Gtk2::DrawingArea->new(); +my $cairo; + +my $pixmap; +my ($lastw, $lasth, $lastd) = (-1, -1, -1); +my ($pixw, $pixh) = (-1, -1); +sub draw($) { + my ($force) = @_; + my $win = $area->window; + my $wgc = Gtk2::Gdk::GC->new($win); + my $alloc = $area->allocation; + my $w = $alloc->width; + my $h = $alloc->height; + my $d = $win->get_depth; + # print "Area $w x $h x $d, xx=$xx\n"; + + if (!defined($pixmap) || $lastw != $w || $lasth != $h || $lastd != $d) { + ($lastw, $lasth, $lastd) = ($w, $h, $d); + if ($w/$h >= 4/3) { + $pixh = $h; + $pixw = int($h/3*4); + } else { + $pixw = $w; + $pixh = int($w/4*3); + } + print "Resized to ${w}x${h}, pixmap size ${pixw}x${pixh}\n"; + + $pixmap = Gtk2::Gdk::Pixmap->new($win, $pixw, $pixh, $d); + $cairo = Gtk2::Gdk::Cairo::Context->create($pixmap); + $cairo->select_font_face('URW Palladio L', 'normal', 'normal'); + my $scale = $pixw/1024; + $cairo->scale($scale, $scale); + } + + if ($force) { + $wgc->set_rgb_background(0); + $wgc->set_rgb_foreground(0); + $win->draw_rectangle($wgc, 1, 0, 0, $w, $h); + } + + $cairo->rectangle(0, 0, 1024, 768); + $cairo->set_source_rgb(0, 0, 0); + $cairo->fill; + + AA->draw($cairo); + + $win->draw_drawable($wgc, $pixmap, 0, 0, 0, 0, $pixw, $pixh); +} + +sub step() { + draw(0); +} + +my $timer = 1; +my $stopped = 1; +$area->signal_connect("expose-event" => sub { + draw(1); + if (!defined $timer) { + $timer = Glib::Timeout->add(30, sub { $stopped || step(); return 1; }); + } +}); +$area->set_flags('can-focus'); +# $area->add_events('key-press-mask'); +$area->signal_connect('key-press-event' => sub { + my ($w, $evt) = @_; + my $k = Gtk2::Gdk::keyval_name(0, $evt->keyval); + print "Pressed key $k\n"; + if ($k eq "Escape") { + Gtk2->main_quit; + } elsif ($k eq "space") { + $stopped = !$stopped; + } +}); + +my $window = Gtk2::Window->new ('toplevel'); +$window->signal_connect ("delete-event" => sub { Gtk2->main_quit }); +$window->set_title("Brum"); +$window->set_wmclass("brum", "Brum"); +$window->set_default_size(640, 480); +$window->add ($area); +$window->show_all; +#$window->fullscreen; + +Gtk2->main; diff --git a/cairotest.pl b/cairotest.pl new file mode 100755 index 0000000..2ea7766 --- /dev/null +++ b/cairotest.pl @@ -0,0 +1,53 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Gtk2 -init; +use Cairo; + +my $area = Gtk2::DrawingArea->new(); +my $cairo; +my $xx=0; +sub draw() { + my $win = $area->window; + my $alloc = $area->allocation; + my $w = $alloc->width; + my $h = $alloc->height; + print "Area $w x $h, xx=$xx\n"; + + $cairo = Gtk2::Gdk::Cairo::Context->create($win); + $cairo->rectangle(0, 0, $w, $h); + $cairo->set_source_rgb(0, 0, 0); + $cairo->fill; + + $cairo->rectangle($xx, 10, 40, 40); + $cairo->set_source_rgb(0, 0, 1); + $cairo->fill; + + my $gc = Gtk2::Gdk::GC->new($win); + $gc->set_rgb_background(0x000000); + $gc->set_rgb_foreground(0x00ff00); + $win->draw_line($gc, $xx, 0, $w-1, $h-1); + + $xx+=5; +} + +my $timer; +$area->signal_connect("expose-event" => sub { + draw(); + if (!defined $timer) { + $timer = Glib::Timeout->add(10, sub { draw(); return 1; }); + } +}); + +my $window = Gtk2::Window->new ('toplevel'); +$window->signal_connect ("delete-event" => sub { Gtk2->main_quit }); +$window->set_title("Brum"); +$window->set_wmclass("anim", "Anim"); +$window->set_default_size(640, 480); +$window->add ($area); +$window->show_all; +$window->fullscreen; + +Gtk2->main; diff --git a/gdktest.pl b/gdktest.pl new file mode 100755 index 0000000..2ec701b --- /dev/null +++ b/gdktest.pl @@ -0,0 +1,46 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Gtk2 -init; + +my $area = Gtk2::DrawingArea->new(); +my $xx = 0; +sub draw() { + my $win = $area->window; + my $alloc = $area->allocation; + my $w = $alloc->width; + my $h = $alloc->height; + print "Area $w x $h\n"; + + ## my $sty = $area->style; + ## my $gc = $sty->fg_gc($area->state); + my $gc = Gtk2::Gdk::GC->new($win); + $gc->set_rgb_background(0x000000); + $gc->set_rgb_foreground(0x000000); + $win->draw_rectangle($gc, 1, 0, 0, $w, $h); + $gc->set_rgb_foreground(0x00ff00); + $win->draw_line($gc, $xx, 0, $w-1, $h-1); + $xx++; + if ($xx >= $w) { $xx=0; } +} + +my $timer; +$area->signal_connect("expose-event" => sub { + draw(); + if (!defined $timer) { + $timer = Glib::Timeout->add(10, sub { draw(); return 1; }); + } +}); + +my $window = Gtk2::Window->new ('toplevel'); +$window->signal_connect ("delete-event" => sub { Gtk2->main_quit }); +$window->set_title("Brum"); +$window->set_wmclass("anim", "Anim"); +$window->set_default_size(640, 480); +$window->add ($area); +$window->show_all; +#$window->fullscreen; + +Gtk2->main; diff --git a/test.pl b/test.pl new file mode 100755 index 0000000..2390174 --- /dev/null +++ b/test.pl @@ -0,0 +1,169 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Gtk2 -init; +use Cairo; + +my $area = Gtk2::DrawingArea->new(); +my $cairo; +my $PI = 3.1415926535; +my $TWOPI = 2*$PI; + +my $rad = 30; +my $rim = 2; +my $arrow_dist = 10; +my $arrow_span = 5; + +sub draw_vertex($$) { + my ($x, $y) = @_; + + my $lg = Cairo::RadialGradient->create($x, $y, 0, $x, $y, $rad); + $lg->add_color_stop_rgb(0, 0.7, 0, 0.7); + $lg->add_color_stop_rgb(1, 0.3, 0, 0.3); + + $cairo->arc($x, $y, $rad, 0, $TWOPI); + $cairo->set_source($lg); + $cairo->fill; + + $cairo->arc($x, $y, $rad, 0, $TWOPI); + $cairo->set_source_rgb(1, 1, 1); + $cairo->set_line_width($rim); + $cairo->stroke; + + $cairo->set_font_size(0.6*$rad); + my $xt = $cairo->text_extents('Brum'); + $cairo->move_to($x - $xt->{'width'}/2 - $xt->{'x_bearing'}, + $y - $xt->{'height'}/2 - $xt->{'y_bearing'}); + $cairo->show_text("Brum"); +} + +sub draw_edge($$$$) { + my ($x1, $y1, $x2, $y2) = @_; + my $dx = $x2 - $x1; + my $dy = $y2 - $y1; + my $d = sqrt($dx*$dx + $dy*$dy); + + $x1 += $dx * $rad/$d; + $y1 += $dy * $rad/$d; + $x2 -= $dx * $rad/$d; + $y2 -= $dy * $rad/$d; + + $cairo->set_source_rgb(1, 1, 1); + + $cairo->move_to($x1, $y1); + $cairo->line_to($x2, $y2); + $cairo->set_line_width(2); + $cairo->stroke; + + my $ax = $x2 - $dx * $arrow_dist/$d; + my $ay = $y2 - $dy * $arrow_dist/$d; + my $adx = -$dy; + my $ady = $dx; + ($adx, $ady) = ($adx * $arrow_span/$d, $ady * $arrow_span/$d); + $cairo->move_to($x2, $y2); + $cairo->line_to($ax+$adx, $ay+$ady); + $cairo->line_to($ax-$adx, $ay-$ady); + $cairo->close_path; + $cairo->fill; +} + +my $xx=0; +my $pixmap; +my ($lastw, $lasth, $lastd) = (-1, -1, -1); +my ($pixw, $pixh) = (-1, -1); +sub draw($) { + my ($force) = @_; + my $win = $area->window; + my $wgc = Gtk2::Gdk::GC->new($win); + my $alloc = $area->allocation; + my $w = $alloc->width; + my $h = $alloc->height; + my $d = $win->get_depth; + # print "Area $w x $h x $d, xx=$xx\n"; + + if (!defined($pixmap) || $lastw != $w || $lasth != $h || $lastd != $d) { + ($lastw, $lasth, $lastd) = ($w, $h, $d); + if ($w/$h >= 4/3) { + $pixh = $h; + $pixw = int($h/3*4); + } else { + $pixw = $w; + $pixh = int($w/4*3); + } + print "Resized to ${w}x${h}, pixmap size ${pixw}x${pixh}\n"; + + $pixmap = Gtk2::Gdk::Pixmap->new($win, $pixw, $pixh, $d); + $cairo = Gtk2::Gdk::Cairo::Context->create($pixmap); + $cairo->select_font_face('URW Palladio L', 'normal', 'normal'); + my $scale = $pixw/1024; + $cairo->scale($scale, $scale); + } + + if ($force) { + $wgc->set_rgb_background(0); + $wgc->set_rgb_foreground(0); + $win->draw_rectangle($wgc, 1, 0, 0, $w, $h); + } + + $cairo->rectangle(0, 0, 1024, 768); + $cairo->set_source_rgb(0, 0, 0); + $cairo->fill; + + my @v = (); + for (my $i=0; $i<6; $i++) { + my $a = $TWOPI/6 * $i + $TWOPI/400*$xx; + my $x = int(1024/2 + 300*cos($a)); + my $y = int(768/2 + 300*sin($a)); + draw_vertex($x, $y); + push @v, { 'x' => $x, 'y' => $y }; + } + + for (my $i=1; $i<6; $i++) { + for (my $j=0; $j<$i; $j++) { + my $v = $v[$i]; + my $w = $v[$j]; + draw_edge($v->{'x'}, $v->{'y'}, $w->{'x'}, $w->{'y'}); + } + } + + $win->draw_drawable($wgc, $pixmap, 0, 0, 0, 0, $pixw, $pixh); +} + +sub step() { + draw(0); + $xx++; +} + +my $timer; +my $stopped = 0; +$area->signal_connect("expose-event" => sub { + draw(1); + if (!defined $timer) { + $timer = Glib::Timeout->add(30, sub { $stopped || step(); return 1; }); + } +}); +$area->set_flags('can-focus'); +# $area->add_events('key-press-mask'); +$area->signal_connect('key-press-event' => sub { + my ($w, $evt) = @_; + my $k = Gtk2::Gdk::keyval_name(0, $evt->keyval); + print "Pressed key $k\n"; + if ($k eq "Escape") { + Gtk2->main_quit; + } elsif ($k eq "space") { + $stopped = !$stopped; + } +}); + +my $window = Gtk2::Window->new ('toplevel'); +$window->signal_connect ("delete-event" => sub { Gtk2->main_quit }); +$window->set_title("Brum"); +$window->set_wmclass("anim", "Anim"); +$window->set_default_size(640, 480); +$window->add ($area); +$window->show_all; +#$window->fullscreen; + +Gtk2->main; diff --git a/test0.pl b/test0.pl new file mode 100755 index 0000000..3b634d5 --- /dev/null +++ b/test0.pl @@ -0,0 +1,74 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Gtk2 -init; +use Cairo; + +my $area = Gtk2::DrawingArea->new(); +my $cairo; +my $xx=0; +my $pixmap; +my ($pixw, $pixh, $pixd) = (-1, -1, -1); +sub draw() { + my $win = $area->window; + my $alloc = $area->allocation; + my $w = $alloc->width; + my $h = $alloc->height; + my $d = $win->get_depth; + # print "Area $w x $h x $d, xx=$xx\n"; + + if (!defined($pixmap) || $pixw != $w || $pixh != $h || $pixd != $d) { + $pixmap = Gtk2::Gdk::Pixmap->new($win, $w, $h, $d); + ($pixw, $pixh, $pixd) = ($w, $h, $d); + $cairo = Gtk2::Gdk::Cairo::Context->create($pixmap); + } + + $cairo->rectangle(0, 0, $w, $h); + $cairo->set_source_rgb(0, 0, 0); + $cairo->fill; + + $cairo->rectangle($xx, 10, 40, 40); + $cairo->set_source_rgb(0, 0, 1); + $cairo->fill; + + #my $gc = Gtk2::Gdk::GC->new($pixmap); + #$gc->set_rgb_background(0x000000); + #$gc->set_rgb_foreground(0x00ff00); + #$pixmap->draw_line($gc, $xx, 0, $w-1, $h-1); + + my $wgc = Gtk2::Gdk::GC->new($win); + $win->draw_drawable($wgc, $pixmap, 0, 0, 0, 0, $w, $h); + + $xx+=1; +} + +my $timer; +$area->signal_connect("expose-event" => sub { + draw(); + if (!defined $timer) { + $timer = Glib::Timeout->add(10, sub { draw(); return 1; }); + } +}); +$area->set_flags('can-focus'); +# $area->add_events('key-press-mask'); +$area->signal_connect('key-press-event' => sub { + my ($w, $evt) = @_; + my $k = Gtk2::Gdk::keyval_name(0, $evt->keyval); + print "Pressed key $k\n"; + if ($k eq "Escape") { + Gtk2->main_quit; + } +}); + +my $window = Gtk2::Window->new ('toplevel'); +$window->signal_connect ("delete-event" => sub { Gtk2->main_quit }); +$window->set_title("Brum"); +$window->set_wmclass("anim", "Anim"); +$window->set_default_size(640, 480); +$window->add ($area); +$window->show_all; +$window->fullscreen; + +Gtk2->main; diff --git a/test1.pl b/test1.pl new file mode 100755 index 0000000..5502883 --- /dev/null +++ b/test1.pl @@ -0,0 +1,119 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Gtk2 -init; +use Cairo; + +my $area = Gtk2::DrawingArea->new(); +my $cairo; + +sub draw_vertex($$) { + my ($x, $y) = @_; + my $rad = 100; + my $rim = 3; + + my $lg = Cairo::RadialGradient->create($x, $y, 0, $x, $y, $rad); + $lg->add_color_stop_rgb(0, 0.7, 0, 0.7); + $lg->add_color_stop_rgb(1, 0.3, 0, 0.3); + + $cairo->arc($x, $y, $rad, 0, 2*3.141592); + $cairo->set_source($lg); + $cairo->fill; + + $cairo->arc($x, $y, $rad, 0, 2*3.141592); + $cairo->set_source_rgb(1, 1, 1); + $cairo->set_line_width($rim); + $cairo->stroke; + + $cairo->set_font_size(0.6*$rad); + my $xt = $cairo->text_extents('Brum'); + $cairo->move_to($x - $xt->{'width'}/2 - $xt->{'x_bearing'}, + $y - $xt->{'height'}/2 - $xt->{'y_bearing'}); + $cairo->show_text("Brum"); +} + +my $xx=0; +my $pixmap; +my ($lastw, $lasth, $lastd) = (-1, -1, -1); +my ($pixw, $pixh) = (-1, -1); +sub draw($) { + my ($force) = @_; + my $win = $area->window; + my $wgc = Gtk2::Gdk::GC->new($win); + my $alloc = $area->allocation; + my $w = $alloc->width; + my $h = $alloc->height; + my $d = $win->get_depth; + # print "Area $w x $h x $d, xx=$xx\n"; + + if (!defined($pixmap) || $lastw != $w || $lasth != $h || $lastd != $d) { + ($lastw, $lasth, $lastd) = ($w, $h, $d); + if ($w/$h >= 4/3) { + $pixh = $h; + $pixw = int($h/3*4); + } else { + $pixw = $w; + $pixh = int($w/4*3); + } + print "Resized to ${w}x${h}, pixmap size ${pixw}x${pixh}\n"; + + if ($force) { + $wgc->set_rgb_background(0); + $wgc->set_rgb_foreground(0); + $win->draw_rectangle($wgc, 1, 0, 0, $w, $h); + } + + $pixmap = Gtk2::Gdk::Pixmap->new($win, $pixw, $pixh, $d); + $cairo = Gtk2::Gdk::Cairo::Context->create($pixmap); + $cairo->select_font_face('URW Palladio L', 'normal', 'normal'); + my $scale = $pixw/1024; + $cairo->scale($scale, $scale); + } + + $cairo->rectangle(0, 0, 1024, 768); + $cairo->set_source_rgb(0, 0, 0); + $cairo->fill; + + draw_vertex(4/3*$xx, $xx); + + $win->draw_drawable($wgc, $pixmap, 0, 0, 0, 0, $pixw, $pixh); +} + +sub step() { + draw(0); + $xx++; +} + +my $timer; +my $stopped = 0; +$area->signal_connect("expose-event" => sub { + draw(1); + if (!defined $timer) { + $timer = Glib::Timeout->add(100, sub { $stopped || step(); return 1; }); + } +}); +$area->set_flags('can-focus'); +# $area->add_events('key-press-mask'); +$area->signal_connect('key-press-event' => sub { + my ($w, $evt) = @_; + my $k = Gtk2::Gdk::keyval_name(0, $evt->keyval); + print "Pressed key $k\n"; + if ($k eq "Escape") { + Gtk2->main_quit; + } elsif ($k eq "space") { + $stopped = !$stopped; + } +}); + +my $window = Gtk2::Window->new ('toplevel'); +$window->signal_connect ("delete-event" => sub { Gtk2->main_quit }); +$window->set_title("Brum"); +$window->set_wmclass("anim", "Anim"); +$window->set_default_size(640, 480); +$window->add ($area); +$window->show_all; +#$window->fullscreen; + +Gtk2->main;