SlideShare una empresa de Scribd logo
1 de 108
Descargar para leer sin conexión
Wx::Perl::SmartWx::Perl::Smart
Schneller
Bessere
GUI's
Wx::Perl::Wx::Perl::SmartSmart
Wx::Perl::Wx::Perl::SmartSmart
~~
Wx::Perl::Wx::Perl::SmartSmart
~~
Wx::Perl::Wx::Perl::SmartSmart
$var ~~ @list
Wx::Perl::Smart
sub OnInit {
my $app = shift;
# load localisation texts in chosen language
my ($v, $dir, $f) = File::Spec->splitpath(__FILE__);
$l18n_file = File::Spec->catfile($dir, $l18n_file) if $dir;
die "localisation file $l18n_file is missing!" unless -e $l18n_file;
my %l18n = %{YAML::Tiny->read( $l18n_file )->[0]{$language}};
$app->{'l18n'} = %l18n;
# loading the numbers of the remembered favorites
$app->{'favorites'} = -e $fav_file ? YAML::Tiny->read( $fav_file ) : YAML::Tiny->new;
my @remembered_pic_names = ref $app->{'favorites'}->[0] eq 'HASH' ? keys $app->{'favorites'}->[0] : ();
# making UI
my $frame = $app->{'frame'} = Wx::Perl::Smart::Frame->new(__PACKAGE__." $VERSION", 'fixed_size');
$frame->SubscribeStrings( $app->{'l18n'} );
my $remember= sub { $frame->SetValues( $app->{'favorites'}[0]{ $_[0]->GetValue() } ); $app->Repaint()};
my $repaint = sub { $app->Repaint() };
my $boardsize = Wx::GetDisplaySize()->GetHeight() - 250;
my $origin_offset = $app->{'origin_offset'} = $boardsize / 2;
my $max_amp = $app->{'max_amp'} = $origin_offset - 10; # max amplitude
my %range_defaults = (# label, min, max, init
frequency_x => ['X', 1, 1, 30], frequency_y => ['Y', 1, 1, 30],
amplitude_x => ['X', 0, 0, 360], amplitude_y => ['Y', 0, 0, 360],
rotation => [$l18n{'amount'}, 1, 0, 30], friction => [$l18n{'friction'}, 0, 0, 200],
length => [$l18n{'length'}, 12, 1, 100], density => [$l18n{'density'},100, 1, 100],
thickness => [$l18n{'thickness'},1, 1, 12], zoom => [$l18n{'zoom'}, 0,-10, 10],
start_colour=> [$l18n{'start'}, 0, 0,1500], flow_colour => [$l18n{'flow'}, 0, 0, 60],
scale_colour=> [$l18n{'scale'}, 1, 1, 4],
);
$frame->SubscribeWidgets
({$_ => Wx::Perl::DisplaySlider->new($frame, @{$range_defaults{$_}}, $repaint)}) for keys %range_defaults;
$frame->SubscribeWidgets({
drawboard => Wx::Perl::DrawMap->new($frame, $boardsize),
fav_select => [-ComboBox => @remembered_pic_names, 0, -1, $remember],
format_select=> [-ComboBox => [qw(PNG JPG TIFF BMP XPM)], 0, 70 ],
save => [-Button => '~save', sub {$app->Save() }],
save_all => [-Button => '~all', sub {$app->SaveAll() }],
remember => [-Button => '~remember', sub {$app->Remember()}],
forget => [-Button => '~forget', sub {$app->Forget() }],
no_phase => [-Button => '~no', sub {$frame->SetValues(amplitude_x => 0, amplitude_y => 0);$app->Repaint()}],
closed_phase => [-Button => '~closed', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 90);$app->Repaint()}],
open_phase => [-Button => '~open', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 180);$app->Repaint()}],
y_invers => [-CheckBox => '~y_inverse', 0, $repaint],
rotation_dir => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(no left right)}], 0, &Wx::wxHORIZONTAL, $repaint),
app_mode => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(lateral rotary free)}], 0, &Wx::wxHORIZONTAL, sub{}),
});
$frame->SetSmartLayout(
{flags => &Wx::wxGROW|&Wx::wxALL},
[ # left part
'<drawboard>',
10,
{border => 10, flags => &Wx::wxALL|&Wx::wxGROW},
'<fav_select>',
['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10, '<remember>'],
],[ # right half
-TabbedBox => [
'~oscillators' =>[
{border => 5, flags => &Wx::wxGROW|&Wx::wxALL},
['~mode :', '<app_mode>'],
-LabeledBox =>['~frequency' =>[qw( <frequency_x> <frequency_y>)]], #<y_invers>
-LabeledBox =>['~start_amp' =>[qw( <amplitude_x> <amplitude_y>),
{border => 5, flags => &Wx::wxALL|&Wx::wxGROW},
['~phase :', 1, '<no_phase>', 1,'<closed_phase>', 1, '<open_phase>'],
]],
-LabeledBox =>[ '~rotation ' =>[qw( <rotation_dir> <rotation> )]],
{border => 10}, '<friction>',
],
'~visuals' => [
{border => 5, flags => &Wx::wxGROW|&Wx::wxALL},
-LabeledBox =>['~line' =>[qw( <length> <density> )]], #<thickness>
-LabeledBox =>['~color' =>[qw( <start_colour> <flow_colour> <scale_colour>)]],
{border => 10},'<zoom>',
],
],
]);
$frame->ResetValues();
$app->Repaint();
$app->SetTopWindow($frame);
1;
Harmonogra
ph
sub OnInit {
my $app = shift;
# load localisation texts in chosen language
my ($v, $dir, $f) = File::Spec->splitpath(__FILE__);
$l18n_file = File::Spec->catfile($dir, $l18n_file) if $dir;
die "localisation file $l18n_file is missing!" unless -e $l18n_file;
my %l18n = %{YAML::Tiny->read( $l18n_file )->[0]{$language}};
$app->{'l18n'} = %l18n;
# loading the numbers of the remembered favorites
$app->{'favorites'} = -e $fav_file ? YAML::Tiny->read( $fav_file ) : YAML::Tiny->new;
my @remembered_pic_names = ref $app->{'favorites'}->[0] eq 'HASH' ? keys $app->{'favorites'}->[0] : ();
# making UI
my $frame = $app->{'frame'} = Wx::Perl::Smart::Frame->new(__PACKAGE__." $VERSION", 'fixed_size');
$frame->SubscribeStrings( $app->{'l18n'} );
my $remember= sub { $frame->SetValues( $app->{'favorites'}[0]{ $_[0]->GetValue() } ); $app->Repaint()};
my $repaint = sub { $app->Repaint() };
my $boardsize = Wx::GetDisplaySize()->GetHeight() - 250;
my $origin_offset = $app->{'origin_offset'} = $boardsize / 2;
my $max_amp = $app->{'max_amp'} = $origin_offset - 10; # max amplitude
my %range_defaults = (# label, min, max, init
frequency_x => ['X', 1, 1, 30], frequency_y => ['Y', 1, 1, 30],
amplitude_x => ['X', 0, 0, 360], amplitude_y => ['Y', 0, 0, 360],
rotation => [$l18n{'amount'}, 1, 0, 30], friction => [$l18n{'friction'}, 0, 0, 200],
length => [$l18n{'length'}, 12, 1, 100], density => [$l18n{'density'},100, 1, 100],
thickness => [$l18n{'thickness'},1, 1, 12], zoom => [$l18n{'zoom'}, 0,-10, 10],
start_colour=> [$l18n{'start'}, 0, 0,1500], flow_colour => [$l18n{'flow'}, 0, 0, 60],
scale_colour=> [$l18n{'scale'}, 1, 1, 4],
);
$frame->SubscribeWidgets
({$_ => Wx::Perl::DisplaySlider->new($frame, @{$range_defaults{$_}}, $repaint)}) for keys %range_defaults;
$frame->SubscribeWidgets({
drawboard => Wx::Perl::DrawMap->new($frame, $boardsize),
fav_select => [-ComboBox => @remembered_pic_names, 0, -1, $remember],
format_select=> [-ComboBox => [qw(PNG JPG TIFF BMP XPM)], 0, 70 ],
save => [-Button => '~save', sub {$app->Save() }],
save_all => [-Button => '~all', sub {$app->SaveAll() }],
remember => [-Button => '~remember', sub {$app->Remember()}],
forget => [-Button => '~forget', sub {$app->Forget() }],
no_phase => [-Button => '~no', sub {$frame->SetValues(amplitude_x => 0, amplitude_y => 0);$app->Repaint()}],
closed_phase => [-Button => '~closed', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 90);$app->Repaint()}],
open_phase => [-Button => '~open', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 180);$app->Repaint()}],
y_invers => [-CheckBox => '~y_inverse', 0, $repaint],
rotation_dir => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(no left right)}], 0, &Wx::wxHORIZONTAL, $repaint),
app_mode => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(lateral rotary free)}], 0, &Wx::wxHORIZONTAL, sub{}),
});
$frame->SetSmartLayout(
{flags => &Wx::wxGROW|&Wx::wxALL},
[ # left part
'<drawboard>',
10,
{border => 10, flags => &Wx::wxALL|&Wx::wxGROW},
'<fav_select>',
['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10, '<remember>'],
],[ # right half
-TabbedBox => [
'~oscillators' =>[
{border => 5, flags => &Wx::wxGROW|&Wx::wxALL},
['~mode :', '<app_mode>'],
-LabeledBox =>['~frequency' =>[qw( <frequency_x> <frequency_y>)]], #<y_invers>
-LabeledBox =>['~start_amp' =>[qw( <amplitude_x> <amplitude_y>),
{border => 5, flags => &Wx::wxALL|&Wx::wxGROW},
['~phase :', 1, '<no_phase>', 1,'<closed_phase>', 1, '<open_phase>'],
]],
-LabeledBox =>[ '~rotation ' =>[qw( <rotation_dir> <rotation> )]],
{border => 10}, '<friction>',
],
'~visuals' => [
{border => 5, flags => &Wx::wxGROW|&Wx::wxALL},
-LabeledBox =>['~line' =>[qw( <length> <density> )]], #<thickness>
-LabeledBox =>['~color' =>[qw( <start_colour> <flow_colour> <scale_colour>)]],
{border => 10},'<zoom>',
],
],
]);
$frame->ResetValues();
$app->Repaint();
$app->SetTopWindow($frame);
1;
Harmonogra
ph
sub OnInit {
my $app = shift;
# load localisation texts in chosen language
my ($v, $dir, $f) = File::Spec->splitpath(__FILE__);
$l18n_file = File::Spec->catfile($dir, $l18n_file) if $dir;
die "localisation file $l18n_file is missing!" unless -e $l18n_file;
my %l18n = %{YAML::Tiny->read( $l18n_file )->[0]{$language}};
$app->{'l18n'} = %l18n;
# loading the numbers of the remembered favorites
$app->{'favorites'} = -e $fav_file ? YAML::Tiny->read( $fav_file ) : YAML::Tiny->new;
my @remembered_pic_names = ref $app->{'favorites'}->[0] eq 'HASH' ? keys $app->{'favorites'}->[0] : ();
# making UI
my $frame = $app->{'frame'} = Wx::Perl::Smart::Frame->new(__PACKAGE__." $VERSION", 'fixed_size');
$frame->SubscribeStrings( $app->{'l18n'} );
my $remember= sub { $frame->SetValues( $app->{'favorites'}[0]{ $_[0]->GetValue() } ); $app->Repaint()};
my $repaint = sub { $app->Repaint() };
my $boardsize = Wx::GetDisplaySize()->GetHeight() - 250;
my $origin_offset = $app->{'origin_offset'} = $boardsize / 2;
my $max_amp = $app->{'max_amp'} = $origin_offset - 10; # max amplitude
my %range_defaults = (# label, min, max, init
frequency_x => ['X', 1, 1, 30], frequency_y => ['Y', 1, 1, 30],
amplitude_x => ['X', 0, 0, 360], amplitude_y => ['Y', 0, 0, 360],
rotation => [$l18n{'amount'}, 1, 0, 30], friction => [$l18n{'friction'}, 0, 0, 200],
length => [$l18n{'length'}, 12, 1, 100], density => [$l18n{'density'},100, 1, 100],
thickness => [$l18n{'thickness'},1, 1, 12], zoom => [$l18n{'zoom'}, 0,-10, 10],
start_colour=> [$l18n{'start'}, 0, 0,1500], flow_colour => [$l18n{'flow'}, 0, 0, 60],
scale_colour=> [$l18n{'scale'}, 1, 1, 4],
);
$frame->SubscribeWidgets
({$_ => Wx::Perl::DisplaySlider->new($frame, @{$range_defaults{$_}}, $repaint)}) for keys %range_defaults;
$frame->SubscribeWidgets({
drawboard => Wx::Perl::DrawMap->new($frame, $boardsize),
fav_select => [-ComboBox => @remembered_pic_names, 0, -1, $remember],
format_select=> [-ComboBox => [qw(PNG JPG TIFF BMP XPM)], 0, 70 ],
save => [-Button => '~save', sub {$app->Save() }],
save_all => [-Button => '~all', sub {$app->SaveAll() }],
remember => [-Button => '~remember', sub {$app->Remember()}],
forget => [-Button => '~forget', sub {$app->Forget() }],
no_phase => [-Button => '~no', sub {$frame->SetValues(amplitude_x => 0, amplitude_y => 0);$app->Repaint()}],
closed_phase => [-Button => '~closed', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 90);$app->Repaint()}],
open_phase => [-Button => '~open', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 180);$app->Repaint()}],
y_invers => [-CheckBox => '~y_inverse', 0, $repaint],
rotation_dir => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(no left right)}], 0, &Wx::wxHORIZONTAL, $repaint),
app_mode => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(lateral rotary free)}], 0, &Wx::wxHORIZONTAL, sub{}),
});
$frame->SetSmartLayout(
{flags => &Wx::wxGROW|&Wx::wxALL},
[ # left part
'<drawboard>',
10,
{border => 10, flags => &Wx::wxALL|&Wx::wxGROW},
'<fav_select>',
['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10, '<remember>'],
],[ # right half
-TabbedBox => [
'~oscillators' =>[
{border => 5, flags => &Wx::wxGROW|&Wx::wxALL},
['~mode :', '<app_mode>'],
-LabeledBox =>['~frequency' =>[qw( <frequency_x> <frequency_y>)]], #<y_invers>
-LabeledBox =>['~start_amp' =>[qw( <amplitude_x> <amplitude_y>),
{border => 5, flags => &Wx::wxALL|&Wx::wxGROW},
['~phase :', 1, '<no_phase>', 1,'<closed_phase>', 1, '<open_phase>'],
]],
-LabeledBox =>[ '~rotation ' =>[qw( <rotation_dir> <rotation> )]],
{border => 10}, '<friction>',
],
'~visuals' => [
{border => 5, flags => &Wx::wxGROW|&Wx::wxALL},
-LabeledBox =>['~line' =>[qw( <length> <density> )]], #<thickness>
-LabeledBox =>['~color' =>[qw( <start_colour> <flow_colour> <scale_colour>)]],
{border => 10},'<zoom>',
],
],
]);
$frame->ResetValues();
$app->Repaint();
$app->SetTopWindow($frame);
1;
Harmonogra
ph
sub OnInit {
my $app = shift;
# load localisation texts in chosen language
my ($v, $dir, $f) = File::Spec->splitpath(__FILE__);
$l18n_file = File::Spec->catfile($dir, $l18n_file) if $dir;
die "localisation file $l18n_file is missing!" unless -e $l18n_file;
my %l18n = %{YAML::Tiny->read( $l18n_file )->[0]{$language}};
$app->{'l18n'} = %l18n;
# loading the numbers of the remembered favorites
$app->{'favorites'} = -e $fav_file ? YAML::Tiny->read( $fav_file ) : YAML::Tiny->new;
my @remembered_pic_names = ref $app->{'favorites'}->[0] eq 'HASH' ? keys $app->{'favorites'}->[0] : ();
# making UI
my $frame = $app->{'frame'} = Wx::Perl::Smart::Frame->new(__PACKAGE__." $VERSION", 'fixed_size');
$frame->SubscribeStrings( $app->{'l18n'} );
my $remember= sub { $frame->SetValues( $app->{'favorites'}[0]{ $_[0]->GetValue() } ); $app->Repaint()};
my $repaint = sub { $app->Repaint() };
my $boardsize = Wx::GetDisplaySize()->GetHeight() - 250;
my $origin_offset = $app->{'origin_offset'} = $boardsize / 2;
my $max_amp = $app->{'max_amp'} = $origin_offset - 10; # max amplitude
my %range_defaults = (# label, min, max, init
frequency_x => ['X', 1, 1, 30], frequency_y => ['Y', 1, 1, 30],
amplitude_x => ['X', 0, 0, 360], amplitude_y => ['Y', 0, 0, 360],
rotation => [$l18n{'amount'}, 1, 0, 30], friction => [$l18n{'friction'}, 0, 0, 200],
length => [$l18n{'length'}, 12, 1, 100], density => [$l18n{'density'},100, 1, 100],
thickness => [$l18n{'thickness'},1, 1, 12], zoom => [$l18n{'zoom'}, 0,-10, 10],
start_colour=> [$l18n{'start'}, 0, 0,1500], flow_colour => [$l18n{'flow'}, 0, 0, 60],
scale_colour=> [$l18n{'scale'}, 1, 1, 4],
);
$frame->SubscribeWidgets
({$_ => Wx::Perl::DisplaySlider->new($frame, @{$range_defaults{$_}}, $repaint)}) for keys %range_defaults;
$frame->SubscribeWidgets({
drawboard => Wx::Perl::DrawMap->new($frame, $boardsize),
fav_select => [-ComboBox => @remembered_pic_names, 0, -1, $remember],
format_select=> [-ComboBox => [qw(PNG JPG TIFF BMP XPM)], 0, 70 ],
save => [-Button => '~save', sub {$app->Save() }],
save_all => [-Button => '~all', sub {$app->SaveAll() }],
remember => [-Button => '~remember', sub {$app->Remember()}],
forget => [-Button => '~forget', sub {$app->Forget() }],
no_phase => [-Button => '~no', sub {$frame->SetValues(amplitude_x => 0, amplitude_y => 0);$app->Repaint()}],
closed_phase => [-Button => '~closed', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 90);$app->Repaint()}],
open_phase => [-Button => '~open', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 180);$app->Repaint()}],
y_invers => [-CheckBox => '~y_inverse', 0, $repaint],
rotation_dir => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(no left right)}], 0, &Wx::wxHORIZONTAL, $repaint),
app_mode => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(lateral rotary free)}], 0, &Wx::wxHORIZONTAL, sub{}),
});
$frame->SetSmartLayout(
{flags => &Wx::wxGROW|&Wx::wxALL},
[ # left part
'<drawboard>',
10,
{border => 10, flags => &Wx::wxALL|&Wx::wxGROW},
'<fav_select>',
['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10, '<remember>'],
],[ # right half
-TabbedBox => [
'~oscillators' =>[
{border => 5, flags => &Wx::wxGROW|&Wx::wxALL},
['~mode :', '<app_mode>'],
-LabeledBox =>['~frequency' =>[qw( <frequency_x> <frequency_y>)]], #<y_invers>
-LabeledBox =>['~start_amp' =>[qw( <amplitude_x> <amplitude_y>),
{border => 5, flags => &Wx::wxALL|&Wx::wxGROW},
['~phase :', 1, '<no_phase>', 1,'<closed_phase>', 1, '<open_phase>'],
]],
-LabeledBox =>[ '~rotation ' =>[qw( <rotation_dir> <rotation> )]],
{border => 10}, '<friction>',
],
'~visuals' => [
{border => 5, flags => &Wx::wxGROW|&Wx::wxALL},
-LabeledBox =>['~line' =>[qw( <length> <density> )]], #<thickness>
-LabeledBox =>['~color' =>[qw( <start_colour> <flow_colour> <scale_colour>)]],
{border => 10},'<zoom>',
],
],
]);
$frame->ResetValues();
$app->Repaint();
$app->SetTopWindow($frame);
1;
Harmonogra
ph
sub OnInit {
my $app = shift;
# load localisation texts in chosen language
my ($v, $dir, $f) = File::Spec->splitpath(__FILE__);
$l18n_file = File::Spec->catfile($dir, $l18n_file) if $dir;
die "localisation file $l18n_file is missing!" unless -e $l18n_file;
my %l18n = %{YAML::Tiny->read( $l18n_file )->[0]{$language}};
$app->{'l18n'} = %l18n;
# loading the numbers of the remembered favorites
$app->{'favorites'} = -e $fav_file ? YAML::Tiny->read( $fav_file ) : YAML::Tiny->new;
my @remembered_pic_names = ref $app->{'favorites'}->[0] eq 'HASH' ? keys $app->{'favorites'}->[0] : ();
# making UI
my $frame = $app->{'frame'} = Wx::Perl::Smart::Frame->new(__PACKAGE__." $VERSION", 'fixed_size');
$frame->SubscribeStrings( $app->{'l18n'} );
my $remember= sub { $frame->SetValues( $app->{'favorites'}[0]{ $_[0]->GetValue() } ); $app->Repaint()};
my $repaint = sub { $app->Repaint() };
my $boardsize = Wx::GetDisplaySize()->GetHeight() - 250;
my $origin_offset = $app->{'origin_offset'} = $boardsize / 2;
my $max_amp = $app->{'max_amp'} = $origin_offset - 10; # max amplitude
my %range_defaults = (# label, min, max, init
frequency_x => ['X', 1, 1, 30], frequency_y => ['Y', 1, 1, 30],
amplitude_x => ['X', 0, 0, 360], amplitude_y => ['Y', 0, 0, 360],
rotation => [$l18n{'amount'}, 1, 0, 30], friction => [$l18n{'friction'}, 0, 0, 200],
length => [$l18n{'length'}, 12, 1, 100], density => [$l18n{'density'},100, 1, 100],
thickness => [$l18n{'thickness'},1, 1, 12], zoom => [$l18n{'zoom'}, 0,-10, 10],
start_colour=> [$l18n{'start'}, 0, 0,1500], flow_colour => [$l18n{'flow'}, 0, 0, 60],
scale_colour=> [$l18n{'scale'}, 1, 1, 4],
);
$frame->SubscribeWidgets
({$_ => Wx::Perl::DisplaySlider->new($frame, @{$range_defaults{$_}}, $repaint)}) for keys %range_defaults;
$frame->SubscribeWidgets({
drawboard => Wx::Perl::DrawMap->new($frame, $boardsize),
fav_select => [-ComboBox => @remembered_pic_names, 0, -1, $remember],
format_select=> [-ComboBox => [qw(PNG JPG TIFF BMP XPM)], 0, 70 ],
save => [-Button => '~save', sub {$app->Save() }],
save_all => [-Button => '~all', sub {$app->SaveAll() }],
remember => [-Button => '~remember', sub {$app->Remember()}],
forget => [-Button => '~forget', sub {$app->Forget() }],
no_phase => [-Button => '~no', sub {$frame->SetValues(amplitude_x => 0, amplitude_y => 0);$app->Repaint()}],
closed_phase => [-Button => '~closed', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 90);$app->Repaint()}],
open_phase => [-Button => '~open', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 180);$app->Repaint()}],
y_invers => [-CheckBox => '~y_inverse', 0, $repaint],
rotation_dir => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(no left right)}], 0, &Wx::wxHORIZONTAL, $repaint),
app_mode => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(lateral rotary free)}], 0, &Wx::wxHORIZONTAL, sub{}),
});
$frame->SetSmartLayout(
{flags => &Wx::wxGROW|&Wx::wxALL},
[ # left part
'<drawboard>',
10,
{border => 10, flags => &Wx::wxALL|&Wx::wxGROW},
'<fav_select>',
['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10, '<remember>'],
],[ # right half
-TabbedBox => [
'~oscillators' =>[
{border => 5, flags => &Wx::wxGROW|&Wx::wxALL},
['~mode :', '<app_mode>'],
-LabeledBox =>['~frequency' =>[qw( <frequency_x> <frequency_y>)]], #<y_invers>
-LabeledBox =>['~start_amp' =>[qw( <amplitude_x> <amplitude_y>),
{border => 5, flags => &Wx::wxALL|&Wx::wxGROW},
['~phase :', 1, '<no_phase>', 1,'<closed_phase>', 1, '<open_phase>'],
]],
-LabeledBox =>[ '~rotation ' =>[qw( <rotation_dir> <rotation> )]],
{border => 10}, '<friction>',
],
'~visuals' => [
{border => 5, flags => &Wx::wxGROW|&Wx::wxALL},
-LabeledBox =>['~line' =>[qw( <length> <density> )]], #<thickness>
-LabeledBox =>['~color' =>[qw( <start_colour> <flow_colour> <scale_colour>)]],
{border => 10},'<zoom>',
],
],
]);
$frame->ResetValues();
$app->Repaint();
$app->SetTopWindow($frame);
1;
Wx::Perl::Smart
sub OnInit {
my $app = shift;
# load localisation texts in chosen language
my ($v, $dir, $f) = File::Spec->splitpath(__FILE__);
$l18n_file = File::Spec->catfile($dir, $l18n_file) if $dir;
die "localisation file $l18n_file is missing!" unless -e $l18n_file;
my %l18n = %{YAML::Tiny->read( $l18n_file )->[0]{$language}};
$app->{'l18n'} = %l18n;
# loading the numbers of the remembered favorites
$app->{'favorites'} = -e $fav_file ? YAML::Tiny->read( $fav_file ) : YAML::Tiny->new;
my @remembered_pic_names = ref $app->{'favorites'}->[0] eq 'HASH' ? keys $app->{'favorites'}->[0] : ();
# making UI
my $frame = $app->{'frame'} = Wx::Perl::Smart::Frame->new(__PACKAGE__." $VERSION", 'fixed_size');
$frame->SubscribeStrings( $app->{'l18n'} );
my $remember= sub { $frame->SetValues( $app->{'favorites'}[0]{ $_[0]->GetValue() } ); $app->Repaint()};
my $repaint = sub { $app->Repaint() };
my $boardsize = Wx::GetDisplaySize()->GetHeight() - 250;
my $origin_offset = $app->{'origin_offset'} = $boardsize / 2;
my $max_amp = $app->{'max_amp'} = $origin_offset - 10; # max amplitude
my %range_defaults = (# label, min, max, init
frequency_x => ['X', 1, 1, 30], frequency_y => ['Y', 1, 1, 30],
amplitude_x => ['X', 0, 0, 360], amplitude_y => ['Y', 0, 0, 360],
rotation => [$l18n{'amount'}, 1, 0, 30], friction => [$l18n{'friction'}, 0, 0, 200],
length => [$l18n{'length'}, 12, 1, 100], density => [$l18n{'density'},100, 1, 100],
thickness => [$l18n{'thickness'},1, 1, 12], zoom => [$l18n{'zoom'}, 0,-10, 10],
start_colour=> [$l18n{'start'}, 0, 0,1500], flow_colour => [$l18n{'flow'}, 0, 0, 60],
scale_colour=> [$l18n{'scale'}, 1, 1, 4],
);
$frame->SubscribeWidgets
({$_ => Wx::Perl::DisplaySlider->new($frame, @{$range_defaults{$_}}, $repaint)}) for keys %range_defaults;
$frame->SubscribeWidgets({
drawboard => Wx::Perl::DrawMap->new($frame, $boardsize),
fav_select => [-ComboBox => @remembered_pic_names, 0, -1, $remember],
format_select=> [-ComboBox => [qw(PNG JPG TIFF BMP XPM)], 0, 70 ],
save => [-Button => '~save', sub {$app->Save() }],
save_all => [-Button => '~all', sub {$app->SaveAll() }],
remember => [-Button => '~remember', sub {$app->Remember()}],
forget => [-Button => '~forget', sub {$app->Forget() }],
no_phase => [-Button => '~no', sub {$frame->SetValues(amplitude_x => 0, amplitude_y => 0);$app->Repaint()}],
closed_phase => [-Button => '~closed', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 90);$app->Repaint()}],
open_phase => [-Button => '~open', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 180);$app->Repaint()}],
y_invers => [-CheckBox => '~y_inverse', 0, $repaint],
rotation_dir => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(no left right)}], 0, &Wx::wxHORIZONTAL, $repaint),
app_mode => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(lateral rotary free)}], 0, &Wx::wxHORIZONTAL, sub{}),
});
$frame->SetSmartLayout(
{flags => &Wx::wxGROW|&Wx::wxALL},
[ # left part
'<drawboard>',
10,
{border => 10, flags => &Wx::wxALL|&Wx::wxGROW},
'<fav_select>',
['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10, '<remember>'],
],[ # right half
-TabbedBox => [
'~oscillators' =>[
{border => 5, flags => &Wx::wxGROW|&Wx::wxALL},
['~mode :', '<app_mode>'],
-LabeledBox =>['~frequency' =>[qw( <frequency_x> <frequency_y>)]], #<y_invers>
-LabeledBox =>['~start_amp' =>[qw( <amplitude_x> <amplitude_y>),
{border => 5, flags => &Wx::wxALL|&Wx::wxGROW},
['~phase :', 1, '<no_phase>', 1,'<closed_phase>', 1, '<open_phase>'],
]],
-LabeledBox =>[ '~rotation ' =>[qw( <rotation_dir> <rotation> )]],
{border => 10}, '<friction>',
],
'~visuals' => [
{border => 5, flags => &Wx::wxGROW|&Wx::wxALL},
-LabeledBox =>['~line' =>[qw( <length> <density> )]], #<thickness>
-LabeledBox =>['~color' =>[qw( <start_colour> <flow_colour> <scale_colour>)]],
{border => 10},'<zoom>',
],
],
]);
$frame->ResetValues();
$app->Repaint();
$app->SetTopWindow($frame);
1;
Wx::Perl::Smart
sub OnInit {
my $app = shift;
# load localisation texts in chosen language
my ($v, $dir, $f) = File::Spec->splitpath(__FILE__);
$l18n_file = File::Spec->catfile($dir, $l18n_file) if $dir;
die "localisation file $l18n_file is missing!" unless -e $l18n_file;
my %l18n = %{YAML::Tiny->read( $l18n_file )->[0]{$language}};
$app->{'l18n'} = %l18n;
# loading the numbers of the remembered favorites
$app->{'favorites'} = -e $fav_file ? YAML::Tiny->read( $fav_file ) : YAML::Tiny->new;
my @remembered_pic_names = ref $app->{'favorites'}->[0] eq 'HASH' ? keys $app->{'favorites'}->[0] : ();
# making UI
my $frame = $app->{'frame'} = Wx::Perl::Smart::Frame->new(__PACKAGE__." $VERSION", 'fixed_size');
$frame->SubscribeStrings( $app->{'l18n'} );
my $remember= sub { $frame->SetValues( $app->{'favorites'}[0]{ $_[0]->GetValue() } ); $app->Repaint()};
my $repaint = sub { $app->Repaint() };
my $boardsize = Wx::GetDisplaySize()->GetHeight() - 250;
my $origin_offset = $app->{'origin_offset'} = $boardsize / 2;
my $max_amp = $app->{'max_amp'} = $origin_offset - 10; # max amplitude
my %range_defaults = (# label, min, max, init
frequency_x => ['X', 1, 1, 30], frequency_y => ['Y', 1, 1, 30],
amplitude_x => ['X', 0, 0, 360], amplitude_y => ['Y', 0, 0, 360],
rotation => [$l18n{'amount'}, 1, 0, 30], friction => [$l18n{'friction'}, 0, 0, 200],
length => [$l18n{'length'}, 12, 1, 100], density => [$l18n{'density'},100, 1, 100],
thickness => [$l18n{'thickness'},1, 1, 12], zoom => [$l18n{'zoom'}, 0,-10, 10],
start_colour=> [$l18n{'start'}, 0, 0,1500], flow_colour => [$l18n{'flow'}, 0, 0, 60],
scale_colour=> [$l18n{'scale'}, 1, 1, 4],
);
$frame->SubscribeWidgets
({$_ => Wx::Perl::DisplaySlider->new($frame, @{$range_defaults{$_}}, $repaint)}) for keys %range_defaults;
$frame->SubscribeWidgets({
drawboard => Wx::Perl::DrawMap->new($frame, $boardsize),
fav_select => [-ComboBox => @remembered_pic_names, 0, -1, $remember],
format_select=> [-ComboBox => [qw(PNG JPG TIFF BMP XPM)], 0, 70 ],
save => [-Button => '~save', sub {$app->Save() }],
save_all => [-Button => '~all', sub {$app->SaveAll() }],
remember => [-Button => '~remember', sub {$app->Remember()}],
forget => [-Button => '~forget', sub {$app->Forget() }],
no_phase => [-Button => '~no', sub {$frame->SetValues(amplitude_x => 0, amplitude_y => 0);$app->Repaint()}],
closed_phase => [-Button => '~closed', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 90);$app->Repaint()}],
open_phase => [-Button => '~open', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 180);$app->Repaint()}],
y_invers => [-CheckBox => '~y_inverse', 0, $repaint],
rotation_dir => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(no left right)}], 0, &Wx::wxHORIZONTAL, $repaint),
app_mode => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(lateral rotary free)}], 0, &Wx::wxHORIZONTAL, sub{}),
});
$frame->SetSmartLayout(
{flags => &Wx::wxGROW|&Wx::wxALL},
[ # left part
'<drawboard>',
10,
{border => 10, flags => &Wx::wxALL|&Wx::wxGROW},
'<fav_select>',
['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10, '<remember>'],
],[ # right half
-TabbedBox => [
'~oscillators' =>[
{border => 5, flags => &Wx::wxGROW|&Wx::wxALL},
['~mode :', '<app_mode>'],
-LabeledBox =>['~frequency' =>[qw( <frequency_x> <frequency_y>)]], #<y_invers>
-LabeledBox =>['~start_amp' =>[qw( <amplitude_x> <amplitude_y>),
{border => 5, flags => &Wx::wxALL|&Wx::wxGROW},
['~phase :', 1, '<no_phase>', 1,'<closed_phase>', 1, '<open_phase>'],
]],
-LabeledBox =>[ '~rotation ' =>[qw( <rotation_dir> <rotation> )]],
{border => 10}, '<friction>',
],
'~visuals' => [
{border => 5, flags => &Wx::wxGROW|&Wx::wxALL},
-LabeledBox =>['~line' =>[qw( <length> <density> )]], #<thickness>
-LabeledBox =>['~color' =>[qw( <start_colour> <flow_colour> <scale_colour>)]],
{border => 10},'<zoom>',
],
],
]);
$frame->ResetValues();
$app->Repaint();
$app->SetTopWindow($frame);
1;
Wx::Perl::Smart
Wx::Perl::Smart::Frame
Wx::Perl::Smart::Dialog
Wx::Perl::Smart::Panel
Wx::Perl::Smart::Sizer
Wx::Perl::Smart::WidgetFactory
Nucleus
Wx::Perl::Smart::Panel
Wx::Perl::Smart::Sizer
aus Kephra
Kephra::App::Panel
Kephra::App::Sizer
KephraXP
K. GUI Libs
Kephra::App::Editor
Kephra::App::Dialog
Kephra::App::DocBar
Kephra::App::Focus
Kephra::App::Panel
Kephra::App::Sizer
Kephra::App::Splitter
Kephra::App::Window
Kephra::App::Util
'kleine Projekte'
App::Harmonograph
App::Spirograph
Trigon
Fraktalzeichner
Games:Sudoku::Algosolver
Wx::Perl::Smart
In 5 Schritten
zur Intelligenz
Wx::Perl::Smart
Widgets
Komposition
Abstraktion
Das sind nur 3
Widgets
Komposition
Abstraktion
Jetzt sind es 5
Wid gets
Komposition
Abstr aktion
Wx::Perl::Smart
Wid gets
Komposition
Abstr aktion
Nummer 1
einfach & sichere
Widgeterzeugung
Nummer 2
mächtige Widgets
Wx::Perl::*
mächtige Widgets
Nummer 3
leicht änderbar,
kompakte
Komposition
Nummer 4
Trennung von
Daten & Layout
Nummer 5
MVC – GUI Layer
GUI Comp. Lang.
MVC – GUI Layer
Wx::Perl::Smart
Wid gets
Komposition
Abstr aktion
Schritt 1
Einzelne
Widgets
Einzelne Widgets
Wx::Button
Wx::Button->
new(..., ..., ...)
Erzeugen
$parent $frame
ID -1
$label wxEmptyString,
wxPoint wxDefaultPosition, [-1,-1]
wxSize& size = wxDefaultSize, [-1,-1]
style 0,
wxValidator,
wxString $name
New Parameter
$button = Wx::Button->new(
$parent, -1, 'label', [-1,-1], [30,-1]);
Wx::Event::EVT_BUTTON
($frame, $button, &callback);
Button Erzeugen
Wx::Perl::Button
($parent, 'label', &callback, 30);
Smart Button
Wx::Perl::Button
($parent, 'label', &callback, 30);
# required , opt
Smart Button
wxWindow* parent,
wxWindowID id,
wxString& value,
wxPoint& pos,
wxSize& size,
long style,
wxValidator& (validator),
wxString& name,
Textc. Parameter
$txt = Wx::TextCtrl->new(
$parent, -1, 'content', [-1,-1], [30,-1],
&Wx::wxTE_MULTILINE
Wx::Perl::TextValidator->new (qr//));
Wx::Event::EVT_KEY_DOWN
($txt, -1, &callback);
Wx::Event::EVT_TEXT
($frame, $txt, &callback);
TextCtrlErzeugen
$txt = Wx::Perl::TextEdit->new(
$pa,'content',&callback,qr/.../,[30,-1]);
Smart TextEdit
$txt = Wx::Perl::TextEdit->new(
$pa,'content',&callback,qr/.../,[30,-1]);
# required ,opt
Smart TextEdit
weglassen was nicht wichtig ist
nimmt hinzu was wichtig wäre
optional auch mit benannten Param.
Def als Code oder String (compilien)
alles normalen Widgets (Moose)
Wx::Perl::Button ... kommt vielleicht
Einzelne Widgets
weglassen was nicht wichtig ist
Einzelne Widgets
weglassen was nicht wichtig ist
Perl hat besseres
ObjRef statt WxID | WidgetName
Einzelne Widgets
weglassen was nicht wichtig ist
Weil du es nicht kontrollieren willst
Position und Größe regeln Sizer
Einzelne Widgets
weglassen was nicht wichtig ist
Weil es Probleme macht
auf undef gesetzte parents
Einzelne Widgets
weglassen was nicht wichtig ist
nimmt hinzu was wichtig wäre
callbacks (coderef)
Einzelne Widgets
weglassen was nicht wichtig ist
nimmt hinzu was wichtig wäre
callbacks (coderef) & zus. styles
Einzelne Widgets
weglassen was nicht wichtig ist
nimmt hinzu was wichtig wäre
optional auch mit benannten Param.
Def als Code oder String (compilien)
alles normalen Widgets (Moose)
Wx::Perl::Button ... kommt vielleicht
Einzelne Widgets
weglassen was nicht wichtig ist
nimmt hinzu was wichtig wäre
optional auch mit benannten Param.
Def als Code oder String (compilien)
alles normalen Widgets (Moose)
Wx::Perl::Button ... kommt vielleicht
Einzelne Widgets
weglassen was nicht wichtig ist
nimmt hinzu was wichtig wäre
optional auch mit benannten Param.
Def als code oder String (compilien)
alles normalen Widgets (Moose)
Wx::Perl::Button ... kommt vielleicht
Einzelne Widgets
weglassen was nicht wichtig ist
nimmt hinzu was wichtig wäre
optional auch mit benannten Param.
Def als code oder String (compilien)
alles normalen Widgets (Moose)
Wx::Perl::Button ... kommt vielleicht
Einzelne Widgets
weglassen was nicht wichtig ist
nimmt hinzu was wichtig wäre
optional auch mit benannten Param.
Def als code oder String (compilien)
alles normalen Widgets (Moose)
Wx::Perl::Button ... kommt vielleicht
Einzelne Widgets
Wx::Perl::Button
($parent, 'label', &callback, 30);
neues Modul für den einen Aufruf
Softwarearchitektur: factory method
Smart Button ?
Wx::Perl::Button
($parent, 'label', &callback, 30);
neues Modul für den einen Aufruf
Softwarearchitektur: factory method
Smart Button ?
@widgets = factory method([
[-Button => 'label', &callback, 30],
…
]);
Smart Factory
@widgets = $factory->MakeWidget([
[-Button => 'label', &callback, 30],
{widget => 'Button', label =>'...', },
]);
Benannte Param.
$factory = Wx::Perl::Smart::
WidgetFactory->new($parent);
Kürzt Aufruf
$factory = Wx::Perl::Smart::
WidgetFactory->new($parent);
Wx::Perl::Smart::WidgetFactory->
MakeWidget([ ….
Und vermeidet
im Sinne einer Factory Method
erzeugt normale Widgets & weitere
Smart Factory
Schritt 2
Zusammen-
gesetzte
Widgets
Zusam. Widgets
RadioButtons
TextSliders
Zusam. Widgets
sammle mehrere Einzelwidgets
und deren Daten & Event-
handling in ein Widget
einfacherer Umgang,
Layout wird übersichtlicher
Schritt 3
Komposition
Komposition
Wx::Perl::Smart::Util
Wx::Perl::Smart::WidgetFactory
Wx::Perl::Smart::Sizer
Wx::Perl::Smart::Panel
Wx::Perl::Smart::Frame
Wx::Perl::Smart::Dialog
Komposition
Wx::Perl::Smart::WidgetFactory
Wx::Perl::Smart::Sizer
Wx::Perl::Smart::Panel
Wx::Perl::Smart::Frame
:WidgetFactory
einfache, robuste Erzeugung
in Tabellenanordnung
Trennung vom GUI-Layout
keine Daten ins Layout
strukturierte Programme
:WidgetFactory
einfache, robuste Erzeugung
in Tabellenanordnung
Trennung vom GUI-Layout
keine Daten ins Layout
strukturierte Programme
Komposition
Wx::Perl::Smart::WidgetFactory
Wx::Perl::Smart::Sizer
Wx::Perl::Smart::Panel
Wx::Perl::Smart::Frame
::Smart::Sizer
einfache und robuste Erzeugung
Erzeugung von Deko-Widgets
Kommentare
mehr Abstraktion (tabs = Sizer)
einfache und effektive Benutzung
::Smart::Sizer
einfache und robuste Erzeugung
Erzeugung von Deko-Widgets
Kommentare
mehr Abstraktion (tabs = Sizer)
einfache und effektive Benutzung
::Smart::Sizer
einfache und robuste Erzeugung
$sizer = Wx::Perl::Smart::Sizer-
>new([$widget, $widget, ...]);
::Smart::Sizer
einfache und robuste Erzeugung
Erzeugung von Deko-Widgets
Kommentare
mehr Abstraktion (tabs = Sizer)
einfache und effektive Benutzung
::Smart::Sizer
Erzeugung von Deko-Widgets
$sizer = Wx::Perl::Smart::Sizer-
>new([$widget, '---', $widget, ...]);
::Smart::Sizer
einfache und robuste Erzeugung
Erzeugung von Deko-Widgets
Kommentare
mehr Abstraktion (tabs = Sizer)
einfache und effektive Benutzung
::Smart::Sizer
einfache und robuste Erzeugung
Erzeugung von Deko-Widgets
Kommentare
mehr Abstraktion (tabs = Sizer)
einfache und effektive Benutzung
::Smart::Sizer
$sizer = Wx::Perl::Smart::Sizer-
>new(-TabbedBox =>
[ [$widget, ...], [...]]);
mehr Abstraktion (tabs = Sizer)
::Smart::Sizer
einfache und robuste Erzeugung
Erzeugung von Deko-Widgets
Kommentare
mehr Abstraktion (tabs = Sizer)
einfache und effektive Benutzung
::Smart::Sizer
einfache und robuste Erzeugung
Erzeugung von Deko-Widgets
Kommentare
mehr Abstraktion (tabs = Sizer)
einfache und effektive Benutzung
Komposition
Wx::Perl::Smart::WidgetFactory
Wx::Perl::Smart::Sizer
Wx::Perl::Smart::Panel
Wx::Perl::Smart::Frame
::Smart::Panel
Panel mit Smart::Sizer
::Smart::Panel
Panel mit Smart::Sizer
$panel = Wx::Perl::Smart::Panel-
>new([$widget, $widget, ...]);
::Smart::Panel
Panel mit Smart::Sizer
Sichbarkeit und Verwandschaft
wird automatisch geregelt
Komposition
Wx::Perl::Smart::WidgetFactory
Wx::Perl::Smart::Sizer
Wx::Perl::Smart::Panel
Wx::Perl::Smart::Frame
::Smart::Frame
Hauptenster einer App
noch eine Abstraktion
vereinfachter Zugriff auf Panel,
Sizer und WidgetFactory
verwaltet auch Widgets und
Localisationstrings
Widgets mit ID
$frame->MakeWidgets({
drawboard => Wx::Perl::Draw...
fav_select => [-ComboBox => ..]
def Layout
$frame->EvalSmartLayout (
{flags => &Wx::wxGROW|&Wx::wxALL},
[ '<drawboard>',
10,
'<fav_select>',
['<format_select>', 10,'<save>', 10,
'<save_all>', 1, '<forget>', 10,...],
ohne Ränder
$frame->EvalSmartLayout (
[ '<drawboard>',
'<fav_select>',
['<format_select>', '<save>',
'<save_all>', 1, '<forget>', ...],
Panel mit ID
$frame->EvalSmartPanel ( 'my_panel' =>
[ '<drawboard>',
10,
'<fav_select>',
['<format_select>', 10,'<save>', 10,
'<save_all>', 1, '<forget>', 10,...],
NutzewieWidget
$frame->EvalSmartLayout (
[ '<my_panel>',
'<fav_select>',
['<format_select>', '<save>',
'<save_all>', 1, '<forget>', ...],
Smart>GUIDesigner
''can't touch this'
Smart>GUIDesigner
Designercode darf nicht
berührt werden
Smart>GUIDesigner
Brauch mehrere
Programme / Formate
Smart>GUIDesigner
Smart ist schneller
effektiver als GUI
Smart>GUIDesigner
Smart ist schneller
effektiver als GUI
änder Abstandsklassen
Smart>GUIDesigner
Smart ist schneller
effektiver als GUI
denk in Proportionen
Komponenten
Wx::Perl::Smart::Util
Wx::Perl::Smart::WidgetFactory
Wx::Perl::Smart::Sizer
Wx::Perl::Smart::Panel
Wx::Perl::Smart::Frame
Wx::Perl::Smart::Dialog
Gen Comp Abstr
Wx::Perl::Smart::Util
Wx::Perl::*
Wx::Perl::Smart::WidgetFactory
Wx::Perl::Smart::Sizer
Wx::Perl::Smart::Panel
Wx::Perl::Smart::Frame
Wx::Perl::Smart::Dialog
Zukunft
Templates
Schablonen
Werte
Events
Schritt 5
Abstraktion
GCL
GUI
Composition
Lang
Abstraktion
Wikiformat für's layout
(oft besser als GUI designer)
kompiliert zu Datenstruktur
(jedes Format funktioniert)
kompiliert zu GUI
andere Backends denkbar
(GCL::Prima, GCL::GTK)
Abstraktion
Wikiformat für's layout
(oft besser als GUI designer)
kompiliert zu Datenstruktur
(jedes Format funktioniert)
kompiliert zu GUI
andere Backends denkbar
(GCL::Prima, GCL::GTK)
Abstraktion
Wikiformat für's layout
(oft besser als GUI designer)
kompiliert zu Datenstruktur
(jedes Format funktioniert)
kompiliert zu GUI
andere Backends denkbar
(GCL::Prima, GCL::GTK)
Abstraktion
Wikiformat für's layout
(oft besser als GUI designer)
kompiliert zu Datenstruktur
(jedes Format funktioniert)
kompiliert zu GUI
andere Backends denkbar
(GCL::Prima, GCL::GTK)
Danke

Más contenido relacionado

La actualidad más candente

Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6garux
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation TutorialLorna Mitchell
 
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2Functional Pe(a)rls version 2
Functional Pe(a)rls version 2osfameron
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perlgarux
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In PerlKang-min Liu
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a bossgsterndale
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Kang-min Liu
 
Learning Perl 6
Learning Perl 6 Learning Perl 6
Learning Perl 6 brian d foy
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)Nikita Popov
 
What's New in Perl? v5.10 - v5.16
What's New in Perl?  v5.10 - v5.16What's New in Perl?  v5.10 - v5.16
What's New in Perl? v5.10 - v5.16Ricardo Signes
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Jeff Carouth
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?Nikita Popov
 
Class 4 - PHP Arrays
Class 4 - PHP ArraysClass 4 - PHP Arrays
Class 4 - PHP ArraysAhmed Swilam
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?osfameron
 
OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersLin Yo-An
 
Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Lin Yo-An
 

La actualidad más candente (20)

Perl6 in-production
Perl6 in-productionPerl6 in-production
Perl6 in-production
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation Tutorial
 
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
 
Perl6 one-liners
Perl6 one-linersPerl6 one-liners
Perl6 one-liners
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perl
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
Learning Perl 6
Learning Perl 6 Learning Perl 6
Learning Perl 6
 
PHP PPT FILE
PHP PPT FILEPHP PPT FILE
PHP PPT FILE
 
PHP and MySQL
PHP and MySQLPHP and MySQL
PHP and MySQL
 
PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)PHP 7 – What changed internally? (Forum PHP 2015)
PHP 7 – What changed internally? (Forum PHP 2015)
 
What's New in Perl? v5.10 - v5.16
What's New in Perl?  v5.10 - v5.16What's New in Perl?  v5.10 - v5.16
What's New in Perl? v5.10 - v5.16
 
Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4Can't Miss Features of PHP 5.3 and 5.4
Can't Miss Features of PHP 5.3 and 5.4
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?
 
Class 4 - PHP Arrays
Class 4 - PHP ArraysClass 4 - PHP Arrays
Class 4 - PHP Arrays
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?
 
OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP haters
 
Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015
 

Similar a Harmonograph GUI Builder

Crazy things done on PHP
Crazy things done on PHPCrazy things done on PHP
Crazy things done on PHPTaras Kalapun
 
PHP for Python Developers
PHP for Python DevelopersPHP for Python Developers
PHP for Python DevelopersCarlos Vences
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Masahiro Nagano
 
Crafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::ExporterCrafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::ExporterRicardo Signes
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackVic Metcalfe
 
循環参照のはなし
循環参照のはなし循環参照のはなし
循環参照のはなしMasahiro Honma
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegamehozayfa999
 
Php my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netPhp my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netProgrammer Blog
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsDavid Golden
 
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...Mateusz Zalewski
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapHoward Lewis Ship
 
There's more than one way to empty it
There's more than one way to empty itThere's more than one way to empty it
There's more than one way to empty itAndrew Shitov
 
redis überall
redis überallredis überall
redis überallzucaritask
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongersbrian d foy
 

Similar a Harmonograph GUI Builder (20)

Crazy things done on PHP
Crazy things done on PHPCrazy things done on PHP
Crazy things done on PHP
 
PHP for Python Developers
PHP for Python DevelopersPHP for Python Developers
PHP for Python Developers
 
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
Designing Opeation Oriented Web Applications / YAPC::Asia Tokyo 2011
 
Crafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::ExporterCrafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::Exporter
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: Hack
 
循環参照のはなし
循環参照のはなし循環参照のはなし
循環参照のはなし
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegame
 
Ns2programs
Ns2programsNs2programs
Ns2programs
 
Php functions
Php functionsPhp functions
Php functions
 
distill
distilldistill
distill
 
Bag of tricks
Bag of tricksBag of tricks
Bag of tricks
 
Php my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netPhp my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.net
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order Functions
 
wget.pl
wget.plwget.pl
wget.pl
 
Intermediate PHP
Intermediate PHPIntermediate PHP
Intermediate PHP
 
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
[PHPCon 2023] “Kto to pisał?!... a, to ja.”, czyli sposoby żeby znienawidzić ...
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter Bootstrap
 
There's more than one way to empty it
There's more than one way to empty itThere's more than one way to empty it
There's more than one way to empty it
 
redis überall
redis überallredis überall
redis überall
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongers
 

Más de lichtkind

Perl 5.20: Feature, Kultur, Module, Werkzeuge
Perl 5.20: Feature, Kultur, Module, WerkzeugePerl 5.20: Feature, Kultur, Module, Werkzeuge
Perl 5.20: Feature, Kultur, Module, Werkzeugelichtkind
 
P6kontext2014
P6kontext2014P6kontext2014
P6kontext2014lichtkind
 
Complete Programming
Complete ProgrammingComplete Programming
Complete Programminglichtkind
 
P6 OO vs Moose (&Moo)
P6 OO vs Moose (&Moo)P6 OO vs Moose (&Moo)
P6 OO vs Moose (&Moo)lichtkind
 
Perl 5 Quiz Chemnitz Edition
Perl 5 Quiz Chemnitz EditionPerl 5 Quiz Chemnitz Edition
Perl 5 Quiz Chemnitz Editionlichtkind
 
Writing Perl 6 Rx
Writing Perl 6 RxWriting Perl 6 Rx
Writing Perl 6 Rxlichtkind
 
Wundertüte Perl
Wundertüte PerlWundertüte Perl
Wundertüte Perllichtkind
 
Perl 6 Regex und Grammars
Perl 6 Regex und GrammarsPerl 6 Regex und Grammars
Perl 6 Regex und Grammarslichtkind
 
Perl 6 Datastructures
Perl 6 DatastructuresPerl 6 Datastructures
Perl 6 Datastructureslichtkind
 
Perl 6 Datenstrukturen
Perl 6 DatenstrukturenPerl 6 Datenstrukturen
Perl 6 Datenstrukturenlichtkind
 
Document Driven Development
Document Driven DevelopmentDocument Driven Development
Document Driven Developmentlichtkind
 
Modern wx perl
Modern wx perlModern wx perl
Modern wx perllichtkind
 
Bettereditors
BettereditorsBettereditors
Bettereditorslichtkind
 
Was können wir von Rebol lernen?
Was können wir von Rebol lernen?Was können wir von Rebol lernen?
Was können wir von Rebol lernen?lichtkind
 
Perl Testing
Perl TestingPerl Testing
Perl Testinglichtkind
 
Perl in der Wiki
Perl in der WikiPerl in der Wiki
Perl in der Wikilichtkind
 
What is Kephra about?
What is Kephra about?What is Kephra about?
What is Kephra about?lichtkind
 

Más de lichtkind (20)

Perl 5.20: Feature, Kultur, Module, Werkzeuge
Perl 5.20: Feature, Kultur, Module, WerkzeugePerl 5.20: Feature, Kultur, Module, Werkzeuge
Perl 5.20: Feature, Kultur, Module, Werkzeuge
 
P6kontext2014
P6kontext2014P6kontext2014
P6kontext2014
 
Complete Programming
Complete ProgrammingComplete Programming
Complete Programming
 
P6 OO vs Moose (&Moo)
P6 OO vs Moose (&Moo)P6 OO vs Moose (&Moo)
P6 OO vs Moose (&Moo)
 
Perl 5 Quiz Chemnitz Edition
Perl 5 Quiz Chemnitz EditionPerl 5 Quiz Chemnitz Edition
Perl 5 Quiz Chemnitz Edition
 
P6oo
P6ooP6oo
P6oo
 
Writing Perl 6 Rx
Writing Perl 6 RxWriting Perl 6 Rx
Writing Perl 6 Rx
 
Wundertüte Perl
Wundertüte PerlWundertüte Perl
Wundertüte Perl
 
Perl 6 Regex und Grammars
Perl 6 Regex und GrammarsPerl 6 Regex und Grammars
Perl 6 Regex und Grammars
 
Perl 6 Datastructures
Perl 6 DatastructuresPerl 6 Datastructures
Perl 6 Datastructures
 
Perl 6 Datenstrukturen
Perl 6 DatenstrukturenPerl 6 Datenstrukturen
Perl 6 Datenstrukturen
 
Document Driven Development
Document Driven DevelopmentDocument Driven Development
Document Driven Development
 
Modern wx perl
Modern wx perlModern wx perl
Modern wx perl
 
Bettereditors
BettereditorsBettereditors
Bettereditors
 
Hgit
HgitHgit
Hgit
 
Was können wir von Rebol lernen?
Was können wir von Rebol lernen?Was können wir von Rebol lernen?
Was können wir von Rebol lernen?
 
Neuperl6
Neuperl6Neuperl6
Neuperl6
 
Perl Testing
Perl TestingPerl Testing
Perl Testing
 
Perl in der Wiki
Perl in der WikiPerl in der Wiki
Perl in der Wiki
 
What is Kephra about?
What is Kephra about?What is Kephra about?
What is Kephra about?
 

Último

英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 

Último (20)

英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 

Harmonograph GUI Builder

  • 6. Wx::Perl::Smart sub OnInit { my $app = shift; # load localisation texts in chosen language my ($v, $dir, $f) = File::Spec->splitpath(__FILE__); $l18n_file = File::Spec->catfile($dir, $l18n_file) if $dir; die "localisation file $l18n_file is missing!" unless -e $l18n_file; my %l18n = %{YAML::Tiny->read( $l18n_file )->[0]{$language}}; $app->{'l18n'} = %l18n; # loading the numbers of the remembered favorites $app->{'favorites'} = -e $fav_file ? YAML::Tiny->read( $fav_file ) : YAML::Tiny->new; my @remembered_pic_names = ref $app->{'favorites'}->[0] eq 'HASH' ? keys $app->{'favorites'}->[0] : (); # making UI my $frame = $app->{'frame'} = Wx::Perl::Smart::Frame->new(__PACKAGE__." $VERSION", 'fixed_size'); $frame->SubscribeStrings( $app->{'l18n'} ); my $remember= sub { $frame->SetValues( $app->{'favorites'}[0]{ $_[0]->GetValue() } ); $app->Repaint()}; my $repaint = sub { $app->Repaint() }; my $boardsize = Wx::GetDisplaySize()->GetHeight() - 250; my $origin_offset = $app->{'origin_offset'} = $boardsize / 2; my $max_amp = $app->{'max_amp'} = $origin_offset - 10; # max amplitude my %range_defaults = (# label, min, max, init frequency_x => ['X', 1, 1, 30], frequency_y => ['Y', 1, 1, 30], amplitude_x => ['X', 0, 0, 360], amplitude_y => ['Y', 0, 0, 360], rotation => [$l18n{'amount'}, 1, 0, 30], friction => [$l18n{'friction'}, 0, 0, 200], length => [$l18n{'length'}, 12, 1, 100], density => [$l18n{'density'},100, 1, 100], thickness => [$l18n{'thickness'},1, 1, 12], zoom => [$l18n{'zoom'}, 0,-10, 10], start_colour=> [$l18n{'start'}, 0, 0,1500], flow_colour => [$l18n{'flow'}, 0, 0, 60], scale_colour=> [$l18n{'scale'}, 1, 1, 4], ); $frame->SubscribeWidgets ({$_ => Wx::Perl::DisplaySlider->new($frame, @{$range_defaults{$_}}, $repaint)}) for keys %range_defaults; $frame->SubscribeWidgets({ drawboard => Wx::Perl::DrawMap->new($frame, $boardsize), fav_select => [-ComboBox => @remembered_pic_names, 0, -1, $remember], format_select=> [-ComboBox => [qw(PNG JPG TIFF BMP XPM)], 0, 70 ], save => [-Button => '~save', sub {$app->Save() }], save_all => [-Button => '~all', sub {$app->SaveAll() }], remember => [-Button => '~remember', sub {$app->Remember()}], forget => [-Button => '~forget', sub {$app->Forget() }], no_phase => [-Button => '~no', sub {$frame->SetValues(amplitude_x => 0, amplitude_y => 0);$app->Repaint()}], closed_phase => [-Button => '~closed', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 90);$app->Repaint()}], open_phase => [-Button => '~open', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 180);$app->Repaint()}], y_invers => [-CheckBox => '~y_inverse', 0, $repaint], rotation_dir => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(no left right)}], 0, &Wx::wxHORIZONTAL, $repaint), app_mode => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(lateral rotary free)}], 0, &Wx::wxHORIZONTAL, sub{}), }); $frame->SetSmartLayout( {flags => &Wx::wxGROW|&Wx::wxALL}, [ # left part '<drawboard>', 10, {border => 10, flags => &Wx::wxALL|&Wx::wxGROW}, '<fav_select>', ['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10, '<remember>'], ],[ # right half -TabbedBox => [ '~oscillators' =>[ {border => 5, flags => &Wx::wxGROW|&Wx::wxALL}, ['~mode :', '<app_mode>'], -LabeledBox =>['~frequency' =>[qw( <frequency_x> <frequency_y>)]], #<y_invers> -LabeledBox =>['~start_amp' =>[qw( <amplitude_x> <amplitude_y>), {border => 5, flags => &Wx::wxALL|&Wx::wxGROW}, ['~phase :', 1, '<no_phase>', 1,'<closed_phase>', 1, '<open_phase>'], ]], -LabeledBox =>[ '~rotation ' =>[qw( <rotation_dir> <rotation> )]], {border => 10}, '<friction>', ], '~visuals' => [ {border => 5, flags => &Wx::wxGROW|&Wx::wxALL}, -LabeledBox =>['~line' =>[qw( <length> <density> )]], #<thickness> -LabeledBox =>['~color' =>[qw( <start_colour> <flow_colour> <scale_colour>)]], {border => 10},'<zoom>', ], ], ]); $frame->ResetValues(); $app->Repaint(); $app->SetTopWindow($frame); 1;
  • 7. Harmonogra ph sub OnInit { my $app = shift; # load localisation texts in chosen language my ($v, $dir, $f) = File::Spec->splitpath(__FILE__); $l18n_file = File::Spec->catfile($dir, $l18n_file) if $dir; die "localisation file $l18n_file is missing!" unless -e $l18n_file; my %l18n = %{YAML::Tiny->read( $l18n_file )->[0]{$language}}; $app->{'l18n'} = %l18n; # loading the numbers of the remembered favorites $app->{'favorites'} = -e $fav_file ? YAML::Tiny->read( $fav_file ) : YAML::Tiny->new; my @remembered_pic_names = ref $app->{'favorites'}->[0] eq 'HASH' ? keys $app->{'favorites'}->[0] : (); # making UI my $frame = $app->{'frame'} = Wx::Perl::Smart::Frame->new(__PACKAGE__." $VERSION", 'fixed_size'); $frame->SubscribeStrings( $app->{'l18n'} ); my $remember= sub { $frame->SetValues( $app->{'favorites'}[0]{ $_[0]->GetValue() } ); $app->Repaint()}; my $repaint = sub { $app->Repaint() }; my $boardsize = Wx::GetDisplaySize()->GetHeight() - 250; my $origin_offset = $app->{'origin_offset'} = $boardsize / 2; my $max_amp = $app->{'max_amp'} = $origin_offset - 10; # max amplitude my %range_defaults = (# label, min, max, init frequency_x => ['X', 1, 1, 30], frequency_y => ['Y', 1, 1, 30], amplitude_x => ['X', 0, 0, 360], amplitude_y => ['Y', 0, 0, 360], rotation => [$l18n{'amount'}, 1, 0, 30], friction => [$l18n{'friction'}, 0, 0, 200], length => [$l18n{'length'}, 12, 1, 100], density => [$l18n{'density'},100, 1, 100], thickness => [$l18n{'thickness'},1, 1, 12], zoom => [$l18n{'zoom'}, 0,-10, 10], start_colour=> [$l18n{'start'}, 0, 0,1500], flow_colour => [$l18n{'flow'}, 0, 0, 60], scale_colour=> [$l18n{'scale'}, 1, 1, 4], ); $frame->SubscribeWidgets ({$_ => Wx::Perl::DisplaySlider->new($frame, @{$range_defaults{$_}}, $repaint)}) for keys %range_defaults; $frame->SubscribeWidgets({ drawboard => Wx::Perl::DrawMap->new($frame, $boardsize), fav_select => [-ComboBox => @remembered_pic_names, 0, -1, $remember], format_select=> [-ComboBox => [qw(PNG JPG TIFF BMP XPM)], 0, 70 ], save => [-Button => '~save', sub {$app->Save() }], save_all => [-Button => '~all', sub {$app->SaveAll() }], remember => [-Button => '~remember', sub {$app->Remember()}], forget => [-Button => '~forget', sub {$app->Forget() }], no_phase => [-Button => '~no', sub {$frame->SetValues(amplitude_x => 0, amplitude_y => 0);$app->Repaint()}], closed_phase => [-Button => '~closed', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 90);$app->Repaint()}], open_phase => [-Button => '~open', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 180);$app->Repaint()}], y_invers => [-CheckBox => '~y_inverse', 0, $repaint], rotation_dir => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(no left right)}], 0, &Wx::wxHORIZONTAL, $repaint), app_mode => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(lateral rotary free)}], 0, &Wx::wxHORIZONTAL, sub{}), }); $frame->SetSmartLayout( {flags => &Wx::wxGROW|&Wx::wxALL}, [ # left part '<drawboard>', 10, {border => 10, flags => &Wx::wxALL|&Wx::wxGROW}, '<fav_select>', ['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10, '<remember>'], ],[ # right half -TabbedBox => [ '~oscillators' =>[ {border => 5, flags => &Wx::wxGROW|&Wx::wxALL}, ['~mode :', '<app_mode>'], -LabeledBox =>['~frequency' =>[qw( <frequency_x> <frequency_y>)]], #<y_invers> -LabeledBox =>['~start_amp' =>[qw( <amplitude_x> <amplitude_y>), {border => 5, flags => &Wx::wxALL|&Wx::wxGROW}, ['~phase :', 1, '<no_phase>', 1,'<closed_phase>', 1, '<open_phase>'], ]], -LabeledBox =>[ '~rotation ' =>[qw( <rotation_dir> <rotation> )]], {border => 10}, '<friction>', ], '~visuals' => [ {border => 5, flags => &Wx::wxGROW|&Wx::wxALL}, -LabeledBox =>['~line' =>[qw( <length> <density> )]], #<thickness> -LabeledBox =>['~color' =>[qw( <start_colour> <flow_colour> <scale_colour>)]], {border => 10},'<zoom>', ], ], ]); $frame->ResetValues(); $app->Repaint(); $app->SetTopWindow($frame); 1;
  • 8. Harmonogra ph sub OnInit { my $app = shift; # load localisation texts in chosen language my ($v, $dir, $f) = File::Spec->splitpath(__FILE__); $l18n_file = File::Spec->catfile($dir, $l18n_file) if $dir; die "localisation file $l18n_file is missing!" unless -e $l18n_file; my %l18n = %{YAML::Tiny->read( $l18n_file )->[0]{$language}}; $app->{'l18n'} = %l18n; # loading the numbers of the remembered favorites $app->{'favorites'} = -e $fav_file ? YAML::Tiny->read( $fav_file ) : YAML::Tiny->new; my @remembered_pic_names = ref $app->{'favorites'}->[0] eq 'HASH' ? keys $app->{'favorites'}->[0] : (); # making UI my $frame = $app->{'frame'} = Wx::Perl::Smart::Frame->new(__PACKAGE__." $VERSION", 'fixed_size'); $frame->SubscribeStrings( $app->{'l18n'} ); my $remember= sub { $frame->SetValues( $app->{'favorites'}[0]{ $_[0]->GetValue() } ); $app->Repaint()}; my $repaint = sub { $app->Repaint() }; my $boardsize = Wx::GetDisplaySize()->GetHeight() - 250; my $origin_offset = $app->{'origin_offset'} = $boardsize / 2; my $max_amp = $app->{'max_amp'} = $origin_offset - 10; # max amplitude my %range_defaults = (# label, min, max, init frequency_x => ['X', 1, 1, 30], frequency_y => ['Y', 1, 1, 30], amplitude_x => ['X', 0, 0, 360], amplitude_y => ['Y', 0, 0, 360], rotation => [$l18n{'amount'}, 1, 0, 30], friction => [$l18n{'friction'}, 0, 0, 200], length => [$l18n{'length'}, 12, 1, 100], density => [$l18n{'density'},100, 1, 100], thickness => [$l18n{'thickness'},1, 1, 12], zoom => [$l18n{'zoom'}, 0,-10, 10], start_colour=> [$l18n{'start'}, 0, 0,1500], flow_colour => [$l18n{'flow'}, 0, 0, 60], scale_colour=> [$l18n{'scale'}, 1, 1, 4], ); $frame->SubscribeWidgets ({$_ => Wx::Perl::DisplaySlider->new($frame, @{$range_defaults{$_}}, $repaint)}) for keys %range_defaults; $frame->SubscribeWidgets({ drawboard => Wx::Perl::DrawMap->new($frame, $boardsize), fav_select => [-ComboBox => @remembered_pic_names, 0, -1, $remember], format_select=> [-ComboBox => [qw(PNG JPG TIFF BMP XPM)], 0, 70 ], save => [-Button => '~save', sub {$app->Save() }], save_all => [-Button => '~all', sub {$app->SaveAll() }], remember => [-Button => '~remember', sub {$app->Remember()}], forget => [-Button => '~forget', sub {$app->Forget() }], no_phase => [-Button => '~no', sub {$frame->SetValues(amplitude_x => 0, amplitude_y => 0);$app->Repaint()}], closed_phase => [-Button => '~closed', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 90);$app->Repaint()}], open_phase => [-Button => '~open', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 180);$app->Repaint()}], y_invers => [-CheckBox => '~y_inverse', 0, $repaint], rotation_dir => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(no left right)}], 0, &Wx::wxHORIZONTAL, $repaint), app_mode => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(lateral rotary free)}], 0, &Wx::wxHORIZONTAL, sub{}), }); $frame->SetSmartLayout( {flags => &Wx::wxGROW|&Wx::wxALL}, [ # left part '<drawboard>', 10, {border => 10, flags => &Wx::wxALL|&Wx::wxGROW}, '<fav_select>', ['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10, '<remember>'], ],[ # right half -TabbedBox => [ '~oscillators' =>[ {border => 5, flags => &Wx::wxGROW|&Wx::wxALL}, ['~mode :', '<app_mode>'], -LabeledBox =>['~frequency' =>[qw( <frequency_x> <frequency_y>)]], #<y_invers> -LabeledBox =>['~start_amp' =>[qw( <amplitude_x> <amplitude_y>), {border => 5, flags => &Wx::wxALL|&Wx::wxGROW}, ['~phase :', 1, '<no_phase>', 1,'<closed_phase>', 1, '<open_phase>'], ]], -LabeledBox =>[ '~rotation ' =>[qw( <rotation_dir> <rotation> )]], {border => 10}, '<friction>', ], '~visuals' => [ {border => 5, flags => &Wx::wxGROW|&Wx::wxALL}, -LabeledBox =>['~line' =>[qw( <length> <density> )]], #<thickness> -LabeledBox =>['~color' =>[qw( <start_colour> <flow_colour> <scale_colour>)]], {border => 10},'<zoom>', ], ], ]); $frame->ResetValues(); $app->Repaint(); $app->SetTopWindow($frame); 1;
  • 9. Harmonogra ph sub OnInit { my $app = shift; # load localisation texts in chosen language my ($v, $dir, $f) = File::Spec->splitpath(__FILE__); $l18n_file = File::Spec->catfile($dir, $l18n_file) if $dir; die "localisation file $l18n_file is missing!" unless -e $l18n_file; my %l18n = %{YAML::Tiny->read( $l18n_file )->[0]{$language}}; $app->{'l18n'} = %l18n; # loading the numbers of the remembered favorites $app->{'favorites'} = -e $fav_file ? YAML::Tiny->read( $fav_file ) : YAML::Tiny->new; my @remembered_pic_names = ref $app->{'favorites'}->[0] eq 'HASH' ? keys $app->{'favorites'}->[0] : (); # making UI my $frame = $app->{'frame'} = Wx::Perl::Smart::Frame->new(__PACKAGE__." $VERSION", 'fixed_size'); $frame->SubscribeStrings( $app->{'l18n'} ); my $remember= sub { $frame->SetValues( $app->{'favorites'}[0]{ $_[0]->GetValue() } ); $app->Repaint()}; my $repaint = sub { $app->Repaint() }; my $boardsize = Wx::GetDisplaySize()->GetHeight() - 250; my $origin_offset = $app->{'origin_offset'} = $boardsize / 2; my $max_amp = $app->{'max_amp'} = $origin_offset - 10; # max amplitude my %range_defaults = (# label, min, max, init frequency_x => ['X', 1, 1, 30], frequency_y => ['Y', 1, 1, 30], amplitude_x => ['X', 0, 0, 360], amplitude_y => ['Y', 0, 0, 360], rotation => [$l18n{'amount'}, 1, 0, 30], friction => [$l18n{'friction'}, 0, 0, 200], length => [$l18n{'length'}, 12, 1, 100], density => [$l18n{'density'},100, 1, 100], thickness => [$l18n{'thickness'},1, 1, 12], zoom => [$l18n{'zoom'}, 0,-10, 10], start_colour=> [$l18n{'start'}, 0, 0,1500], flow_colour => [$l18n{'flow'}, 0, 0, 60], scale_colour=> [$l18n{'scale'}, 1, 1, 4], ); $frame->SubscribeWidgets ({$_ => Wx::Perl::DisplaySlider->new($frame, @{$range_defaults{$_}}, $repaint)}) for keys %range_defaults; $frame->SubscribeWidgets({ drawboard => Wx::Perl::DrawMap->new($frame, $boardsize), fav_select => [-ComboBox => @remembered_pic_names, 0, -1, $remember], format_select=> [-ComboBox => [qw(PNG JPG TIFF BMP XPM)], 0, 70 ], save => [-Button => '~save', sub {$app->Save() }], save_all => [-Button => '~all', sub {$app->SaveAll() }], remember => [-Button => '~remember', sub {$app->Remember()}], forget => [-Button => '~forget', sub {$app->Forget() }], no_phase => [-Button => '~no', sub {$frame->SetValues(amplitude_x => 0, amplitude_y => 0);$app->Repaint()}], closed_phase => [-Button => '~closed', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 90);$app->Repaint()}], open_phase => [-Button => '~open', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 180);$app->Repaint()}], y_invers => [-CheckBox => '~y_inverse', 0, $repaint], rotation_dir => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(no left right)}], 0, &Wx::wxHORIZONTAL, $repaint), app_mode => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(lateral rotary free)}], 0, &Wx::wxHORIZONTAL, sub{}), }); $frame->SetSmartLayout( {flags => &Wx::wxGROW|&Wx::wxALL}, [ # left part '<drawboard>', 10, {border => 10, flags => &Wx::wxALL|&Wx::wxGROW}, '<fav_select>', ['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10, '<remember>'], ],[ # right half -TabbedBox => [ '~oscillators' =>[ {border => 5, flags => &Wx::wxGROW|&Wx::wxALL}, ['~mode :', '<app_mode>'], -LabeledBox =>['~frequency' =>[qw( <frequency_x> <frequency_y>)]], #<y_invers> -LabeledBox =>['~start_amp' =>[qw( <amplitude_x> <amplitude_y>), {border => 5, flags => &Wx::wxALL|&Wx::wxGROW}, ['~phase :', 1, '<no_phase>', 1,'<closed_phase>', 1, '<open_phase>'], ]], -LabeledBox =>[ '~rotation ' =>[qw( <rotation_dir> <rotation> )]], {border => 10}, '<friction>', ], '~visuals' => [ {border => 5, flags => &Wx::wxGROW|&Wx::wxALL}, -LabeledBox =>['~line' =>[qw( <length> <density> )]], #<thickness> -LabeledBox =>['~color' =>[qw( <start_colour> <flow_colour> <scale_colour>)]], {border => 10},'<zoom>', ], ], ]); $frame->ResetValues(); $app->Repaint(); $app->SetTopWindow($frame); 1;
  • 10. Harmonogra ph sub OnInit { my $app = shift; # load localisation texts in chosen language my ($v, $dir, $f) = File::Spec->splitpath(__FILE__); $l18n_file = File::Spec->catfile($dir, $l18n_file) if $dir; die "localisation file $l18n_file is missing!" unless -e $l18n_file; my %l18n = %{YAML::Tiny->read( $l18n_file )->[0]{$language}}; $app->{'l18n'} = %l18n; # loading the numbers of the remembered favorites $app->{'favorites'} = -e $fav_file ? YAML::Tiny->read( $fav_file ) : YAML::Tiny->new; my @remembered_pic_names = ref $app->{'favorites'}->[0] eq 'HASH' ? keys $app->{'favorites'}->[0] : (); # making UI my $frame = $app->{'frame'} = Wx::Perl::Smart::Frame->new(__PACKAGE__." $VERSION", 'fixed_size'); $frame->SubscribeStrings( $app->{'l18n'} ); my $remember= sub { $frame->SetValues( $app->{'favorites'}[0]{ $_[0]->GetValue() } ); $app->Repaint()}; my $repaint = sub { $app->Repaint() }; my $boardsize = Wx::GetDisplaySize()->GetHeight() - 250; my $origin_offset = $app->{'origin_offset'} = $boardsize / 2; my $max_amp = $app->{'max_amp'} = $origin_offset - 10; # max amplitude my %range_defaults = (# label, min, max, init frequency_x => ['X', 1, 1, 30], frequency_y => ['Y', 1, 1, 30], amplitude_x => ['X', 0, 0, 360], amplitude_y => ['Y', 0, 0, 360], rotation => [$l18n{'amount'}, 1, 0, 30], friction => [$l18n{'friction'}, 0, 0, 200], length => [$l18n{'length'}, 12, 1, 100], density => [$l18n{'density'},100, 1, 100], thickness => [$l18n{'thickness'},1, 1, 12], zoom => [$l18n{'zoom'}, 0,-10, 10], start_colour=> [$l18n{'start'}, 0, 0,1500], flow_colour => [$l18n{'flow'}, 0, 0, 60], scale_colour=> [$l18n{'scale'}, 1, 1, 4], ); $frame->SubscribeWidgets ({$_ => Wx::Perl::DisplaySlider->new($frame, @{$range_defaults{$_}}, $repaint)}) for keys %range_defaults; $frame->SubscribeWidgets({ drawboard => Wx::Perl::DrawMap->new($frame, $boardsize), fav_select => [-ComboBox => @remembered_pic_names, 0, -1, $remember], format_select=> [-ComboBox => [qw(PNG JPG TIFF BMP XPM)], 0, 70 ], save => [-Button => '~save', sub {$app->Save() }], save_all => [-Button => '~all', sub {$app->SaveAll() }], remember => [-Button => '~remember', sub {$app->Remember()}], forget => [-Button => '~forget', sub {$app->Forget() }], no_phase => [-Button => '~no', sub {$frame->SetValues(amplitude_x => 0, amplitude_y => 0);$app->Repaint()}], closed_phase => [-Button => '~closed', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 90);$app->Repaint()}], open_phase => [-Button => '~open', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 180);$app->Repaint()}], y_invers => [-CheckBox => '~y_inverse', 0, $repaint], rotation_dir => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(no left right)}], 0, &Wx::wxHORIZONTAL, $repaint), app_mode => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(lateral rotary free)}], 0, &Wx::wxHORIZONTAL, sub{}), }); $frame->SetSmartLayout( {flags => &Wx::wxGROW|&Wx::wxALL}, [ # left part '<drawboard>', 10, {border => 10, flags => &Wx::wxALL|&Wx::wxGROW}, '<fav_select>', ['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10, '<remember>'], ],[ # right half -TabbedBox => [ '~oscillators' =>[ {border => 5, flags => &Wx::wxGROW|&Wx::wxALL}, ['~mode :', '<app_mode>'], -LabeledBox =>['~frequency' =>[qw( <frequency_x> <frequency_y>)]], #<y_invers> -LabeledBox =>['~start_amp' =>[qw( <amplitude_x> <amplitude_y>), {border => 5, flags => &Wx::wxALL|&Wx::wxGROW}, ['~phase :', 1, '<no_phase>', 1,'<closed_phase>', 1, '<open_phase>'], ]], -LabeledBox =>[ '~rotation ' =>[qw( <rotation_dir> <rotation> )]], {border => 10}, '<friction>', ], '~visuals' => [ {border => 5, flags => &Wx::wxGROW|&Wx::wxALL}, -LabeledBox =>['~line' =>[qw( <length> <density> )]], #<thickness> -LabeledBox =>['~color' =>[qw( <start_colour> <flow_colour> <scale_colour>)]], {border => 10},'<zoom>', ], ], ]); $frame->ResetValues(); $app->Repaint(); $app->SetTopWindow($frame); 1;
  • 11. Wx::Perl::Smart sub OnInit { my $app = shift; # load localisation texts in chosen language my ($v, $dir, $f) = File::Spec->splitpath(__FILE__); $l18n_file = File::Spec->catfile($dir, $l18n_file) if $dir; die "localisation file $l18n_file is missing!" unless -e $l18n_file; my %l18n = %{YAML::Tiny->read( $l18n_file )->[0]{$language}}; $app->{'l18n'} = %l18n; # loading the numbers of the remembered favorites $app->{'favorites'} = -e $fav_file ? YAML::Tiny->read( $fav_file ) : YAML::Tiny->new; my @remembered_pic_names = ref $app->{'favorites'}->[0] eq 'HASH' ? keys $app->{'favorites'}->[0] : (); # making UI my $frame = $app->{'frame'} = Wx::Perl::Smart::Frame->new(__PACKAGE__." $VERSION", 'fixed_size'); $frame->SubscribeStrings( $app->{'l18n'} ); my $remember= sub { $frame->SetValues( $app->{'favorites'}[0]{ $_[0]->GetValue() } ); $app->Repaint()}; my $repaint = sub { $app->Repaint() }; my $boardsize = Wx::GetDisplaySize()->GetHeight() - 250; my $origin_offset = $app->{'origin_offset'} = $boardsize / 2; my $max_amp = $app->{'max_amp'} = $origin_offset - 10; # max amplitude my %range_defaults = (# label, min, max, init frequency_x => ['X', 1, 1, 30], frequency_y => ['Y', 1, 1, 30], amplitude_x => ['X', 0, 0, 360], amplitude_y => ['Y', 0, 0, 360], rotation => [$l18n{'amount'}, 1, 0, 30], friction => [$l18n{'friction'}, 0, 0, 200], length => [$l18n{'length'}, 12, 1, 100], density => [$l18n{'density'},100, 1, 100], thickness => [$l18n{'thickness'},1, 1, 12], zoom => [$l18n{'zoom'}, 0,-10, 10], start_colour=> [$l18n{'start'}, 0, 0,1500], flow_colour => [$l18n{'flow'}, 0, 0, 60], scale_colour=> [$l18n{'scale'}, 1, 1, 4], ); $frame->SubscribeWidgets ({$_ => Wx::Perl::DisplaySlider->new($frame, @{$range_defaults{$_}}, $repaint)}) for keys %range_defaults; $frame->SubscribeWidgets({ drawboard => Wx::Perl::DrawMap->new($frame, $boardsize), fav_select => [-ComboBox => @remembered_pic_names, 0, -1, $remember], format_select=> [-ComboBox => [qw(PNG JPG TIFF BMP XPM)], 0, 70 ], save => [-Button => '~save', sub {$app->Save() }], save_all => [-Button => '~all', sub {$app->SaveAll() }], remember => [-Button => '~remember', sub {$app->Remember()}], forget => [-Button => '~forget', sub {$app->Forget() }], no_phase => [-Button => '~no', sub {$frame->SetValues(amplitude_x => 0, amplitude_y => 0);$app->Repaint()}], closed_phase => [-Button => '~closed', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 90);$app->Repaint()}], open_phase => [-Button => '~open', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 180);$app->Repaint()}], y_invers => [-CheckBox => '~y_inverse', 0, $repaint], rotation_dir => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(no left right)}], 0, &Wx::wxHORIZONTAL, $repaint), app_mode => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(lateral rotary free)}], 0, &Wx::wxHORIZONTAL, sub{}), }); $frame->SetSmartLayout( {flags => &Wx::wxGROW|&Wx::wxALL}, [ # left part '<drawboard>', 10, {border => 10, flags => &Wx::wxALL|&Wx::wxGROW}, '<fav_select>', ['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10, '<remember>'], ],[ # right half -TabbedBox => [ '~oscillators' =>[ {border => 5, flags => &Wx::wxGROW|&Wx::wxALL}, ['~mode :', '<app_mode>'], -LabeledBox =>['~frequency' =>[qw( <frequency_x> <frequency_y>)]], #<y_invers> -LabeledBox =>['~start_amp' =>[qw( <amplitude_x> <amplitude_y>), {border => 5, flags => &Wx::wxALL|&Wx::wxGROW}, ['~phase :', 1, '<no_phase>', 1,'<closed_phase>', 1, '<open_phase>'], ]], -LabeledBox =>[ '~rotation ' =>[qw( <rotation_dir> <rotation> )]], {border => 10}, '<friction>', ], '~visuals' => [ {border => 5, flags => &Wx::wxGROW|&Wx::wxALL}, -LabeledBox =>['~line' =>[qw( <length> <density> )]], #<thickness> -LabeledBox =>['~color' =>[qw( <start_colour> <flow_colour> <scale_colour>)]], {border => 10},'<zoom>', ], ], ]); $frame->ResetValues(); $app->Repaint(); $app->SetTopWindow($frame); 1;
  • 12. Wx::Perl::Smart sub OnInit { my $app = shift; # load localisation texts in chosen language my ($v, $dir, $f) = File::Spec->splitpath(__FILE__); $l18n_file = File::Spec->catfile($dir, $l18n_file) if $dir; die "localisation file $l18n_file is missing!" unless -e $l18n_file; my %l18n = %{YAML::Tiny->read( $l18n_file )->[0]{$language}}; $app->{'l18n'} = %l18n; # loading the numbers of the remembered favorites $app->{'favorites'} = -e $fav_file ? YAML::Tiny->read( $fav_file ) : YAML::Tiny->new; my @remembered_pic_names = ref $app->{'favorites'}->[0] eq 'HASH' ? keys $app->{'favorites'}->[0] : (); # making UI my $frame = $app->{'frame'} = Wx::Perl::Smart::Frame->new(__PACKAGE__." $VERSION", 'fixed_size'); $frame->SubscribeStrings( $app->{'l18n'} ); my $remember= sub { $frame->SetValues( $app->{'favorites'}[0]{ $_[0]->GetValue() } ); $app->Repaint()}; my $repaint = sub { $app->Repaint() }; my $boardsize = Wx::GetDisplaySize()->GetHeight() - 250; my $origin_offset = $app->{'origin_offset'} = $boardsize / 2; my $max_amp = $app->{'max_amp'} = $origin_offset - 10; # max amplitude my %range_defaults = (# label, min, max, init frequency_x => ['X', 1, 1, 30], frequency_y => ['Y', 1, 1, 30], amplitude_x => ['X', 0, 0, 360], amplitude_y => ['Y', 0, 0, 360], rotation => [$l18n{'amount'}, 1, 0, 30], friction => [$l18n{'friction'}, 0, 0, 200], length => [$l18n{'length'}, 12, 1, 100], density => [$l18n{'density'},100, 1, 100], thickness => [$l18n{'thickness'},1, 1, 12], zoom => [$l18n{'zoom'}, 0,-10, 10], start_colour=> [$l18n{'start'}, 0, 0,1500], flow_colour => [$l18n{'flow'}, 0, 0, 60], scale_colour=> [$l18n{'scale'}, 1, 1, 4], ); $frame->SubscribeWidgets ({$_ => Wx::Perl::DisplaySlider->new($frame, @{$range_defaults{$_}}, $repaint)}) for keys %range_defaults; $frame->SubscribeWidgets({ drawboard => Wx::Perl::DrawMap->new($frame, $boardsize), fav_select => [-ComboBox => @remembered_pic_names, 0, -1, $remember], format_select=> [-ComboBox => [qw(PNG JPG TIFF BMP XPM)], 0, 70 ], save => [-Button => '~save', sub {$app->Save() }], save_all => [-Button => '~all', sub {$app->SaveAll() }], remember => [-Button => '~remember', sub {$app->Remember()}], forget => [-Button => '~forget', sub {$app->Forget() }], no_phase => [-Button => '~no', sub {$frame->SetValues(amplitude_x => 0, amplitude_y => 0);$app->Repaint()}], closed_phase => [-Button => '~closed', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 90);$app->Repaint()}], open_phase => [-Button => '~open', sub {$frame->SetValues(amplitude_x => 90, amplitude_y => 180);$app->Repaint()}], y_invers => [-CheckBox => '~y_inverse', 0, $repaint], rotation_dir => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(no left right)}], 0, &Wx::wxHORIZONTAL, $repaint), app_mode => Wx::Perl::RadioGroup->new($frame, [@l18n{qw(lateral rotary free)}], 0, &Wx::wxHORIZONTAL, sub{}), }); $frame->SetSmartLayout( {flags => &Wx::wxGROW|&Wx::wxALL}, [ # left part '<drawboard>', 10, {border => 10, flags => &Wx::wxALL|&Wx::wxGROW}, '<fav_select>', ['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10, '<remember>'], ],[ # right half -TabbedBox => [ '~oscillators' =>[ {border => 5, flags => &Wx::wxGROW|&Wx::wxALL}, ['~mode :', '<app_mode>'], -LabeledBox =>['~frequency' =>[qw( <frequency_x> <frequency_y>)]], #<y_invers> -LabeledBox =>['~start_amp' =>[qw( <amplitude_x> <amplitude_y>), {border => 5, flags => &Wx::wxALL|&Wx::wxGROW}, ['~phase :', 1, '<no_phase>', 1,'<closed_phase>', 1, '<open_phase>'], ]], -LabeledBox =>[ '~rotation ' =>[qw( <rotation_dir> <rotation> )]], {border => 10}, '<friction>', ], '~visuals' => [ {border => 5, flags => &Wx::wxGROW|&Wx::wxALL}, -LabeledBox =>['~line' =>[qw( <length> <density> )]], #<thickness> -LabeledBox =>['~color' =>[qw( <start_colour> <flow_colour> <scale_colour>)]], {border => 10},'<zoom>', ], ], ]); $frame->ResetValues(); $app->Repaint(); $app->SetTopWindow($frame); 1;
  • 21. Das sind nur 3 Widgets Komposition Abstraktion
  • 22. Jetzt sind es 5 Wid gets Komposition Abstr aktion
  • 24. Nummer 1 einfach & sichere Widgeterzeugung
  • 29. Nummer 5 MVC – GUI Layer
  • 30. GUI Comp. Lang. MVC – GUI Layer
  • 35. $parent $frame ID -1 $label wxEmptyString, wxPoint wxDefaultPosition, [-1,-1] wxSize& size = wxDefaultSize, [-1,-1] style 0, wxValidator, wxString $name New Parameter
  • 36. $button = Wx::Button->new( $parent, -1, 'label', [-1,-1], [30,-1]); Wx::Event::EVT_BUTTON ($frame, $button, &callback); Button Erzeugen
  • 38. Wx::Perl::Button ($parent, 'label', &callback, 30); # required , opt Smart Button
  • 39. wxWindow* parent, wxWindowID id, wxString& value, wxPoint& pos, wxSize& size, long style, wxValidator& (validator), wxString& name, Textc. Parameter
  • 40. $txt = Wx::TextCtrl->new( $parent, -1, 'content', [-1,-1], [30,-1], &Wx::wxTE_MULTILINE Wx::Perl::TextValidator->new (qr//)); Wx::Event::EVT_KEY_DOWN ($txt, -1, &callback); Wx::Event::EVT_TEXT ($frame, $txt, &callback); TextCtrlErzeugen
  • 43. weglassen was nicht wichtig ist nimmt hinzu was wichtig wäre optional auch mit benannten Param. Def als Code oder String (compilien) alles normalen Widgets (Moose) Wx::Perl::Button ... kommt vielleicht Einzelne Widgets
  • 44. weglassen was nicht wichtig ist Einzelne Widgets
  • 45. weglassen was nicht wichtig ist Perl hat besseres ObjRef statt WxID | WidgetName Einzelne Widgets
  • 46. weglassen was nicht wichtig ist Weil du es nicht kontrollieren willst Position und Größe regeln Sizer Einzelne Widgets
  • 47. weglassen was nicht wichtig ist Weil es Probleme macht auf undef gesetzte parents Einzelne Widgets
  • 48. weglassen was nicht wichtig ist nimmt hinzu was wichtig wäre callbacks (coderef) Einzelne Widgets
  • 49. weglassen was nicht wichtig ist nimmt hinzu was wichtig wäre callbacks (coderef) & zus. styles Einzelne Widgets
  • 50. weglassen was nicht wichtig ist nimmt hinzu was wichtig wäre optional auch mit benannten Param. Def als Code oder String (compilien) alles normalen Widgets (Moose) Wx::Perl::Button ... kommt vielleicht Einzelne Widgets
  • 51. weglassen was nicht wichtig ist nimmt hinzu was wichtig wäre optional auch mit benannten Param. Def als Code oder String (compilien) alles normalen Widgets (Moose) Wx::Perl::Button ... kommt vielleicht Einzelne Widgets
  • 52. weglassen was nicht wichtig ist nimmt hinzu was wichtig wäre optional auch mit benannten Param. Def als code oder String (compilien) alles normalen Widgets (Moose) Wx::Perl::Button ... kommt vielleicht Einzelne Widgets
  • 53. weglassen was nicht wichtig ist nimmt hinzu was wichtig wäre optional auch mit benannten Param. Def als code oder String (compilien) alles normalen Widgets (Moose) Wx::Perl::Button ... kommt vielleicht Einzelne Widgets
  • 54. weglassen was nicht wichtig ist nimmt hinzu was wichtig wäre optional auch mit benannten Param. Def als code oder String (compilien) alles normalen Widgets (Moose) Wx::Perl::Button ... kommt vielleicht Einzelne Widgets
  • 55. Wx::Perl::Button ($parent, 'label', &callback, 30); neues Modul für den einen Aufruf Softwarearchitektur: factory method Smart Button ?
  • 56. Wx::Perl::Button ($parent, 'label', &callback, 30); neues Modul für den einen Aufruf Softwarearchitektur: factory method Smart Button ?
  • 57. @widgets = factory method([ [-Button => 'label', &callback, 30], … ]); Smart Factory
  • 58. @widgets = $factory->MakeWidget([ [-Button => 'label', &callback, 30], {widget => 'Button', label =>'...', }, ]); Benannte Param.
  • 61. im Sinne einer Factory Method erzeugt normale Widgets & weitere Smart Factory
  • 64. Zusam. Widgets sammle mehrere Einzelwidgets und deren Daten & Event- handling in ein Widget einfacherer Umgang, Layout wird übersichtlicher
  • 68. :WidgetFactory einfache, robuste Erzeugung in Tabellenanordnung Trennung vom GUI-Layout keine Daten ins Layout strukturierte Programme
  • 69. :WidgetFactory einfache, robuste Erzeugung in Tabellenanordnung Trennung vom GUI-Layout keine Daten ins Layout strukturierte Programme
  • 71. ::Smart::Sizer einfache und robuste Erzeugung Erzeugung von Deko-Widgets Kommentare mehr Abstraktion (tabs = Sizer) einfache und effektive Benutzung
  • 72. ::Smart::Sizer einfache und robuste Erzeugung Erzeugung von Deko-Widgets Kommentare mehr Abstraktion (tabs = Sizer) einfache und effektive Benutzung
  • 73. ::Smart::Sizer einfache und robuste Erzeugung $sizer = Wx::Perl::Smart::Sizer- >new([$widget, $widget, ...]);
  • 74. ::Smart::Sizer einfache und robuste Erzeugung Erzeugung von Deko-Widgets Kommentare mehr Abstraktion (tabs = Sizer) einfache und effektive Benutzung
  • 75. ::Smart::Sizer Erzeugung von Deko-Widgets $sizer = Wx::Perl::Smart::Sizer- >new([$widget, '---', $widget, ...]);
  • 76. ::Smart::Sizer einfache und robuste Erzeugung Erzeugung von Deko-Widgets Kommentare mehr Abstraktion (tabs = Sizer) einfache und effektive Benutzung
  • 77. ::Smart::Sizer einfache und robuste Erzeugung Erzeugung von Deko-Widgets Kommentare mehr Abstraktion (tabs = Sizer) einfache und effektive Benutzung
  • 78. ::Smart::Sizer $sizer = Wx::Perl::Smart::Sizer- >new(-TabbedBox => [ [$widget, ...], [...]]); mehr Abstraktion (tabs = Sizer)
  • 79. ::Smart::Sizer einfache und robuste Erzeugung Erzeugung von Deko-Widgets Kommentare mehr Abstraktion (tabs = Sizer) einfache und effektive Benutzung
  • 80. ::Smart::Sizer einfache und robuste Erzeugung Erzeugung von Deko-Widgets Kommentare mehr Abstraktion (tabs = Sizer) einfache und effektive Benutzung
  • 83. ::Smart::Panel Panel mit Smart::Sizer $panel = Wx::Perl::Smart::Panel- >new([$widget, $widget, ...]);
  • 84. ::Smart::Panel Panel mit Smart::Sizer Sichbarkeit und Verwandschaft wird automatisch geregelt
  • 86. ::Smart::Frame Hauptenster einer App noch eine Abstraktion vereinfachter Zugriff auf Panel, Sizer und WidgetFactory verwaltet auch Widgets und Localisationstrings
  • 87. Widgets mit ID $frame->MakeWidgets({ drawboard => Wx::Perl::Draw... fav_select => [-ComboBox => ..]
  • 88. def Layout $frame->EvalSmartLayout ( {flags => &Wx::wxGROW|&Wx::wxALL}, [ '<drawboard>', 10, '<fav_select>', ['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10,...],
  • 89. ohne Ränder $frame->EvalSmartLayout ( [ '<drawboard>', '<fav_select>', ['<format_select>', '<save>', '<save_all>', 1, '<forget>', ...],
  • 90. Panel mit ID $frame->EvalSmartPanel ( 'my_panel' => [ '<drawboard>', 10, '<fav_select>', ['<format_select>', 10,'<save>', 10, '<save_all>', 1, '<forget>', 10,...],
  • 97. Smart>GUIDesigner Smart ist schneller effektiver als GUI änder Abstandsklassen
  • 98. Smart>GUIDesigner Smart ist schneller effektiver als GUI denk in Proportionen
  • 104. Abstraktion Wikiformat für's layout (oft besser als GUI designer) kompiliert zu Datenstruktur (jedes Format funktioniert) kompiliert zu GUI andere Backends denkbar (GCL::Prima, GCL::GTK)
  • 105. Abstraktion Wikiformat für's layout (oft besser als GUI designer) kompiliert zu Datenstruktur (jedes Format funktioniert) kompiliert zu GUI andere Backends denkbar (GCL::Prima, GCL::GTK)
  • 106. Abstraktion Wikiformat für's layout (oft besser als GUI designer) kompiliert zu Datenstruktur (jedes Format funktioniert) kompiliert zu GUI andere Backends denkbar (GCL::Prima, GCL::GTK)
  • 107. Abstraktion Wikiformat für's layout (oft besser als GUI designer) kompiliert zu Datenstruktur (jedes Format funktioniert) kompiliert zu GUI andere Backends denkbar (GCL::Prima, GCL::GTK)
  • 108. Danke