|
From: Eric W. <scr...@gm...> - 2007-03-17 10:17:15
|
Hi all,
I'm working on a few ideas for better expressing wx child widgets and
layouts in Perl and I'm curious what you think is most needed.
First, let me say a big thank you to Mattia. I've been using wxPerl for
a while now and am fairly familiar with the code and what a monumental
effort this was and is. Mattia, you deserve many more thank-you's and
likely don't hear them often enough. What I'm working on is something
like an "ideal syntax", not any sort of flaw in the bindings.
Next, I've heard "I want a good, free GUI rad tool" before, and to be
honest, I have no interest in that sort of thing or that line of
discussion and thus no intention to do anything about it. Sorry, wrong
thread. If someone has an adequately smalltalkish inspiration for
wedding the tool to the code, it might be applicable. Otherwise, no.
And, we all know about the lack-of-perl-specific-documentation issue, so
let's take that one as read.
So, now that we're talking about code rather than tools... What are
your nits and peeves about creating, using, and configuring widgets?
Mine are roughly as follows. Aside: As trivial as some may seem, the
sum of trivialities is non-trivial, and I think part of what makes Perl
special is that speed-bumps and trivial nits were eliminated early in
the design. (If you haven't studied a little python, ruby, C++, or
other languages, you might not yet appreciate Perl's amazing lack of
hindrances (and then look at perl6!)) Also, a cursory glance at Jifty
and Moose might help to shed some light on how I'm thinking and what is
possible.
Many of my issues could probably be summarized as "Perl ain't C++".
A. Too many constants and imports.
For better or worse, perl5 subroutines are methods. Having all of these
constants in my namespace bothers me greatly. Wx::wxDefaultPosition()
isn't any fun to type either. EVT_foobarbazbork() also seems rather
wrong in some way.
B. Long method calls and positional parameters.
I don't want lines longer than 72 characters in my code, but even when
indenting only 2 spaces, it is almost impossible to construct and style
a TextCtrl in 1-2 lines. Further, distending a call with positional
parameters gets clunky very quickly. Now, assign the resultant object
to $self->{that_thingy} and you have to get out your spectacles to
figure out what's happening. Alternatively, spend 20 lines per
sub-widget (which is just too much code to read.)
C. Flags
e.g. "wxTE_MULTILINE|wxTE_READONLY|wxTE_DONTWRAP" -- It's a mouthful,
and I typically have to look in the documentation anyway. With so many
options, the business of constructing flags via or'd constants gets
noisy rather quickly.
D. XRC (sort of)
I've done some XRC research and preliminary experiments, but don't see
it being a solution because (1) it is slow (startup time on a very
simple frame layout is longer than the whole of dotReader load-time)
and (2) it seems to rather limit control despite the verbosity penalty
of XML, plus the "load, then get" usage (aka "why isn't the dom my
object?".) I say "sort of" here because it can't really be much of a
pain-point if it's not actually viable. But, I bring it up because
maybe I'm totally wrong and somebody will clue-stick me.
So, that's the executive summary of my wishlist. It basically comes
down to very distinct differences (visually and architecturally)
between "Perl code" and "Wx code".
Please append, confirm, or dispute according to your experiences.
The rest of this message is an alpha-release brain-dump of my current
line-of-thought... If you're interested in helping me hammer on the
specifics of this idea, please change the subject line. I'm only
including this as background on the above line of inquiry.
I'm working on an idea to create a set of classes with a mixture of
named and positional parameters (e.g. the positional ones being the
ones that don't come with 'foo = somedefault' in the C++ headers.)
This would be a sort of "normal form" for all of the Wx::Foo->new()
constructors.
Building on top of that, a declarative syntax which would build and
install methods to create, configure, and layout your widgets as well
as making accessors for the resultant objects. A *very* preliminary
snapshot of what this looks like is:
use WxPerl::Declare;
bitmaps sub {shift->choose_bitmap(@_)},
children(
ctrl custom_bit => 'Thing::Control' => 'argument', 'argument',
ctrl text_ctrl => -TextCtrl => "",
style(te => 'MULTILINE|READONLY|DONTWRAP'),
code { # setup special thingy...
my $self = shift;
warn "this runs on $self here";
},
ctrl dismiss_button => -Button => '&Close',
ctrl details_button => -Button => '&Details',
);
layout(
h_split qw(right_window bv_manager note_viewer),
v_split qw(window_1 sidebar right_window 195),
# still working on how this comes together
box->vertical->items(qw(...)), # ?
-BoxSizer => [
vertical => {'sizer options here?' => 'foo'},
object_identifier => [@sizer_Add_opts],
],
);
no WxPerl::Declare;
...
# in new() or init()
$self->__create_children;
$self->__do_layout;
Where [custom_bit, text_ctrl, dissmiss_button, details_button,
right_window, bv_manager, note_viewer, window_1, sidebar, and
right_window] are all names for the accessors of the subwidgets. The
'ctrl', and 'code' keywords are directives (think of them as road-signs
in the argument list.) The sizer stuff still needs some thought, so
ignore the internals of layout(). The main point is that children()
and layout() create the methods __create_children() and __do_layout(),
which you then call later (once you have a $self.) By moving all of
the create, configure, and layout into a declarative "header" on your
class, you don't have to write the longhand code for widget creation
and layout. It definitely compacts the declaration. I'm hoping it
will also make it more readable (and maybe more importantly:
skimmable.) Note that $self is implied just about everywhere. I'm
also throwing numeric id's out the window (as far as the interface is
concerned) under the assumption that providing named accessors for the
objects is way better.
Aside: If you don't believe that is Perl (with no source filters), just
take my word for it, or read up on Moose and Jifty. Hey, I haven't
even gotten as far as abusing indirect object syntax!
Again, this is *preliminary* thinking. You can assist by adding entropy
and/or information.
Thanks,
Eric
--
We who cut mere stones must always be envisioning cathedrals.
--Quarry worker's creed
---------------------------------------------------
http://scratchcomputing.com
---------------------------------------------------
|