Question of Style [was Re: Conceptual Question on Signal Handling in Subclasses]
- From: Ian Flanigan <flan lean to>
- To: Havoc Pennington <hp redhat com>
- Cc: Ian Flanigan <flan lean to>, gtk-app-devel-list gnome org
- Subject: Question of Style [was Re: Conceptual Question on Signal Handling in Subclasses]
- Date: Tue, 5 Jun 2001 05:15:07 -0700
Havoc Pennington writes:
Write a custom object derived from GtkObject using the GTK
object/type system. See for example the source code for any widget
in GTK. It involves knowing a lot about the GTK object/type
system, so you may not want to go there.
Okay, maybe I didn't explain things well in the first message.
I _am_ trying to use the GTK object/type system. I _have_
successfully built multiple classes, some derived from GtkWidget and
some from GtkObject. For the most part, they work great.
What I am trying to do is design a class in the GTK object system that
has something equivalent to virtual functions as non-default signal
handlers. I want to do this in a way that other GTK programmers will
understand easily.
I know that I can create virtual-like functions by having something in
the class structure like:
struct _MyGtkObjectClass
{
...
void (* my_gtk_object_virt_func) ( MyGtkObject *obj );
...
}
The thing is, I've looked through many of the GTK class definitions
and I've never seen a virtual function that wasn't the default handler
for a signal. This leads me to believe that in GTK virtual functions
are, by convention, only used for signal handling. Is this true?
The task I'm trying to accomplish is to use gtk_signal_connect_object
to connect one object's signal to another object's handler that is a
virtual function (so that subclasses can choose how they handle the
signal). I've thought of three ways:
1) Naked virtual functions. This is what Havoc suggested in his first
reply.
struct _MyNakedObjectClass
{
...
void (* my_naked_object_virtual) ( MyNakedObject *obj, ... );
...
}
void
connect_two_objects( GtkObject *x, MyNakedObject *y )
{
MyNakedObjectClass *y_class;
y_class = MY_NAKED_OBJECT_CLASS( GTK_OBJECT( y )->klass );
g_assert( IS_MY_GTK_OBJECT_CLASS( y_class ) );
gtk_signal_connect_object_while_alive( GTK_OBJECT( x ), "my_signal",
y_class->my_naked_object_virtual,
GTK_OBJECT( y ) );
}
2) Corresponding Signals. Here I would have a signal in my object
that corresponded to the signal in the other object. Then I would
have a function that would just emit that signal, like this:
struct _MyCorrespondingObjectClass
{
...
void (* my_corresponding_object_virtual) ( MyCorrespondingObject *obj,
... );
...
}
[ assume that my_corresponding_object_virtual is set up as the
default signal handler for "my_corresponding_signal" ]
void
connect_two_objects( GtkObject *x, MyCorrespondingObject *y )
{
MyCorrespondingObjectClass *y_class;
gtk_signal_connect_object_while_alive( GTK_OBJECT( x ), "my_signal",
my_corresponding_object_handler,
GTK_OBJECT( y ) );
}
void
my_corresponding_object_handler( MyCorrespondingObject *obj,
GtkObject *other )
{
gtk_signal_emit_by_name( GTK_OBJECT( obj ),
"my_corresponding_signal",
other );
}
3) Wrapped virtual functions. Here I wrap the virtual function call
with a static function. That way the connect_two_objects function
doesn't have to do anything fancy.
struct _MyWrappedObjectClass
{
...
void (* my_wrapped_object_virtual) ( MyWrappedObject *obj, ... );
...
}
void
connect_two_objects( GtkObject *x, MyWrappedObject *y )
{
gtk_signal_connect_object_while_alive( GTK_OBJECT( x ), "my_signal",
my_wrapped_object_virtual_wrapper,
GTK_OBJECT( y ) );
}
void
my_wrapped_object_virtual_wrapper( MyWrappedObject *obj,
GtkObject *other )
{
MyWrappedObjectClass *obj_class;
obj_class = MY_WRAPPED_OBJECT_CLASS( GTK_OBJECT( obj )->klass );
g_assert( IS_MY_GTK_OBJECT_CLASS( obj_class ) );
obj_class->my_wrapped_object_virtual( obj, other );
}
For the moment, I've implemented method 1 and it works fine. I just
wonder if it's the way people will expect this kind of thing to be
done.
Any advice or comments are much appreciated.
Thanks,
Ian Flanigan
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]