Wednesday, February 10, 2010

Wx::DefinedUI

For quite some time (like, years) I've toyed with the possibility of defining GUIs under wxWidgets (in Perl, Wx, or in Python, wxPython) by using a sort of pseudocode decorated with actual code to execute the meat of the program. This year, the Muse has accepted my application, and I've started on Wx::DefinedUI in Perl.

To do this, I first managed to get past the hump that's always stopped me in the past: syntax. Bear with me, this is important.

See, whenever I start brainstorming about a new way to reorganize programming, I first scratch out a bunch of data structures in pseudocode, then I realize it's hard to implement that stuff. Then I run aground. For I while I thought XML would help, but no, XML is also too hard to type. This is what killed MagnifiCat, it's what killed the semantic programming of last year (earlier posts on this blog), and it's what killed the Web programming framework I started over the holidays.

But early this year, I got back to Wx. And I looked at the structure of one of the demo programs, and it looks like this:
use Wx::DefinedUI qw(-filter);

dialog (resize) "Wx::BoxSizer"
size (box, v):
size (box, h) [1, GROW]:
button (id=OK) [0, ALL, 10] "Close window"
button [0, 0] "Button 2"
button [0, TOP BOTTOM, 5] "Button 3"
space [10, 10, 0, GROW]
size (box, h) [1, GROW]:
button [1, ALL, 5] "Button 1"
space [1, 30, 1, 0, 0]
button [1, GROW ALL, 5] "Button 2"
size (static, v) [2, GROW] "Wx::StaticBoxSizer":
button [1, GROW ALL, 5] "Button 3"
button [1, GROW ALL, 5] "Button 4"
That's it. Granted, that code doesn't do anything, it just demonstrates the use of box sizers, but there are two points I want to make about it.

First, it provides a detailed, extremely readable, and yet still parseable, overview of the application. If we provided IDs for all those buttons and wrote code to be called on click, we'd have a real application, and one that we could understand with no further ado.

Second - and this is important - as of yesterday, it works. I decided to go ahead and tackle the parsing problem. I looked up Parse::RecDescent and found it good - but then I went ahead and polished up my old XML::xmlapi as a structure manipulation module I can work quickly with, and wrote Parse::RecDescent::Simple to allow parsing of each of those lines. That stuff's already on CPAN, because it's working and stable to the point I need right now.

For parsing of the indentation, I've written part of Parse::Indented. It's not on CPAN yet, because I still want to add a feature allowing embedding of Perl code into my tree. Maybe tomorrow.

The crucial point here is this: I have a parsing framework that lets me use pseudocode to define things, things that will then run. Next step: use that very parsing framework to get back to the Web application framework and semantic programming. It should be easy!

Here's another point, by the bye: publishing early and often keeps the momentum going. I've published five modules to CPAN in the last week. It's heady stuff.

No comments:

Post a Comment