App-GUI-Cellgraph

 view release on metacpan or  search on metacpan

lib/App/GUI/Cellgraph.pm  view on Meta::CPAN

This graphical application uses cellular automata logic, as described in
I<Steve Wolfram>s book  I<"A new kind of science">, to paint tiled pictures.
Although, the original concept got expanded by many additional options
and functionalities.

It is meant for B<fun>, leasure, B<beautiful>, personalized images
and a deeper B<understanding> about how cellular automatons work.


=for HTML <p>
<img src="https://raw.githubusercontent.com/lichtkind/App-GUI-Cellgraph/main/example/POD/30.png"      alt=""  width="300" height="300">
<img src="https://raw.githubusercontent.com/lichtkind/App-GUI-Cellgraph/main/example/POD/blauberg.png"alt=""  width="300" height="300">
<img src="https://raw.githubusercontent.com/lichtkind/App-GUI-Cellgraph/main/example/POD/7io.png"     alt=""  width="300" height="300">
<img src="https://raw.githubusercontent.com/lichtkind/App-GUI-Cellgraph/main/example/POD/teppich2.png"alt=""  width="300" height="300">
<img src="https://raw.githubusercontent.com/lichtkind/App-GUI-Cellgraph/main/example/POD/igt.png"    alt=""  width="300" height="300">
<img src="https://raw.githubusercontent.com/lichtkind/App-GUI-Cellgraph/main/example/POD/cascadestar.png"    alt=""  width="300" height="300">
</p>


=head1 Mechanics

Every tile (square) in the picture represents one automaton (called B<cell>).
The tile color depicts the state of that cell. The B<state> is just an one
digit B<number> (0 or 1 at start). To see and change which B<color> stands
for which state - choose the rightmost tab titled "I<Colors>". The uppermost
row of the picture represents a row of automata in its initial state,

lib/App/GUI/Cellgraph.pm  view on Meta::CPAN

picture is computed. Please note there the tabs, in the top row.
They select which page of settings is visible.

Please mind the tool tips - short help texts which appear if the mouse
stands still over a button. Also helpful are messages in the status bar
at the bottom that appear while browsing the menu of after a command given.

=head2 General Settings

=for HTML <p>
<img src="https://raw.githubusercontent.com/lichtkind/App-GUI-Cellgraph/main/example/POD/GUIglobal7.png"   alt="" width="85%" height="85%">
</p>

The first tab contains settings, that shape the drawing in the most broad way.
It is segmented into three parts that somewhat parallel the last three tabs.

The topmost section sets the framework for rules by which the cell state
changes - computation round by computation round. B<Input Size> appoints
the size of neighbourhood, the left side of an subrule. If you set it to
an odd number like 5, then the cells current state plus its two neighbours
on each side determine the next state of a cell. But if you set it to an

lib/App/GUI/Cellgraph.pm  view on Meta::CPAN

offers three options: I<lines>, I<gaps> and I<no>. The first (default)
option draws thin grey lines between the cells. These lines are white if
I<gaps> is chosen. And there will be I<no> gaps between the tiles if
that option is selected . And B<Cell Size> simply defines how many pixel
a tile edge is long.


=head2 Starting Row

=for HTML <p>
<img src="https://raw.githubusercontent.com/lichtkind/App-GUI-Cellgraph/main/example/POD/GUIstart6.png" alt="" width="85%" height="85%">
</p>

This tab contains settings that define the start values - the states
and activity values of all cells in the starting row. The upper part is
about the cell states and the lower part about the activity values.
Since both parts parallel each other, lets explain them in one go.


Central in the upper and lower part are 20 cells that change their state
by left or right clicking on them. You either cycle that way through the

lib/App/GUI/Cellgraph.pm  view on Meta::CPAN

row values. The B<1> always (also in other panels) resets the default values.
And B<?> always triggers a random value generator on all cells for happy
accidents. In addition to that there are also the buttons with arrows on it.
They just the summary value up or down, in order to give you the next or
previous start configuration.


=head2 State Rules

=for HTML <p>
<img src="https://raw.githubusercontent.com/lichtkind/App-GUI-Cellgraph/main/example/POD/GUIrules7.png" alt="" width="85%" height="85%">
</p>

This tab contains settings that define the transfer function of cell states.
The upper part is very similar to the previous tab containing a summary
value and several buttons that trigger complex changes. Below that is a
list of all distinct subrules (please check the second paragraph in chapter
about the "general settings" tab). On the right side of each arrow is
one cell. By clicking in with left or right you cycle through its states.
This way you change the result of that subrule. If you see that subrules
are missing, please use the scrollwheel on you mouse or the scrollbar on

lib/App/GUI/Cellgraph.pm  view on Meta::CPAN

This will only have an effect, when state rule selection (second row in the
general settings) is set to "I<all>". And lastly the B<!> button inverts
every subrule result. If a cell can have 5 states (0..4) and the current
subrule result is 1, it will then switch to 3, since 4 - 1 = 3. 4 woud
switch to zero and a state of 2 would not change because 4 - 2 = 2.


=head2 Action Rules

=for HTML <p>
<img src="https://raw.githubusercontent.com/lichtkind/App-GUI-Cellgraph/main/example/POD/GUIaction7.png" alt="" width="85%" height="85%">
</p>

This tab parallels the previous even more, by also listing all subrules.
But here you can dial in the consequent activity value gain (right beside
the => arrow) and activity value gain spread of each subrule (rightmost
in each subrul row). The logic behind the activity values and their
changes is explained in detail in the third paragraph in the chapter
about the "I<General Settings>" tab.

Since both type of values are different they have their own summary

lib/App/GUI/Cellgraph.pm  view on Meta::CPAN

sets all values to the one present in the first subrule. B<+> and B<->
lets you increase and decrease all values at once. B</> lets all
values move toward zero and B<*> away from zero. B<%> increases the values
in odd numbered subrules and decreases them in even numbered. And
on the left of ? is the B<~> button that changes all values with a small,
random amount.

=head2 Colors

=for HTML <p>
<img src="https://raw.githubusercontent.com/lichtkind/App-GUI-Cellgraph/main/example/POD/GUIcolor7.png" alt="" width="85%" height="85%">
</p>

This panel helps you to customize the automaton/cell state colors, with
which the picture is drawn. It helps you also to remember you favorite
colors and color sets. The panel is divided into five sections by
horizontal lines. The following paragraphs will describe them from top
to bottom.

The first section is for storing and loading complete sets of state colors.
Just select a set you want to load either in the drop down menu or by

lib/App/GUI/Cellgraph/Config/Default.pm  view on Meta::CPAN


# default configuration of the app

package App::GUI::Cellgraph::Config::Default;
use v5.12;

our $data = {
    file_base_dir => '~',
    file_base_ending => 'png',
    image_size => 700,
    open_dir => '~',
    save_dir => '~',
    write_dir => '~',
    last_settings => [],
    color_set => {
        grey   => [ '#FFF',  '#DDD',   '#BBB',   '#999',   '#777',   '#555',    '#333',    '#111', 'black' ],
        basic  => [ 'white', 'gray92', 'gray86', 'gray79', 'gray69', 'gray56',  'gray39', 'gray25','black' ],
        dawn   => [ 'white', '#f9d87b', '#936d1a', '#bf3136', '#8f1416', '#99158b', '#1d1d7c', '#111111', 'black' ],
        day    => [ 'white', '#ffcf3d', '#e29955', '#ff1418', '#4acfab', '#48614a', 'gray20',  '#111111', 'black' ],

lib/App/GUI/Cellgraph/Frame.pm  view on Meta::CPAN

    my ( $class, $parent, $title ) = @_;
    my $self = $class->SUPER::new( $parent, -1, $title );
    $self->SetIcon( Wx::GetWxPerlIcon() );
    $self->CreateStatusBar( 1 );
    $self->SetStatusWidths(2, 800, 100);
    Wx::InitAllImageHandlers();
    $self->{'title'} = $title;
    $self->{'config'} = App::GUI::Cellgraph::Config->new();
    my $sr_calc = App::GUI::Cellgraph::Compute::Subrule->new( 3, 2, 'all' );
    $self->{'img_size'} = 700;
    $self->{'img_format'} = 'png';
    my $window_size = [1200, 840];

    # create GUI parts
    $self->{'tabs'}            = Wx::AuiNotebook->new( $self, -1, [-1,-1], [-1,-1], &Wx::wxAUI_NB_TOP );
    $self->{'tab'}{'global'} = App::GUI::Cellgraph::Frame::Tab::General->new( $self->{'tabs'}, $sr_calc );
    $self->{'tab'}{'start'}  = App::GUI::Cellgraph::Frame::Tab::Start->new(  $self->{'tabs'} );
    $self->{'tab'}{'rules'}  = App::GUI::Cellgraph::Frame::Tab::Rules->new(  $self->{'tabs'}, $sr_calc );
    $self->{'tab'}{'action'} = App::GUI::Cellgraph::Frame::Tab::Action->new( $self->{'tabs'}, $sr_calc );
    $self->{'tab'}{'color'}  = App::GUI::Cellgraph::Frame::Tab::Color->new(  $self->{'tabs'}, $self->{'config'} );
    $self->{'tab_names'} = [keys %{$self->{'tab'}}];

lib/App/GUI/Cellgraph/Frame.pm  view on Meta::CPAN


sub write_image {
    my ($self, $file)  = @_;
    $self->{'board'}->save_file( $file );
    $file = App::GUI::Cellgraph::Settings::shrink_path( $file );
    $self->SetStatusText( "saved image under: $file", 0 );
}

sub save_image_dialog {
    my ($self) = @_;
    my @wildcard = ( 'SVG files (*.svg)|*.svg', 'PNG files (*.png)|*.png', 'JPEG files (*.jpg)|*.jpg');
    my $wildcard = '|All files (*.*)|*.*';
    my $default_ending = $self->{'config'}->get_value('file_base_ending');
    $wildcard = ($default_ending eq 'jpg') ? ( join '|', @wildcard[2,1,0]) . $wildcard :
                ($default_ending eq 'png') ? ( join '|', @wildcard[1,0,2]) . $wildcard :
                                             ( join '|', @wildcard[0,1,2]) . $wildcard ;
    my @wildcard_ending = ($default_ending eq 'jpg') ? (qw/jpg png svg/) :
                          ($default_ending eq 'png') ? (qw/png svg jpg/) :
                                                       (qw/svg jpg png/) ;

    my $dialog = Wx::FileDialog->new ( $self, "select a file name to save image", $self->{'config'}->get_value('save_dir'), '', $wildcard, &Wx::wxFD_SAVE );
    return if $dialog->ShowModal == &Wx::wxID_CANCEL;
    my $path = $dialog->GetPath;
    return if -e $path and
              Wx::MessageDialog->new( $self, "\n\nReally overwrite the image file?", 'Confirmation Question',
                                      &Wx::wxYES_NO | &Wx::wxICON_QUESTION )->ShowModal() != &Wx::wxID_YES;
    my $file_ending = lc substr ($path, -4);
    unless ($dialog->GetFilterIndex == 3 or # filter set to all endings
            ($file_ending eq '.jpg' or $file_ending eq '.png' or $file_ending eq '.svg')){
            $path .= '.' . $wildcard_ending[$dialog->GetFilterIndex];
    }
    my $ret = $self->write_image( $path );
    if ($ret){ $self->SetStatusText( $ret, 0 ) }
    else     { $self->{'config'}->set_value('save_dir', App::GUI::Cellgraph::Settings::extract_dir( $path )) }
}

1;

lib/App/GUI/Cellgraph/Frame/Panel/Board.pm  view on Meta::CPAN

    }
#say "paint took:",timestr( timediff(Benchmark->new, $t1) );
    delete $self->{'flag'};
    $dc;
}

sub save_file {
    my( $self, $file_name, $width, $height ) = @_;
    my $file_end = lc substr( $file_name, -3 );
    if ($file_end eq 'svg') { $self->save_svg_file( $file_name, $width, $height ) }
    elsif ($file_end eq 'png' or $file_end eq 'jpg') { $self->save_bmp_file( $file_name, $file_end, $width, $height ) }
    else { return "unknown file ending: '$file_end'" }
}

sub save_svg_file {
    my( $self, $file_name, $width, $height ) = @_;
    $width  //= $self->{'img_size'};
    $height //= $self->{'img_size'};
    $width  //= $self->{'size'}{'x'};
    $height //= $self->{'size'}{'y'};
    my $dc = Wx::SVGFileDC->new( $file_name, $width, $height, 250 );  #  250 dpi

lib/App/GUI/Cellgraph/Frame/Panel/Board.pm  view on Meta::CPAN

    $width  //= $self->{'img_size'};
    $height //= $self->{'img_size'};
    $width  //= $self->{'size'}{'x'};
    $height //= $self->{'size'}{'y'};
    my $bmp = Wx::Bitmap->new( $width, $height, 24); # bit depth
    my $dc = Wx::MemoryDC->new( );
    $dc->SelectObject( $bmp );
    $self->paint( $dc, $width, $height);
    #$dc->Blit (0, 0, $width, $height, $self->{'dc'}, 10, 10 + $self->{'menu_size'});
    $dc->SelectObject( &Wx::wxNullBitmap );
    $bmp->SaveFile( $file_name, $file_end eq 'png' ? &Wx::wxBITMAP_TYPE_PNG : &Wx::wxBITMAP_TYPE_JPEG );
}

1;



( run in 1.270 second using v1.01-cache-2.11-cpan-df04353d9ac )