From: Scott L. <sla...@th...> - 2002-09-06 06:25:14
|
On Thu, 5 Sep 2002, Mattia Barbon wrote: > (BTW subclassing wxMenuBar is unusual, why do you need it? > just curious); I just did it to separate the menubar code in its own module. For example, to do a minimal application with a menubar to trigger a dialog, I would have 1) a main script, 2) MyApp.pm, 3) MyFrame.pm, 4) MyMenuBar.pm, 5) MyDialog.pm, 6) MyPanel.pm, with Frame the parent of MenuBar and Dialog, and Dialog the parent of Panel. Maybe it's a little awkward if I have a dialog triggered by a menu event, though, because the dialog has the Frame for its parent and I end up doing things like this from the MenuBar subclass no strict 'refs'; EVT_MENU($parent, '...', \&{ref($parent) . 'OnMenuDialog'}); (so MyFrame isn't hardcoded, though still we have OnMenuDialog hardcoded..) to pass it back to the Frame class anyway. So maybe this is why it's unusual to subclass MenuBar. Anyway, MenuBar is not the only scalar class I tried to subclass. I also tried some dialogs like TextEntryDialog and SingleChoiceDialog. You might again say it's unusual to subclass these, as they are small and specific, but I like to treat all the dialog as objects when I do something like $d = MyDialog->new(); $d->Destroy(); then inside of MyDialog I did something like (it's from memory, hopefully you get the idea though) sub new { ... if ($self->ShowModal() == wxOK) { $self->{textfield} = $self->GetStringSelection(); ... } return $self; } Basically I mean I treat the Dialog as an object which had some attributes set by the user (as a CGI programmer, I think of the form submit button and $q->param() to get the CGI form values), then I use $d from above like if ($d->{textfield} =~ /whatever.../) { .... } and so on. (Really I use Class::Accessor::Fast and Class::Fields modules to do easy AUTOLOAD of private and public attributes, so instead of $self->{textfield} = ... I have $self->textfield(...) and access simply with $self->textfield - so from the perspective the dialog parent it seems as if $d->textfield is an accessor method of an object.) > I can move wxMenuBar (or any other class) to subclassable (or > to not subclassable) it just requires some small work. Speaking of this.. what is the trick? I'm trying to understand what makes the objects be either a HASH or SCALAR reference. I grepped for 'bless' in the source code, and I think the only relevant case is function wxPli_make_object in ./cpp/helpers.cpp. It creates a new HASH, but how is a SCALAR object created? I looked at XS/Menu.xs for MenuBar which is a SCALAR, and its `new' is barebones, just translates the C++ directly. On the other hand, XS/Frame.xs, XS/TreeCtrl.xs, XS/Panel.xs, those have RETVAL = new wxPliSOMETHING where SOMETHING is Frame, TreeCtrl, Panel, etc. I search around a little -- panel.h, helpers.h -- find these WXPLI_DEFAULT_CONSTRUCTOR and so on all call wxPli_make_object. Aha. But still, what about the SCALAR ones? There is a comment in cpp/helpers.cpp of the wxPli_sv_2_object function in wxHashModule class that says "get 'this' pointer from a blessed scalar/hash reference". I grepped wxPli_sv_2_object and found it in ./typemap, but it was in the INPUT section. In the TYPEMAP section, I found both wxMenuBar and wxFrame are O_WXOBJECT, and in the OUTPUT section, O_WXOBJECT uses wxPli_object_2_sv. It's hurting my mind now. |