#!/usr/bin/perl #Simple 2D 2Colors automaton. # # Use the TRUE and FALSE constants exported by the Glib module. use Glib qw/TRUE FALSE/; use Gtk2 '-init'; use strict; use GD; my %laws= ( "0,0,0" => 0, "0,0,0" => 0, "0,0,1" => 0, "0,1,0" => 0, "0,1,1" => 0, "1,0,0" => 0, "1,0,1" => 0, "1,1,0" => 0, "1,1,1" => 0); sub OnToggled{ my ($arg,$arg2)=@_; if ($arg->get_active){ print "activating $arg2!\n"; $laws{"0,0,0"}=1 if ($arg2=="000"); $laws{"0,0,1"}=1 if ($arg2=="001"); $laws{"0,1,0"}=1 if ($arg2=="010"); $laws{"0,1,1"}=1 if ($arg2=="011"); $laws{"1,0,0"}=1 if ($arg2=="100"); $laws{"1,0,1"}=1 if ($arg2=="101"); $laws{"1,1,0"}=1 if ($arg2=="110"); $laws{"1,1,1"}=1 if ($arg2=="111"); } else{ print "deactivating $arg2!\n"; $laws{"0,0,0"}=0 if ($arg2=="000"); $laws{"0,0,1"}=0 if ($arg2=="001"); $laws{"0,1,0"}=0 if ($arg2=="010"); $laws{"0,1,1"}=0 if ($arg2=="011"); $laws{"1,0,0"}=0 if ($arg2=="100"); $laws{"1,0,1"}=0 if ($arg2=="101"); $laws{"1,1,0"}=0 if ($arg2=="110"); $laws{"1,1,1"}=0 if ($arg2=="111"); } print "$laws{'0,0,0'} $laws{'0,0,1'} $laws{'0,1,0'} $laws{'0,1,1'} $laws{'1,0,0'} $laws{'1,0,1'} $laws{'1,1,0'} $laws{'1,1,1'}\n"; }; sub hello { my ($widget, $window) = @_; my @screen; my $height=200; my $width= 2 *$height ; my $size=2; my $min_x=$height-10; my $max_x=$height+10 ; @screen=&init ($width,$height,@screen); @screen=&docalcul (\%laws,\$min_x,\$max_x,$width,$height,@screen); &display ($size,\$min_x,\$max_x,$width,$height,@screen); } sub init { my ($width,$height,@screen)=@_; $width+=1; $height+=1; foreach my $y (0..$height){ foreach my $x (0..$width){ $screen[$x][$y]=0; } } my $mid =$width / 2; $screen[$mid][0]=1; return @screen; }; sub display { my ($size,$rminx1,$rminx2,$width,$height,@screen)=@_; # create a new image print "bornes: $$rminx1 .. $$rminx2\n"; my $im = new GD::Image(($$rminx2-$$rminx1)*$size,$height*$size); # allocate some colors my $white = $im->colorAllocate(255,255,255); my $black = $im->colorAllocate(0,0,0); foreach my $y (0..$height){ foreach my $x ($$rminx1 .. $$rminx2){ if ($screen[$x][$y]==0){ $im->filledRectangle(($$rminx1-$x)*$size,$y*$size,(1+($$rminx1-$x))*$size,(1+$y)*$size,$white); } else { $im->filledRectangle($x*$size,$y*$size,(1+$x)*$size,(1+$y)*$size,$black); } } #print "\n"; } open DISPLAY, "| display 2>/dev/null" or die "can't fork: $!"; local $SIG{PIPE} = sub { die "display pipe broke" }; binmode DISPLAY; print DISPLAY $im->png; close DISPLAY or die "bad spool: $! $?"; }; sub docalcul { my ($rlaws,$rminx,$rmaxx,$width,$height,@screen)=@_; foreach my $y (0..$height){ foreach my $x (0..$width-2){ #we don't want to overflow. my $value="$screen[$x-1][$y],$screen[$x+0][$y],$screen[$x+1][$y]"; $screen[$x+0][$y+1]=$$rlaws{$value}; $$rminx=$x if ($$rlaws{$value}==1 && $x<$$rminx); $$rmaxx=$x if ($$rlaws{$value}==1 && $x>$$rmaxx); } } return @screen; }; sub delete_event { Gtk2->main_quit; return FALSE; } sub make_box { my ($img,$window,$homogenous, $spacing, $expand, $fill, $padding) = @_; # Create a new hbox with the appropriate homogeneous and spacing settings my $box = Gtk2::HBox->new($homogenous, $spacing); my $toggle = Gtk2::CheckButton->new; #my $toggle_image = Gtk2::Image::new_from_file( "foo", "${img}.jpg") ; my $toggle_image = Gtk2::Label->new( "$img") ; my $label = Gtk2::Label->new("->"); $box->pack_start( $toggle_image, TRUE, TRUE, 0 ) ; $box->pack_start( $label, TRUE, TRUE, 0 ) ; $box->pack_start( $toggle, TRUE, TRUE, 0 ) ; $toggle->signal_connect( "toggled",\&OnToggled,"$img") ; $toggle_image->show() ; $label->show(); $toggle->show() ; return $box; } # Create our window my $window = Gtk2::Window->new('toplevel'); # connect the delete_event signal to the main window. $window->signal_connect(delete_event => \&delete_event); $window->set_border_width(10); # We create a vertical box (vbox) to pack the horizontal boxes into. my $box1 = Gtk2::VBox->new(FALSE, 0); my $which = $ARGV[0]; # create a new label. my $label = Gtk2::Label->new("Select Rules!"); $label->set_alignment(0.0, 0.0); $box1->pack_start($label, FALSE, FALSE, 0); $label->show; # Call our make box function - homogeneous = FALSE, spacing = 0, # expand = FALSE, fill = FALSE, padding = 0 foreach ( qw / 000 001 010 011 100 101 110 111 / ){ my $box2 = make_box("$_",$window,TRUE, 0, TRUE, TRUE, 0); $box1->pack_start($box2, TRUE, TRUE, 0); $box2->show; } my $separator = Gtk2::HSeparator->new; $box1->pack_start($separator, FALSE, TRUE, 5); $separator->show; $label = Gtk2::Label->new("Action!"); $label->set_alignment(0.0, 0.0); $box1->pack_start($label, FALSE, FALSE, 0); $label->show; my $quitbox = Gtk2::HBox->new(FALSE, 0); $separator = Gtk2::HSeparator->new; my $button = Gtk2::Button->new("Quit"); my $run = Gtk2::Button->new("Run"); $button->signal_connect(clicked => sub { Gtk2->main_quit; }); $run->signal_connect(clicked => \&hello, $window); $quitbox->pack_start($run, FALSE, TRUE, 0); $quitbox->pack_start($separator, FALSE, TRUE, 5); $quitbox->pack_start($button, TRUE, FALSE, 0); $separator->show; $box1->pack_start($quitbox, FALSE, FALSE, 0); $window->add($box1); # And show everything left $button->show; $run->show; $quitbox->show; $box1->show; $window->show; Gtk2->main; 0;