Hi,
On 15/02/2013 19:59, Dave Hayes wrote:
1) Apparently Wx::ComboCtrl does not respect or use wxTE_PROCESS_TAB. Why?
That's a decision of wxWidgets designers / maintainers. It seems
sensible to me as a combo box that captures tab key presses would be
quite an odd thing. Best roll your own from scratch if that is what you
want.
2) There's an infrequent practice in wxperl of returning blessed scalar
references for subclassable controls. I'm not sure I like those very
much, since I normally expect blessed references to be hashes (or less
Sometimes wxWidgets classes do not lend themselves to easy wrapping in
Wx and when there are simple workarounds in Perl it doesn't seem worth
the effort to figure out and test a system of changing this
However, I cannot do
(unless there is some perl mysticism I am unaware of):
package MyComboPopup;
use base qw(Wx::PlComboPopup);
sub new {
my $class = shift;
my $self = $class->SUPER::new(@_);
$self->{'mydata'} = 'foo';
EVT_CHAR($self, sub {
my ($self, $event) = @_;
my $data = $self->{'mydata'};
....
});
return $self;. This would normally be a pedantic issue except for
the practice of subclassing controls and events
}
This is because $self will be a blessed scalar reference.
wxComboPopup is a bit of a special case. It is implemented in wxWidgets
as a 'mix-in' - and we can't wrap that directly in wxPerl. It doesn't
inherit from anything (least of all wxEvtHandler) so above code would
never work.
The Wx::Demo code shows how to use it. Don't do anything on the 'new'
constructor. Do it in an overridden 'Create'.
I feel I am
forced to do things like this (in the combo control object):
package MyComboCtrl;
use base qw(Wx::ComboCtrl);
sub new {
my $class = shift;
my $self = $class->SUPER::new(@_);
$self->{'mydata'} = 'foo';
my $popup = MyComboPopup->new;
EVT_CHAR($popup, sub {
my ($popup, $event) = @_;
my $data = $self->{'mydata'};
....
});
return $self;
}
If I understand correctly, this will produce a closure on $self which
means it will never be destroyed. I don't see a way to avoid this
easily, with the possible exception of Scalar::Util::weaken.
As noted above, this isn't a particular issue for your ComboCtrl usage -
as you cannot attach events to the Wx::ComboPopup - which is just a thin
helper class. So I cannot give you a working example for the above
problem - you cannot attach events to a Wx::ComboPopup.
Almost any actual eventhandler class ( the '$self' in my($self,$event) =
@_; ) will be a hash reference. There are some exceptions ( some of the
ready-made dialog classes) but nothing that you should come across in
normal usage.
Let's pretend '$popup' in the above example is some sort of window that
can actually receive events.
You want to handle the results of an EVT_CHAR in $popup in some parent
window of $popup.
Personally I would say that you should not write code that relies on
child windows knowing what their parents are. So you ought to raise some
sort of custom commandevent in the child and handle that in the parent.
However, you can ignore that if you wish.
You can always do
$obj->GetParent() if you know that your direct parent is the window you
want.
More usefully, if you want your top level parent (a frame or dialog)
my $frame = Wx::GetTopLevelParent($obj);
If you want to get at a specific window but don't want to hang on to a
reference to it, get it by 'id'.
my $savedid = $somewindow->GetId();
....
....
.... later when $somewindow no longer in scope ...
my $somewindow = Wx::Window::FindWindowById( $savedid );
Hope it helps.
Mark