On the Apple II BASIC in the 1980s, you would use "HGR", to get to a screen, "HCOLOR" would set a color, and "HPLOT" would plot points. You could also manipulate the screen byte data, and you wouldn't have to hand off program control to any event handler. This ridiculously rudimentary functionality seems to be missing today from every language and every library.
So I wrote a small library to do this in C using the X Window API: HGR(x,y) puts up an XWindow, HCOLOR(i) sets the color, and HPLOT(i,j) plots a point, plus you extract the window's bitmap and can modify it and display the modified thing. This was not straightforward, and I don't want to go through it again.
I am using Perl for some things now, and I need such a tool for Perl, something where you can call a subroutine that preferably returns without spawning a new thread, having output a window, where you can add graphical stuff to the window, and query the events when your program feels like it. This is the functionality of 1980s BASIC, so it shouldn't be hard. But the tools I saw didn't do it:
Does anyone know how to put up an XWindow from a running application, without forking out a GUI application process, where you can draw primitive things in the window like points and lines, and where you can query your windows' events on your own schedule? I briefly looked at the X Window API for Perl, it's as horrendous as C, and interfacing the C code with Perl is also horrendous. If necessary, I'll do it. But maybe not. Is there an HGR for Perl already?
If you are wondering what I mean, no event loop graphical library, see this linked paper, which unfortunately is for C. Such a thing is extremely useful for scientific stuff, outside of introductory programming classes.
Pretty much every GUI toolkit supports building windows without entering the event loop. Here is tk example
#!/usr/bin/perl --
use strict;
use warnings;
use Tk;
my $mw = tkinit();
my $ca = $mw->Canvas(
background => 'white'
)->pack(qw/-expand 1 -fill both /);
$mw->geometry( '500x600+10+10' );
for my $cc (
{ red => \&red, green => \&der, blue => \&erd },
{ green => \&red, red => \&der, blue => \&erd },
{ green => \&red, blue => \&der, red => \&erd },
)
{
$ca->delete('all');
my %color = %$cc;
for my $fill ( keys %color ) {
my $red = $color{$fill};
for my $t ( 10 .. 220 ) {
my $d = 0.1;
my ( $x, $y ) = $red->( $t, 0.1 );
$_ += 250 for $x, $y;
$ca->createOval(
$x, $y,
( $t * 2 * $d ) + $x,
( $t * 2 * $d ) + $y,
-fill => $fill,
);
$mw->update;
select undef, undef, undef, 0.001;
}
$mw->update;
}
}
Tk::DoOneEvent(0) while Tk::MainWindow->Count; ## MainLoop;
exit 0;
sub red {
my ( $t, $d ) = @_;
my $x = $t * sin( $t * $d );
my $y = $t * cos( $t * $d );
$x, $y;
}
sub der {
my ( $t, $d ) = @_;
my $x = $t * sin( $t * $d );
my $y = $t * cos( $t * 2 * $d );
$x, $y;
}
sub erd {
my ( $t, $d ) = @_;
my $x = $t * sin( $t * 2 * $d );
my $y = $t * cos( $t * $d );
$x, $y;
}
__END__
Both Gtk2 and Wx support the same thing, its either update/show/display ... and the windows get drawn, and when you want user interaction, you call MainLoop or run the app or handle it yourself, its just a while loop dispatching pending events
wxTheApp->Dispatch while wxTheApp->Pending;
Gtk2->main_iteration while Gtk2->events_pending;
I recommend using the Perl module Inline::C. That module makes it easy to expose a C library to your Perl application. With some C libraries the 'AUTOWRAP' option makes it completely trivial. But even if you have to write some wrappers yourself, Inline::C really eases the XS burden.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With