SlideShare a Scribd company logo
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
Ad

More Related Content

What's hot (20)

Perl6 in-production
Perl6 in-productionPerl6 in-production
Perl6 in-production
Andrew Shitov
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
garux
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation Tutorial
Lorna Mitchell
 
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
osfameron
 
Perl6 one-liners
Perl6 one-linersPerl6 one-liners
Perl6 one-liners
Andrew Shitov
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perl
garux
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
Kang-min Liu
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
gsterndale
 
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 PPT FILE
PHP PPT FILEPHP PPT FILE
PHP PPT FILE
AbhishekSharma2958
 
PHP and MySQL
PHP and MySQLPHP and MySQL
PHP and MySQL
Sanketkumar Biswas
 
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.16
Ricardo 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.4
Jeff 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 Arrays
Ahmed 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 haters
Lin Yo-An
 
Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015
Lin Yo-An
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
garux
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation Tutorial
Lorna Mitchell
 
Functional Pe(a)rls version 2
Functional Pe(a)rls version 2Functional Pe(a)rls version 2
Functional Pe(a)rls version 2
osfameron
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perl
garux
 
Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
Kang-min Liu
 
Refactor like a boss
Refactor like a bossRefactor like a boss
Refactor like a boss
gsterndale
 
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.16
Ricardo 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.4
Jeff 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 Arrays
Ahmed 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 haters
Lin Yo-An
 
Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015
Lin Yo-An
 

Similar to Wx::Perl::Smart (20)

Crazy things done on PHP
Crazy things done on PHPCrazy things done on PHP
Crazy things done on PHP
Taras Kalapun
 
PHP for Python Developers
PHP for Python DevelopersPHP for Python Developers
PHP for Python Developers
Carlos 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 2011
Masahiro Nagano
 
Crafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::ExporterCrafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::Exporter
Ricardo 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: Hack
Vic Metcalfe
 
循環参照のはなし
循環参照のはなし循環参照のはなし
循環参照のはなし
Masahiro Honma
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegame
hozayfa999
 
Ns2programs
Ns2programsNs2programs
Ns2programs
Meenakshi Devi
 
Php functions
Php functionsPhp functions
Php functions
JIGAR MAKHIJA
 
distill
distilldistill
distill
Thomas Knudstrup
 
Bag of tricks
Bag of tricksBag of tricks
Bag of tricks
brian d foy
 
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
Programmer 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 Functions
David Golden
 
wget.pl
wget.plwget.pl
wget.pl
Yasuhiro Onishi
 
Intermediate PHP
Intermediate PHPIntermediate PHP
Intermediate PHP
Bradley Holt
 
[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 Bootstrap
Howard 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 it
Andrew Shitov
 
redis überall
redis überallredis überall
redis überall
zucaritask
 
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
brian d foy
 
Crazy things done on PHP
Crazy things done on PHPCrazy things done on PHP
Crazy things done on PHP
Taras Kalapun
 
PHP for Python Developers
PHP for Python DevelopersPHP for Python Developers
PHP for Python Developers
Carlos 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 2011
Masahiro Nagano
 
Crafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::ExporterCrafting Custom Interfaces with Sub::Exporter
Crafting Custom Interfaces with Sub::Exporter
Ricardo 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: Hack
Vic Metcalfe
 
循環参照のはなし
循環参照のはなし循環参照のはなし
循環参照のはなし
Masahiro Honma
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegame
hozayfa999
 
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
Programmer 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 Functions
David 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 Bootstrap
Howard 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 it
Andrew Shitov
 
redis überall
redis überallredis überall
redis überall
zucaritask
 
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
brian d foy
 
Ad

More from 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
lichtkind
 
P6kontext2014
P6kontext2014P6kontext2014
P6kontext2014
lichtkind
 
Complete Programming
Complete ProgrammingComplete Programming
Complete Programming
lichtkind
 
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 Edition
lichtkind
 
P6oo
P6ooP6oo
P6oo
lichtkind
 
Writing Perl 6 Rx
Writing Perl 6 RxWriting Perl 6 Rx
Writing Perl 6 Rx
lichtkind
 
Wundertüte Perl
Wundertüte PerlWundertüte Perl
Wundertüte Perl
lichtkind
 
Perl 6 Regex und Grammars
Perl 6 Regex und GrammarsPerl 6 Regex und Grammars
Perl 6 Regex und Grammars
lichtkind
 
Perl 6 Datastructures
Perl 6 DatastructuresPerl 6 Datastructures
Perl 6 Datastructures
lichtkind
 
Perl 6 Datenstrukturen
Perl 6 DatenstrukturenPerl 6 Datenstrukturen
Perl 6 Datenstrukturen
lichtkind
 
Document Driven Development
Document Driven DevelopmentDocument Driven Development
Document Driven Development
lichtkind
 
Modern wx perl
Modern wx perlModern wx perl
Modern wx perl
lichtkind
 
Bettereditors
BettereditorsBettereditors
Bettereditors
lichtkind
 
Hgit
HgitHgit
Hgit
lichtkind
 
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 Testing
lichtkind
 
Perl in der Wiki
Perl in der WikiPerl in der Wiki
Perl in der Wiki
lichtkind
 
What is Kephra about?
What is Kephra about?What is Kephra about?
What is Kephra about?
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, Werkzeuge
lichtkind
 
P6kontext2014
P6kontext2014P6kontext2014
P6kontext2014
lichtkind
 
Complete Programming
Complete ProgrammingComplete Programming
Complete Programming
lichtkind
 
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 Edition
lichtkind
 
Writing Perl 6 Rx
Writing Perl 6 RxWriting Perl 6 Rx
Writing Perl 6 Rx
lichtkind
 
Wundertüte Perl
Wundertüte PerlWundertüte Perl
Wundertüte Perl
lichtkind
 
Perl 6 Regex und Grammars
Perl 6 Regex und GrammarsPerl 6 Regex und Grammars
Perl 6 Regex und Grammars
lichtkind
 
Perl 6 Datastructures
Perl 6 DatastructuresPerl 6 Datastructures
Perl 6 Datastructures
lichtkind
 
Perl 6 Datenstrukturen
Perl 6 DatenstrukturenPerl 6 Datenstrukturen
Perl 6 Datenstrukturen
lichtkind
 
Document Driven Development
Document Driven DevelopmentDocument Driven Development
Document Driven Development
lichtkind
 
Modern wx perl
Modern wx perlModern wx perl
Modern wx perl
lichtkind
 
Bettereditors
BettereditorsBettereditors
Bettereditors
lichtkind
 
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 Testing
lichtkind
 
Perl in der Wiki
Perl in der WikiPerl in der Wiki
Perl in der Wiki
lichtkind
 
What is Kephra about?
What is Kephra about?What is Kephra about?
What is Kephra about?
lichtkind
 
Ad

Recently uploaded (20)

Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]
saniaaftab72555
 
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
steaveroggers
 
Automation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath CertificateAutomation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath Certificate
VICTOR MAESTRE RAMIREZ
 
Douwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License codeDouwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License code
aneelaramzan63
 
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New VersionPixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
saimabibi60507
 
WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)
sh607827
 
Expand your AI adoption with AgentExchange
Expand your AI adoption with AgentExchangeExpand your AI adoption with AgentExchange
Expand your AI adoption with AgentExchange
Fexle Services Pvt. Ltd.
 
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Andre Hora
 
Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025
kashifyounis067
 
Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025
kashifyounis067
 
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Eric D. Schabell
 
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
University of Hawai‘i at Mānoa
 
Maxon CINEMA 4D 2025 Crack FREE Download LINK
Maxon CINEMA 4D 2025 Crack FREE Download LINKMaxon CINEMA 4D 2025 Crack FREE Download LINK
Maxon CINEMA 4D 2025 Crack FREE Download LINK
younisnoman75
 
How to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud PerformanceHow to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud Performance
ThousandEyes
 
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Lionel Briand
 
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
Egor Kaleynik
 
Solidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license codeSolidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license code
aneelaramzan63
 
Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025
kashifyounis067
 
FL Studio Producer Edition Crack 2025 Full Version
FL Studio Producer Edition Crack 2025 Full VersionFL Studio Producer Edition Crack 2025 Full Version
FL Studio Producer Edition Crack 2025 Full Version
tahirabibi60507
 
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and CollaborateMeet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Maxim Salnikov
 
Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]
saniaaftab72555
 
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
steaveroggers
 
Automation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath CertificateAutomation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath Certificate
VICTOR MAESTRE RAMIREZ
 
Douwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License codeDouwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License code
aneelaramzan63
 
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New VersionPixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
saimabibi60507
 
WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)
sh607827
 
Expand your AI adoption with AgentExchange
Expand your AI adoption with AgentExchangeExpand your AI adoption with AgentExchange
Expand your AI adoption with AgentExchange
Fexle Services Pvt. Ltd.
 
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Andre Hora
 
Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025
kashifyounis067
 
Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025
kashifyounis067
 
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Eric D. Schabell
 
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
University of Hawai‘i at Mānoa
 
Maxon CINEMA 4D 2025 Crack FREE Download LINK
Maxon CINEMA 4D 2025 Crack FREE Download LINKMaxon CINEMA 4D 2025 Crack FREE Download LINK
Maxon CINEMA 4D 2025 Crack FREE Download LINK
younisnoman75
 
How to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud PerformanceHow to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud Performance
ThousandEyes
 
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Lionel Briand
 
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
How Valletta helped healthcare SaaS to transform QA and compliance to grow wi...
Egor Kaleynik
 
Solidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license codeSolidworks Crack 2025 latest new + license code
Solidworks Crack 2025 latest new + license code
aneelaramzan63
 
Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025Adobe After Effects Crack FREE FRESH version 2025
Adobe After Effects Crack FREE FRESH version 2025
kashifyounis067
 
FL Studio Producer Edition Crack 2025 Full Version
FL Studio Producer Edition Crack 2025 Full VersionFL Studio Producer Edition Crack 2025 Full Version
FL Studio Producer Edition Crack 2025 Full Version
tahirabibi60507
 
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and CollaborateMeet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Maxim Salnikov
 

Wx::Perl::Smart

  • 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