Re: how are interfaces created? (talking about the Java-like "interface")



Le samedi 29 janvier 2005 �2:03 -0800, Ben Johnson a �it :
> On Sat, Jan 29, 2005 at 07:47:08PM +0100, Jean Br?fort wrote:
> > Le samedi 29 janvier 2005 ?? 10:10 -0800, Ben Johnson a ??crit :
> > > On Sat, Jan 29, 2005 at 08:27:55AM +0100, Jean Br?fort wrote:
> > > > Le vendredi 28 janvier 2005 ?? 15:22 -0800, Ben Johnson a ??crit :
> > > > > I want to understand how interfaces are defined and used/implemented.
> > > ...
> > > > 
> > > > It's a GInterface object. When creating a new class of object, you
> > > > derive it from an existing class and you can add one or several
> > > > interfaces to enrich your class.
> > > > Here is a sample code I used to add printing support to the gnome canvas
> > > > (this code is used by GChemPaint).
> > > > 
> > > > GType
> > > > gnome_canvas_group_ext_get_type (void)
> > > > {
> > > > 	static GType group_ext_type;
> > > > 
> > > > 	if (!group_ext_type) {
> > > > 		static const GTypeInfo object_info = {
> > > > 			sizeof (GnomeCanvasGroupExtClass),
> > > > 			(GBaseInitFunc) NULL,
> > > > 			(GBaseFinalizeFunc) NULL,
> > > > 			(GClassInitFunc) gnome_canvas_group_ext_class_init,
> > > > 			(GClassFinalizeFunc) NULL,
> > > > 			NULL,			/* class_data */
> > > > 			sizeof (GnomeCanvasGroupExt),
> > > > 			0,			/* n_preallocs */
> > > > 			(GInstanceInitFunc) gnome_canvas_group_ext_init,
> > > > 			NULL			/* value_table */
> > > > 		};
> > > > 
> > > > 		static const GInterfaceInfo print_info = {
> > > > 			(GInterfaceInitFunc) gnome_canvas_group_print_init,
> > > > 			NULL, NULL
> > > > 		};
> > > > 
> > > > 		group_ext_type = g_type_register_static (GNOME_TYPE_CANVAS_GROUP_EXT,
> > > > "GnomeCanvasGroupExt",
> > > > 						    &object_info, 0);
> > > > 
> > > > 		g_type_add_interface_static (group_ext_type, G_TYPE_PRINTABLE,
> > > > &print_info);
> > > > 	}
> > > > 
> > > > 	return group_ext_type;
> > > > }
> > > > 
> > > > Hope this helps,
> > > 
> > > It does help *very* much.  Thank you.  I hope you don't answering a
> > > couple questions.
> > > 
> > > Once an object of GnomeCanvasGroupExtClass is instantiated, can it be
> > > cast as something else having to do with the print_info (Printable?)?
> > > How is that done?  And, when the cast is performed, what functionality
> > > is exposed?
> > 
> > Yes, you can cast it either to a GPrintable or a GnomeCanvasExtGroup. As
> > a sample, I reproduce the function which prints the group:
> > 
> > void gnome_canvas_group_ext_print (GPrintable *printable,
> > GnomePrintContext *pc)
> > {
> > 	GList *list;
> > 	double affine[6];
> > 	GnomeCanvasItem *item;
> > 	g_return_if_fail (GNOME_IS_CANVAS_GROUP_EXT (printable));
> > 	for (list = GNOME_CANVAS_GROUP (printable) ->item_list; list; list =
> > list->next) {
> > 		item = GNOME_CANVAS_ITEM (list->data);
> > 		if (!(item->object.flags & GNOME_CANVAS_ITEM_VISIBLE))
> > 			continue;
> > 		if (GNOME_IS_CANVAS_GROUP_EXT(item))
> > 			gnome_canvas_group_ext_print (G_PRINTABLE (item), pc);
> > 		else if (G_IS_PRINTABLE (item))
> > 		{
> > 			gnome_canvas_item_i2w_affine (item, affine);
> > 			gnome_print_gsave(pc);
> > 			gnome_print_concat(pc, affine);
> > 			g_printable_print (G_PRINTABLE (item), pc); 
> > 			gnome_print_grestore(pc);
> > 		}
> > 	}
> > }
> > 
> > 
> > 
> 
> excellent!  I think I'm understanding this well enough now.  I have a
> couple more questions...
> 
> Is GPrintable a completely new type that you defined?  I haven't been
> able to find it anywhere else.

Yes, but the idea was suggested by Michael Meeks, AFAIK. It is just used
in GChemPaint.

> There is one thing that's confusing me.  From your definitions earlier I
> gathered that an object of GnomeCanvasGroupExtClass is by definition
> also a G_TYPE_PRINTABLE.  In the code you just posted...
> 
> > 		if (GNOME_IS_CANVAS_GROUP_EXT(item))
> > 			gnome_canvas_group_ext_print (G_PRINTABLE (item), pc);
> > 		else if (G_IS_PRINTABLE (item))
> > 		{
> 
> I'm assuming that GNOME_IS_CANVAS_GROUP_EXT(item) tests to see if item
> is an object of the GnomeCanvasGroupExtClass class and G_IS_PRINTABLE()
> tests to see if item is a G_TYPE_PRINTABLE.  If one is true, isn't the
> other?

No, if it is a GnomeCanvasGroupExt, it is also a GPrintable, but because
of internals of GnomeCanvas, if it was treated as every GPrintable, the
affine transform would be applied several times.
Not all GPrintable are groups, they might be lines, rectangles, text or
other items (otherwise nothing would be printed).

> I'm looking at the GTK_TYPE_EDITABLE interface now as it is used in
> GtkEntryClass definition, which is helping a lot too.  I see that the
> GtkEditableClass is a lot like any other class but its member functions
> have no definition...  so if thing declared itself to be GTK_TYPE_EDITABLE 
> but didn't set those function pointers it should probably cause segfaults.

If you add a GTK_TYPE_EDITABLE interface to your class, you'll have to
provide an init function for the interface just like
gnome_canvas_group_print_init in my sample, and in this function, you
must give values to all the pointers in the GtkEditableClass structure.
Something as:

static void
my_derived_editable_init (GtkEditableClass *iface)
{
	iface->insert_text = my_derived_editable_insert_text;
	iface->delete_text = my_derived_editable_delete_text;
	iface->changed = my_derived_editable_changed;
	...
}

and implement your functions:

static void
my_derived_editable_insert_text	(GtkEditable    *editable,
				     const gchar    *text,
				     gint            length,
				     gint           *position);

and so on.





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]