App-GUI-Juliagraph
view release on metacpan or search on metacpan
lib/App/GUI/Juliagraph/Frame/Tab/Mapping.pm view on Meta::CPAN
# visible tab with all visual settings
package App::GUI::Juliagraph::Frame::Tab::Mapping;
use v5.12;
use warnings;
use base qw/Wx::Panel/;
use Graphics::Toolkit::Color qw/color/;
use Wx;
use App::GUI::Juliagraph::Widget::SliderStep;
use App::GUI::Juliagraph::Widget::SliderCombo;
use App::GUI::Juliagraph::Widget::ProgressBar;
my $default_settings = {
custom_partition => 0, scale_steps => 20, scale_distro => 'square',
user_colors => 1, begin_color => 'color 2', end_color => 'color 4', background_color => 'black',
gradient_dynamic => 0, gradient_space => 'HSL',
use_subgradient => 0, subgradient_size => 500, subgradient_steps => 5,
subgradient_dynamic => 0, subgradient_space => 'HSL', subgradient_distro => 'sqrt',
};
sub new {
my ( $class, $parent ) = @_;
my $self = $class->SUPER::new( $parent, -1);
$self->{'callback'} = sub {};
$self->{'tab'}{'color'} = '';
my $map_lbl = Wx::StaticText->new($self, -1, 'C o l o r G r a d i e n t : ' );
my $color_lbl = Wx::StaticText->new($self, -1, 'User Colors : ' );
$self->{'lbl_backg'} = Wx::StaticText->new($self, -1, 'Background : ' );
$self->{'lbl_begin'} = Wx::StaticText->new($self, -1, 'Begin : ' );
$self->{'lbl_end'} = Wx::StaticText->new($self, -1, 'End : ' );
my $map_dyn_lbl = Wx::StaticText->new($self, -1, 'Dynamic : ' );
my $map_space_lbl = Wx::StaticText->new($self, -1, 'Space : ' );
my $scale_lbl = Wx::StaticText->new($self, -1, 'P a r t i t i o n i n g T h e I t e r a t i o n S c a l e : ' );
my $custom_lbl = Wx::StaticText->new($self, -1, 'Custom : ' );
$self->{'lbl_max'} = Wx::StaticText->new($self, -1, 'Iterations (Size) : ' );
$self->{'lbl_distro'} = Wx::StaticText->new($self, -1, 'Distribution : ' );
my $submap_lbl = Wx::StaticText->new($self, -1, 'S u b G r a d i e n t : ' );
$self->{'lbl_sub_use'} = Wx::StaticText->new($self, -1, 'Activate : ' );
$self->{'lbl_sub_dyn'} = Wx::StaticText->new($self, -1, 'Dynamic : ' );
$self->{'lbl_sub_space'} = Wx::StaticText->new($self, -1, 'Space : ' );
$self->{'lbl_sub_distro'} = Wx::StaticText->new($self, -1, 'Distribution : ' );
$map_lbl->SetToolTip('Decide which colors are used to paint the drawing.');
$color_lbl->SetToolTip('Use slected colors (on) or just simple gray scale (off)');
$self->{'lbl_backg'}->SetToolTip('Which color is used to paint areas where computation never exceeds the bailout value.');
$self->{'lbl_begin'}->SetToolTip('Starting color of the rainbow.');
$self->{'lbl_end'}->SetToolTip('Endcolor of the rainbow');
$map_dyn_lbl->SetToolTip('How many big is the slant of a color gradient in one or another direction (between the selected colors in next tab)');
$map_space_lbl->SetToolTip('In which color space will the gradient between chosen colors be computed ?');
$scale_lbl->SetToolTip('Divide the scale of possible iterations into goups (partitions) that can be mapped to colors.');
$custom_lbl->SetToolTip('Divide the scale of possible iterations into goups (partitions) that can be mapped to colors. Use every iteration count gets its own color when off.');
$self->{'lbl_max'}->SetToolTip('Maximal iteration count that gets partitioned.');
$self->{'lbl_distro'}->SetToolTip('How to compute the partitioning of the iteration scale. Linear means evenly sized portions.');
$submap_lbl->SetToolTip('Gradients between areas of iteration counts based on final value.');
$self->{'lbl_sub_use'}->SetToolTip('Make even more fine grained color gradients, my computing gradient between color regions.');
$self->{'lbl_sub_dyn'}->SetToolTip('How big is the slant of a color sub gradient in one or another direction ?');
$self->{'lbl_sub_space'}->SetToolTip('In which color space will the subgradient between chosen colors be computed ?');
my @color_names = map { 'color '.$_ } 1 .. 11;
$self->{'custom_partition'} = Wx::CheckBox->new( $self, -1, '', [-1,-1],[30, -1]);
$self->{'user_colors'} = Wx::CheckBox->new( $self, -1, '', [-1,-1],[30, -1]);
$self->{'use_subgradient'} = Wx::CheckBox->new( $self, -1, '', [-1,-1],[30, -1]);
$self->{'scale_steps'} = App::GUI::Juliagraph::Widget::SliderCombo->new( $self, 252, 'Steps :', "In how many parts the scale (0 .. max) will be partitioned, meaning: how many different colors/shades we use to paint the fractal", 2, 100, 20);
$self->{'scale_max'} = Wx::TextCtrl->new( $self, -1, 0, [-1,-1], [60, -1], &Wx::wxTE_RIGHT | &Wx::wxTE_READONLY);
$self->{'scale_distro'} = Wx::ComboBox->new( $self, -1, 'linear', [-1,-1],[100, -1], [qw/log cubert sqrt linear square cube exp/]);
$self->{'begin_color'} = Wx::ComboBox->new( $self, -1, 'color 3', [-1,-1],[100, -1], [@color_names]);
$self->{'end_color'} = Wx::ComboBox->new( $self, -1, 'color 4', [-1,-1],[100, -1], [@color_names]);
$self->{'background_color'} = Wx::ComboBox->new( $self, -1,'black', [-1,-1],[100,-1], [qw/black blue gray white/, 'color 11']);
$self->{'gradient_dynamic'} = Wx::ComboBox->new( $self, -1, 0, [-1,-1],[80, -1], [-5, -4, -3, -2.5, -2, -1.6, -1.3, -1, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1, 1.3, 1.6, 2, 2.5, 3, 4, 5...
$self->{'gradient_space'} = Wx::ComboBox->new( $self, -1, 'RGB', [-1,-1],[80, -1], [qw/RGB HSL/]);
$self->{'subgradient_steps'} = App::GUI::Juliagraph::Widget::SliderCombo->new( $self, 249, 'Steps :', "How man shades toes the subgradient have ?", 2, 100, 5, 1);
$self->{'subgradient_size'} = App::GUI::Juliagraph::Widget::SliderCombo->new( $self, 249, 'Size :', "Up to which value (Bailout/Stop Value + X) does the scale goes, from which subgradient is computed", 100, 5000, 500, 50);
$self->{'subgradient_space'} = Wx::ComboBox->new( $self, -1, 'RGB', [-1,-1],[80, -1], [qw/RGB HSL/]);
$self->{'subgradient_dynamic'}= Wx::ComboBox->new($self, -1, 0, [-1,-1],[80, -1], [-5, -4, -3, -2.5, -2, -1.6, -1.3, -1, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1, 1.3, 1.6, 2, 2.5, 3, 4, 5])...
$self->{'subgradient_distro'} = Wx::ComboBox->new( $self, -1, 'linear', [-1,-1],[100, -1], [qw/log cubert sqrt linear square cube exp/]);
$self->{'custom_partition'}->SetToolTip('Divide the scale of possible iterations into goups (partitions) that can be mapped to colors. Use every iteration count gets its own color when off.');
$self->{'scale_max'}->SetToolTip('Maximal iteration count.');
$self->{'scale_distro'}->SetToolTip('Relation between partitions size wise, linear means they all equally big.');
$self->{'user_colors'}->SetToolTip('Use chosen color selection to compute color rainbow (on) or just a gray scale (off).');
$self->{'use_subgradient'}->SetToolTip('Make color gradient smoother by computing gradients between colored areas based on final value of iteration.');
$self->{'begin_color'}->SetToolTip('Starting color of the rainbow.');
$self->{'end_color'}->SetToolTip('Endcolor of the rainbow');
$self->{'background_color'}->SetToolTip('Color that is used to paint areas where iteration stays below stop value.');
$self->{'gradient_dynamic'}->SetToolTip('Skew direction of gradient (positive value = left)');
$self->{'subgradient_dynamic'}->SetToolTip('Skew direction of gradient (positive value = left)');
$self->{'subgradient_distro'}->SetToolTip('Relation between parts of subgradient size wise');
$self->{'color_rainbow'} = App::GUI::Juliagraph::Widget::ProgressBar->new( $self, 450, 30, [20, 20, 110]);
$self->{'background_rainbow'} = App::GUI::Juliagraph::Widget::ProgressBar->new( $self, 450, 10, [20, 20, 110]);
$self->{'color_rainbow'}->SetToolTip('Color gradient display.');
$self->{'background_rainbow'}->SetToolTip('Background color display.');
Wx::Event::EVT_CHECKBOX( $self, $self->{'custom_partition'},sub { $self->enable_partition($self->{'custom_partition'}->GetValue); $self->{'callback'}->() });
Wx::Event::EVT_CHECKBOX( $self, $self->{'user_colors'}, sub { $self->enable_user_colors($self->{'user_colors'}->GetValue); $self->{'callback'}->() });
Wx::Event::EVT_CHECKBOX( $self, $self->{'use_subgradient'}, sub { $self->enable_subgradient($self->{'use_subgradient'}->GetValue);$self->{'callback'}->() });
Wx::Event::EVT_COMBOBOX( $self, $self->{$_}, sub { $self->update_max_color; $self->{'callback'}->() })
for qw/begin_color end_color/;
Wx::Event::EVT_COMBOBOX( $self, $self->{$_}, sub { $self->{'callback'}->() })
for qw/scale_distro gradient_dynamic gradient_space background_color
subgradient_distro subgradient_dynamic subgradient_space/;
$self->{$_}->SetCallBack( sub { $self->{'callback'}->(); }) for qw/scale_steps subgradient_size subgradient_steps/;
my $std_margin = 20;
my $std = &Wx::wxALIGN_LEFT | &Wx::wxALIGN_CENTER_VERTICAL | &Wx::wxGROW;
my $box = $std | &Wx::wxTOP | &Wx::wxBOTTOM;
my $item = $std | &Wx::wxLEFT;
my $row = $std | &Wx::wxTOP;
my $div_sizer = Wx::BoxSizer->new(&Wx::wxHORIZONTAL);
$div_sizer->AddSpacer( $std_margin );
$div_sizer->AddSpacer( 10 );
$div_sizer->Add( $custom_lbl, 0, $box, 12);
$div_sizer->AddSpacer( 10 );
$div_sizer->Add( $self->{'custom_partition'}, 0, $box, 5);
$div_sizer->AddSpacer( 20 );
$div_sizer->Add( $self->{'scale_steps'}, 0, $box, 5);
$div_sizer->AddStretchSpacer();
$div_sizer->AddSpacer( $std_margin );
my $div2_sizer = Wx::BoxSizer->new(&Wx::wxHORIZONTAL);
$div2_sizer->AddSpacer( $std_margin );
$div2_sizer->AddSpacer( 75 );
$div2_sizer->Add( $self->{'lbl_max'}, 0, $box, 12);
$div2_sizer->AddSpacer( 10 );
$div2_sizer->Add( $self->{'scale_max'}, 0, $box, 5);
$div2_sizer->AddSpacer( 97 );
$div2_sizer->Add( $self->{'lbl_distro'}, 0, $box, 12);
$div2_sizer->AddSpacer( 10 );
$div2_sizer->Add( $self->{'scale_distro'}, 0, $box, 5);
$div2_sizer->AddStretchSpacer();
$div2_sizer->AddSpacer( $std_margin );
my $color_sizer = Wx::BoxSizer->new(&Wx::wxHORIZONTAL);
$color_sizer->AddSpacer( $std_margin );
$color_sizer->AddSpacer( 10 );
$color_sizer->Add( $color_lbl, 0, $box, 12);
$color_sizer->AddSpacer( 10 );
$color_sizer->Add( $self->{'user_colors'}, 0, $box, 0);
$color_sizer->AddSpacer( 80 );
$color_sizer->Add( $self->{'lbl_begin'}, 0, $box, 12);
$color_sizer->AddSpacer( 10 );
$color_sizer->Add( $self->{'begin_color'}, 0, $box, 5);
$color_sizer->AddSpacer( 28 );
$color_sizer->Add( $self->{'lbl_end'}, 0, $box, 12);
$color_sizer->AddSpacer( 10 );
$color_sizer->Add( $self->{'end_color'}, 0, $box, 5);
$color_sizer->AddStretchSpacer();
$color_sizer->AddSpacer( $std_margin );
my $map_sizer = Wx::BoxSizer->new(&Wx::wxHORIZONTAL);
$map_sizer->AddSpacer( $std_margin );
$map_sizer->AddSpacer( 10 );
$map_sizer->Add( $self->{'lbl_backg'}, 0, $box, 12);
$map_sizer->AddSpacer( 10 );
$map_sizer->Add( $self->{'background_color'}, 0, $box, 5);
$map_sizer->AddSpacer( 23 );
$map_sizer->Add( $map_dyn_lbl, 0, $box, 12);
$map_sizer->AddSpacer( 10 );
$map_sizer->Add( $self->{'gradient_dynamic'}, 0, $box, 5);
$map_sizer->AddSpacer( 22 );
$map_sizer->Add( $map_space_lbl, 0, $box, 12);
$map_sizer->AddSpacer( 10 );
$map_sizer->Add( $self->{'gradient_space'}, 0, $box, 5);
$map_sizer->AddStretchSpacer();
$map_sizer->AddSpacer( $std_margin );
my $sub_sizer = Wx::BoxSizer->new(&Wx::wxHORIZONTAL);
$sub_sizer->AddSpacer( $std_margin );
$sub_sizer->AddSpacer( 10 );
$sub_sizer->Add( $self->{'lbl_sub_use'}, 0, $box, 12);
$sub_sizer->AddSpacer( 10 );
$sub_sizer->Add( $self->{'use_subgradient'}, 0, $box, 5);
$sub_sizer->AddSpacer( 20 );
$sub_sizer->Add( $self->{'subgradient_steps'}, 1, $box, 5);
$sub_sizer->AddSpacer( $std_margin );
my $sub2_sizer = Wx::BoxSizer->new(&Wx::wxHORIZONTAL);
$sub2_sizer->AddSpacer( $std_margin );
$sub2_sizer->AddSpacer( 140 );
$sub2_sizer->Add( $self->{'subgradient_size'}, 1, $box, 4);
$sub2_sizer->AddSpacer( $std_margin );
my $sub3_sizer = Wx::BoxSizer->new(&Wx::wxHORIZONTAL);
$sub3_sizer->AddSpacer( $std_margin );
$sub3_sizer->AddSpacer( 10 );
$sub3_sizer->Add( $self->{'lbl_sub_distro'}, 0, $box, 12);
$sub3_sizer->AddSpacer( 10 );
$sub3_sizer->Add( $self->{'subgradient_distro'}, 0, $box, 4);
$sub3_sizer->AddSpacer( 25 );
$sub3_sizer->Add( $self->{'lbl_sub_dyn'}, 0, $box, 12);
$sub3_sizer->AddSpacer( 10 );
$sub3_sizer->Add( $self->{'subgradient_dynamic'},0, $box, 4);
$sub3_sizer->AddSpacer( 25 );
$sub3_sizer->Add( $self->{'lbl_sub_space'}, 0, $box, 12);
$sub3_sizer->AddSpacer( 10 );
$sub3_sizer->Add( $self->{'subgradient_space'}, 0, $box, 4);
$sub3_sizer->AddStretchSpacer();
$sub3_sizer->AddSpacer( $std_margin );
my $sizer = Wx::BoxSizer->new(&Wx::wxVERTICAL);
$sizer->AddSpacer( 10 );
$sizer->Add( $map_lbl, 0, $item, $std_margin);
$sizer->Add( $color_sizer, 0, $row, 8);
$sizer->Add( $map_sizer, 0, $row, 10);
$sizer->AddSpacer( 2 );
$sizer->Add( Wx::StaticLine->new( $self, -1), 0, $box, 10 );
$sizer->AddSpacer( 5 );
$sizer->Add( $self->{'color_rainbow'}, 0, $item | &Wx::wxRIGHT, 20 );
$sizer->AddSpacer( 10 );
$sizer->Add( $self->{'background_rainbow'}, 0, $item | &Wx::wxRIGHT, 20 );
$sizer->AddSpacer( 5 );
$sizer->Add( Wx::StaticLine->new( $self, -1), 0, $box, 10 );
$sizer->Add( $scale_lbl, 0, $item, $std_margin);
$sizer->Add( $div_sizer, 0, $row, 8);
$sizer->Add( $div2_sizer, 0, $row, 10);
$sizer->Add( Wx::StaticLine->new( $self, -1), 0, $box, 10 );
$sizer->Add( $submap_lbl, 0, $item, $std_margin);
$sizer->Add( $sub_sizer, 0, $row, 8);
$sizer->Add( $sub2_sizer, 0, $row, 10);
$sizer->Add( $sub3_sizer, 0, $row, 10);
$sizer->Add( Wx::StaticLine->new( $self, -1), 0, $box, 10 );
$sizer->AddStretchSpacer();
$self->SetSizer($sizer);
$self->init();
$self;
}
sub init { $_[0]->set_settings ( $default_settings ) }
sub set_settings {
my ( $self, $settings ) = @_;
return 0 unless ref $settings eq 'HASH' and exists $settings->{'user_colors'};
$self->PauseCallBack();
for my $key (qw/custom_partition scale_steps user_colors use_subgradient subgradient_size subgradient_steps/){
next unless exists $settings->{$key} and exists $settings->{$key};
$self->{$key}->SetValue( $settings->{$key} );
}
for my $key (qw/scale_distro background_color begin_color end_color gradient_dynamic
gradient_space subgradient_dynamic subgradient_space subgradient_distro/){
next unless exists $settings->{$key} and exists $self->{$key};
$self->{$key}->SetSelection( $self->{$key}->FindString($settings->{$key}) );
}
$self->enable_partition( $settings->{'custom_partition'} );
$self->enable_user_colors( $settings->{'user_colors'} );
$self->enable_subgradient( $settings->{'use_subgradient'} );
$self->update_max_color( );
$self->RestoreCallBack();
1;
}
sub get_settings {
my ( $self ) = @_;
return {
custom_partition => int $self->{'custom_partition'}->GetValue,
user_colors => int $self->{'user_colors'}->GetValue,
use_subgradient => int $self->{'use_subgradient'}->GetValue,
scale_steps => $self->{'scale_steps'}->GetValue,
scale_distro => $self->{'scale_distro'}->GetStringSelection,
background_color => $self->{'background_color'}->GetStringSelection,
begin_color => $self->{'begin_color'}->GetStringSelection,
end_color => $self->{'end_color'}->GetStringSelection,
gradient_dynamic => $self->{'gradient_dynamic'}->GetStringSelection,
gradient_space => $self->{'gradient_space'}->GetStringSelection,
subgradient_size => $self->{'subgradient_size'}->GetValue,
subgradient_steps => $self->{'subgradient_steps'}->GetValue,
subgradient_dynamic=>$self->{'subgradient_dynamic'}->GetStringSelection,
subgradient_space => $self->{'subgradient_space'}->GetStringSelection,
subgradient_distro => $self->{'subgradient_distro'}->GetStringSelection,
};
}
sub enable_partition {
my ( $self, $on ) = @_;
$on //= $self->{'custom_partition'}->GetValue;
$self->{'custom_partition'}->SetValue( $on ) unless int($on) == int $self->{'custom_partition'}->GetValue;
$self->{$_}->Enable( $on ) for qw/scale_steps scale_distro scale_max lbl_max lbl_distro/;
$self->enable_subgradient(0) if $on;
$self->{'use_subgradient'}->Enable( not $on );
$self->{'lbl_sub_use'}->Enable( not $on );
}
sub enable_user_colors {
my ( $self, $on ) = @_;
$on //= $self->{'user_colors'}->GetValue;
$self->{'user_colors'}->SetValue( $on ) unless int($on) == int $self->{'user_colors'}->GetValue;
$self->{ $_ }->Enable( $on ) for qw/background_color begin_color end_color lbl_begin lbl_end lbl_backg/;
}
sub enable_subgradient {
my ( $self, $on ) = @_;
$on //= $self->{'use_subgradient'}->GetValue;
$self->{'use_subgradient'}->SetValue($on) unless int($on) == int $self->{'use_subgradient'}->GetValue;
$self->{$_}->Enable( $on ) for qw/subgradient_steps subgradient_dynamic subgradient_space subgradient_distro
lbl_sub_dyn lbl_sub_space lbl_sub_distro subgradient_size/;
}
sub update_max_color {
my ( $self ) = @_;
my $begin_color = substr $self->{'begin_color'}->GetStringSelection, 6;
my $end_color = substr $self->{'end_color'}->GetStringSelection, 6;
my $max_color = $begin_color > $end_color ? $begin_color : $end_color;
$self->{'tab'}{'color'}->set_active_color_count( $max_color ) if ref $self->{'tab'}{'color'};
}
sub connect_color_tab {
my ($self, $ref) = @_;
return unless ref $ref eq 'App::GUI::Juliagraph::Frame::Tab::Color';
$self->{'tab'}{'color'} = $ref;
$self->update_max_color;
}
sub SetCallBack {
my ($self, $code) = @_;
return unless ref $code eq 'CODE';
$self->{'callback'} = $code;
}
sub PauseCallBack {
my ($self) = @_;
$self->{'pause'} = $self->{'callback'};
$self->{'callback'} = sub {};
}
sub RestoreCallBack {
my ($self) = @_;
return unless exists $self->{'pause'};
$self->{'callback'} = $self->{'pause'};
delete $self->{'pause'};
}
1;
( run in 0.501 second using v1.01-cache-2.11-cpan-f56aa216473 )