From: Mark D. <mar...@zn...> - 2007-03-17 12:18:24
|
Hi Eric and All, This counts as entropy, I think. I have been working on something that scratches similar itches, but in slightly different ways. Some of my main 'itches' were the same as yours, I think: or'd flags - I always have to visit the manual EVT_MACRO syntax - always have to look this up even though its very simple - as you say, it seems wrong. object constructors - always have to visit the manual. Using (rather cheekily) the namespace VP, I was drawn towards creating a series of classes for the GUI components. So, if you inherit from VP::Frame you get an additional constructor: my $frame = MyFrame->VPNew(); VPNew accepts optional hash parameters: my $frame = MyInherits->VPNew( title => 'My Window', bordertop => 0 ); Internally it applies defaults to any missing params before calling its own 'new'. Its own 'new' does the $class->SUPER::new(@) before calling $self->__after_new() $self->__create_controls() $self->__create_events() $self->__layout() which in turn call $self->VPOnNew() $self->VPOnCreateControls() $self->VPOnCreateEvents() $self->VPOnLayout() which can be overridden in the derived class. I had four simply because it adds a helpful structure when you come to write documentation. There are two procs for each 'section' because down the line I have an itch which you don't share which is a bit of a dialog designer - but that's a separate thread. There is also $self->VPOnClose() which does the sensible thing for most situations. For sizers, I looked at the possibility of subclassing and decided no. I stuck some methods in a common class inherited by my toplevel windows and containers like $self->CreateBoxSizer() which take perl hash arguments or return sensible default sizers. Underlying it all, I wanted to make this provide an easier interface to starting with Wx. I've long since abandon thoughts of perlifying the wxWidgets manual, so, assuming I document the VP__ methods, folks have to be able to figure everything else out from the wxWidgets manual. Which brings me to EVT_MACRO syntax. I think all that may be needed here is prominent documentation of the $evthandler->Connect($evtsource, $evtidstart, $evtidend, $functionref); syntax with a pointer to the alternative event macro style. Add a couple of documented VP methods to make it even easier: $evthandler->VPConnectEvent($evtsource, $evttype, $functionref); $evthandler->VPConnectEventRange($evtsource, $startid, $endid, $functionref); I think I would personally have found this easier to use, but the EVT_MACRO syntax is a very clever way of making the wxWidgets docs easier to follow. I'd still have to visit the docs to look up the event types, of course. On XRC, I've never seen the point of this in Perl, an interpreted language - I have no desire to share templates across different languages. There are better perl specific ways to do this. Your WxPerl::Declare stuff looks very interesting. My own stuff keeps collections of named child objects allowing $frame->VPGet('childname') syntax or $frame->VPGet('childname1','childname2','childname3'); for children of child containers. $frame->childname1->childname2->childname3(); looks much more attractive. I'm not sure that the syntax that gets you there fulfills my own goal of allowing easier entry to Wx usage. I'd have to play for a while. Hmmm. Same itches but differing solutions. Regards Mark Eric Wilhelm wrote: > 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 |