Re: size_request/size_allocate question
- From: muppet <scott asofyet org>
- To: Jaap Karssenberg <j g karssenberg student utwente nl>
- Cc: GTK2-Perl List <gtk-perl-list gnome org>
- Subject: Re: size_request/size_allocate question
- Date: Fri, 14 Oct 2005 08:16:30 -0400
On Oct 14, 2005, at 5:52 AM, Jaap Karssenberg wrote:
I try to subclass Gtk2::HBox and I want to handle size allocation
myself. I figured overloading size_request() and size_allocation()
would do the trick, but these methods don't get called when the
widget is shown :( I've included my code below, does anyone have a
suggestion what I do wrong ?
That's not how you override signals. This is another case of the
GObject-as-a-perl-object abstraction leaking some of the GObject
details.
size-request and size-allocate are widget signals. The methods
size_request() and size_allocate() emit the corresponding signals,
and the real work happens in the class closure for the signal handler.
What you have done is provide a new implementation of the methods
that will be seen by perl when it searches for the method by $widget-
>size_request() by looking at the actual type of $widget and
searching @ISA. The problem is that for any *interesting* invocation
of this method, it will be called from the C function
gtk_widget_size_request(), deep within gtk+ --- that is, control
never gets to the perl method lookup! You have to ensure that these
things are invoked by C code, which means that normal perl OO stuff
doesn't work quite right.
The way to do this, then, is to override the "class closure" for the
signal.
See also: http://gtk2-perl.sourceforge.net/doc/
subclassing_widgets_in_perl.html (which explains the above situation)
and http://gtk2-perl.sourceforge.net/doc/examples/
histogramplot.pl.html (which has a size-request override).
Also, as you'd written it, the constructor was completely broken.
SUPER::new would find Gtk2::HBox::new(), which unconditionally calls
gtk_hbox_new(), giving you an actual GtkHBox blessed as a
Gtk2::HBox. Your own methods would not be found, and your new
subclass would not be created (the GType is wrong). The correct way
to instantiate GObject subclasses is to use Glib::Object::new();
Glib::Object::Subclass will alias this for you, so you don't need to
provide a constructor.
Changes to your code:
- rename size_request() to _size_request()
- rename size_allocate() to _size_allocate()
- change SUPER::size_request and SUPER::size_allocate to
signal_chain_from_overridden.
- add a signal map to the Subclass pragma to tell your new GType to
invoke your class closures
- remove new()
- if necessary, do instance initialization (defaults, etc) in
INIT_INSTANCE().
package Gtk2::Ex::ButtonPathBar;
our $VERSION = '0.01';
use strict;
use Gtk2;
use Glib::Object::Subclass
Glib::HBox::,
signals => {
# provide overrides for widget signals
size_allocate => \&_size_allocate,
size_request => \&_size_request,
},
;
# use a different name to avoid clashes and the resulting infinite loops
sub _size_request {
my $self = shift;
print "Got a size request\n";
# SUPER doesn't work for signals.
$self->signal_chain_from_overridden (@_);
}
#again, a different name
sub _size_allocate {
my ($self, $allocation) = @_;
my ($w, $h) = ($allocation->width, $allocation->height);
print "got allocation for $w, $h\n";
$self->signal_chain_from_overridden ($allocation);
}
1;
# End Code listing
--
elysse (pregnant): are your hands cold?
me: uh, i suppose so.
elysse: will you put them on me?
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]