Index: examples/cellrenderer_popup.pl =================================================================== RCS file: /cvsroot/gtk2-perl/gtk2-perl-xs/Gtk2/examples/cellrenderer_popup.pl,v retrieving revision 1.4 diff -u -r1.4 cellrenderer_popup.pl --- examples/cellrenderer_popup.pl 8 Nov 2003 06:23:57 -0000 1.4 +++ examples/cellrenderer_popup.pl 31 Jan 2004 06:14:16 -0000 @@ -59,9 +59,6 @@ ], ; -# !!!! very important !!!! -__PACKAGE__->_install_overrides; - use Data::Dumper; use constant xpad => 3; @@ -80,7 +77,7 @@ return (0, 0, $w + xpad * 2 + arrow_width, $h + ypad * 2); } -sub on_get_size { +sub GET_SIZE { my ($cell, $widget, $area) = @_; if ($area) { return (3, 3, $area->width - arrow_width - 2*xpad - 4, $area->height - 6); @@ -96,7 +93,7 @@ return $cell->{layout} = $widget->create_pango_layout (""); } -sub on_render { +sub RENDER { my ($cell, $drawable, $widget, $background_area, $cell_area, $expose_area, $flags) = @_; my $state = 'normal'; @@ -173,7 +170,7 @@ $editable->remove_widget; } -sub on_start_editing { +sub START_EDITING { my ($cell, $event, $widget, $path, $background_area, $cell_area, $flags) = @_; my $menu = Gtk2::Menu->new; my @data = @{ $cell->{list} }; Index: t/GtkCellRenderer.t =================================================================== RCS file: /cvsroot/gtk2-perl/gtk2-perl-xs/Gtk2/t/GtkCellRenderer.t,v retrieving revision 1.2 diff -u -r1.2 GtkCellRenderer.t --- t/GtkCellRenderer.t 10 Jan 2004 04:43:38 -0000 1.2 +++ t/GtkCellRenderer.t 31 Jan 2004 06:14:16 -0000 @@ -10,6 +10,26 @@ Gtk2::CellRendererText::, ; +my %hits; + +sub INIT_INSTANCE { $hits{init}++; } + +sub GET_SIZE { $hits{size}++; shift->SUPER::GET_SIZE (@_) } +sub RENDER { $hits{render}++; shift->SUPER::RENDER (@_) } +sub ACTIVATE { $hits{activate}++; shift->SUPER::ACTIVATE (@_) } +sub START_EDITING { $hits{edit}++; shift->SUPER::START_EDITING (@_) } + + +# do that again, in the style of 1.02x, to check for regressions of +# backward compatibility. +package Mup::CellRendererPopupCompat; + +use Test::More; + +use Glib::Object::Subclass + Gtk2::CellRendererText::, + ; + __PACKAGE__->_install_overrides; my %hits; @@ -67,6 +87,24 @@ $treeview->append_column ($column); +# +# custom cell renderer +# +ok ($renderer = Mup::CellRendererPopupCompat->new, 'Mup::CellRendererPopupCompat->new'); +$renderer->set (mode => 'editable'); +$column = Gtk2::TreeViewColumn->new_with_attributes ('selector', $renderer, + text => 0,); +# this handler commits the user's selection to the model. compare with +# the one for the typical text renderer -- the only difference is a var name. +$renderer->signal_connect (edited => sub { + my ($cell, $text_path, $new_text, $model) = @_; + my $path = Gtk2::TreePath->new_from_string ($text_path); + my $iter = $model->get_iter ($path); + $model->set ($iter, 2, $new_text); + }, $model); +$treeview->append_column ($column); + + $vbox->pack_start ($treeview, 1, 1, 0); $window->show_all; Index: xs/GtkCellRenderer.xs =================================================================== RCS file: /cvsroot/gtk2-perl/gtk2-perl-xs/Gtk2/xs/GtkCellRenderer.xs,v retrieving revision 1.15 diff -u -r1.15 GtkCellRenderer.xs --- xs/GtkCellRenderer.xs 28 Jan 2004 20:42:10 -0000 1.15 +++ xs/GtkCellRenderer.xs 31 Jan 2004 06:14:16 -0000 @@ -83,11 +83,20 @@ } /* - * the following functions look for on_whatever in the package belonging + * the following functions look for WHATEVER in the package belonging * to a cell. this is our custom override, since CellRenderer does not * have signals for these virtual methods. */ +#define GET_METHOD(cell, method, fallback) \ + HV * stash = gperl_object_stash_from_type (G_OBJECT_TYPE (cell)); \ + GV * slot = gv_fetchmethod (stash, fallback); \ + \ + if (slot && GvCV (slot)) \ + warn ("%s is deprecated, use %s instead", fallback, method); \ + else \ + slot = gv_fetchmethod (stash, method); \ + static void gtk2perl_cell_renderer_get_size (GtkCellRenderer * cell, GtkWidget * widget, @@ -97,11 +106,9 @@ gint * width, gint * height) { - HV * stash = gperl_object_stash_from_type (G_OBJECT_TYPE (cell)); - SV ** slot = hv_fetch (stash, "on_get_size", - sizeof ("on_get_size") - 1, 0); + GET_METHOD (cell, "GET_SIZE", "on_get_size"); - if (slot && GvCV (*slot)) { + if (slot && GvCV (slot)) { int count, i; dSP; @@ -115,10 +122,11 @@ PUSHs (sv_2mortal (newSVGdkRectangle_ornull (cell_area))); PUTBACK; - count = call_sv ((SV *)GvCV (*slot), G_ARRAY); + count = call_sv ((SV *)GvCV (slot), G_ARRAY); +// count = call_method ("GET_SIZE", G_ARRAY); SPAGAIN; if (count != 4) - croak ("on_get_size must return four values -- " + croak ("GET_SIZE must return four values -- " "the x_offset, y_offset, width, and height"); i = POPi; if (height) *height = i; @@ -145,10 +153,9 @@ GdkRectangle * expose_area, GtkCellRendererState flags) { - HV * stash = gperl_object_stash_from_type (G_OBJECT_TYPE (cell)); - SV ** slot = hv_fetch (stash, "on_render", sizeof ("on_render") - 1, 0); + GET_METHOD (cell, "RENDER", "on_render"); - if (slot && GvCV (*slot)) { + if (slot && GvCV (slot)) { dSP; ENTER; @@ -165,7 +172,8 @@ PUSHs (sv_2mortal (newSVGtkCellRendererState (flags))); PUTBACK; - call_sv ((SV *)GvCV (*slot), G_VOID|G_DISCARD); + call_sv ((SV *)GvCV (slot), G_VOID|G_DISCARD); +// call_method ("RENDER", G_VOID|G_DISCARD); FREETMPS; LEAVE; @@ -182,11 +190,10 @@ GtkCellRendererState flags) { gboolean retval = FALSE; - HV * stash = gperl_object_stash_from_type (G_OBJECT_TYPE (cell)); - SV ** slot = hv_fetch (stash, "on_activate", - sizeof ("on_activate") - 1, 0); - if (slot && GvCV (*slot)) { + GET_METHOD (cell, "ACTIVATE", "on_activate"); + + if (slot && GvCV (slot)) { dSP; ENTER; @@ -202,7 +209,8 @@ XPUSHs (sv_2mortal (newSVGtkCellRendererState (flags))); PUTBACK; - call_sv ((SV*) GvCV (*slot), G_SCALAR); + call_sv ((SV*) GvCV (slot), G_SCALAR); +// call_method ("ACTIVATE", G_SCALAR); SPAGAIN; retval = POPi; @@ -226,11 +234,9 @@ { GtkCellEditable * editable = NULL; - HV * stash = gperl_object_stash_from_type (G_OBJECT_TYPE (cell)); - SV ** slot = hv_fetch (stash, "on_start_editing", - sizeof ("on_start_editing") - 1, 0); + GET_METHOD (cell, "START_EDITING", "on_start_editing"); - if (slot && GvCV (*slot)) { + if (slot && GvCV (slot)) { SV * sv; dSP; @@ -248,7 +254,8 @@ PUSHs (sv_2mortal (newSVGtkCellRendererState (flags))); PUTBACK; - call_sv ((SV*) GvCV (*slot), G_SCALAR); + call_sv ((SV*) GvCV (slot), G_SCALAR); +// call_method ("START_EDITING", G_SCALAR); SPAGAIN; sv = POPs; @@ -307,20 +314,20 @@ # here's a pointless subclass implementation which # expensively illustrates how to chain up with cell renderers. - sub on_get_size { - return shift->parent_get_size (@_); + sub GET_SIZE { + return shift->SUPER::GET_SIZE (@_); } - sub on_render { - shift->parent_render (@_); + sub RENDER { + shift->SUPER::RENDER (@_); } - sub on_activate { - return shift->parent_activate (@_); + sub ACTIVATE { + return shift->SUPER::ACTIVATE (@_); } - sub on_start_editing { - return shift->parent_start_editing (@_); + sub START_EDITING { + return shift->SUPER::START_EDITING (@_); } For the curious, the parent_* functions use C to find the calling @@ -406,28 +413,32 @@ GtkCellRendererState flags -=for apidoc - -=for signature YourCellRendererPackage->_install_overrides - -Modify the underlying GObjectClass structure for the package -I to call Perl methods as virtual overrides for the -C, C, C, and C methods. The -overrides will look for I::on_get_size, -I::on_render, I::on_activate, -and I::on_start_editing. If the method is not -present, it will silently be skipped. - -Usually called on __PACKAGE__ immediately after registering a new cellrenderer -subclass. - -=cut +##=for apidoc +## +##=for signature YourCellRendererPackage->_install_overrides +## +##Modify the underlying GObjectClass structure for the package +##I to call Perl methods as virtual overrides for the +##C, C, C, and C methods. The +##overrides will look for I::GET_SIZE, +##I::RENDER, I::ACTIVATE, +##and I::START_EDITING. If the method is not +##present, it will silently be skipped. +## +##Usually called on __PACKAGE__ immediately after registering a new cellrenderer +##subclass. +## +##=cut void -_install_overrides (const char * package) +_INSTALL_OVERRIDES (const char * package) + ALIAS: + _install_overrides = 1 PREINIT: GType gtype; GtkCellRendererClass * class; CODE: + warn ("%s %s", ix == 1 ? "_install_overrides" : "_INSTALL_OVERRIDES", + package); gtype = gperl_object_type_from_package (package); if (!gtype) croak ("package '%s' is not registered with Gtk2-Perl", @@ -437,7 +448,8 @@ package, g_type_name (gtype)); /* peek should suffice, as the bindings should keep this class * alive for us. */ - class = g_type_class_peek (gtype); + //class = g_type_class_peek (gtype); + class = g_type_class_ref (gtype); if (! class) croak ("internal problem: can't peek at type class for %s(%d)", g_type_name (gtype), gtype); @@ -451,75 +463,16 @@ # class of the parent; so we rely on the package returned by caller(). # therefore, it is only valid to call these from the derived package. # -=for apidoc parent_render - -=for signature $cell->parent_render ($window, $widget, $rectangle, $background_area, $cell_area, $expose_area, $flags) - -=for arg ... (__hide__) -=for arg drawable (GdkDrawable) -=for arg widget (GtkWidget) -=for arg background_area (GdkRectangle_ornull) -=for arg cell_area (GdkRectangle_ornull) -=for arg expose_area (GdkRectangle_ornull) -=for arg flags (GtkCellRendererState) - -Invoke the C method of the parent class; only valid in virtual -overrides for C. - -=cut - -=for apidoc parent_activate - -=for signature boolean = $cell->parent_activate ($event, $widget, $path, $background_area, $cell_area, $flags) - -=for arg ... (__hide__) -=for arg event (GdkEvent) -=for arg widget (GtkWidget) -=for arg background_area (GdkRectangle_ornull) -=for arg cell_area (GdkRectangle_ornull) -=for arg expose_area (GdkRectangle_ornull) -=for arg flags (GtkCellRendererState) - -Invoke the C method of the parent class; only valid in virtual -overrides for C. - -=cut - -=for apidoc parent_start_editing - -=for signature GtkEditable_ornull = $cell->parent_start_editing ($widget, $rectangle) - -=for arg ... (__hide__) -=for arg event (GdkEvent) -=for arg widget (GtkWidget) -=for arg path (char*) -=for arg background_area (GdkRectangle_ornull) -=for arg cell_area (GdkRectangle_ornull) -=for arg flags (GtkCellRendererState) - -Invoke the C method of the parent class; only valid in virtual -overrides for C. - -=cut - -=for apidoc - -=for signature ($xoffset, $yoffset, $width, $height) = $cell->parent_get_size ($widget, $rectangle) - -=for arg ... (__hide__) -=for arg widget (GtkWidget) -=for arg rectangle (GdkRectangle_ornull) - -Invoke the C method of the parent class; only valid in virtual -overrides for C. - -=cut void -parent_get_size (GtkCellRenderer * cell, ...) +GET_SIZE (GtkCellRenderer * cell, ...) ALIAS: - parent_render = 1 - parent_activate = 2 - parent_start_editing = 3 + RENDER = 1 + ACTIVATE = 2 + START_EDITING = 3 + parent_get_size = 4 + parent_render = 5 + parent_activate = 6 + parent_start_editing = 7 PREINIT: GtkCellRendererClass * class; GType thisclass, parent_class; @@ -530,6 +483,10 @@ eval_pv ("$_ = caller;", 0); thisclass = gperl_type_from_package (SvPV_nolen (DEFSV)); SvSetSV (DEFSV, saveddefsv); + if (!thisclass) { + warn ("bollocks! %d", ix); + return; + } /* look up his parent */ parent_class = g_type_parent (thisclass); if (! g_type_is_a (parent_class, GTK_TYPE_CELL_RENDERER)) @@ -538,7 +495,8 @@ /* that's our boy. call one of his functions. */ class = g_type_class_peek (parent_class); switch (ix) { - case 0: + case 4: /* deprecated parent_get_size */ + case 0: /* GET_SIZE */ if (class->get_size) { gint x_offset, y_offset, width, height; class->get_size (cell, @@ -555,7 +513,8 @@ PUSHs (sv_2mortal (newSViv (height))); } break; - case 1: + case 5: /* deprecated parent_render */ + case 1: /* RENDER */ if (class->render) class->render (cell, SvGdkDrawable_ornull (ST (1)), /* drawable */ @@ -565,7 +524,8 @@ SvGdkRectangle_ornull (ST (5)), /* expose_area */ SvGtkCellRendererState (ST (6))); /* flags */ break; - case 2: + case 6: /* deprecated parent_activate */ + case 2: /* ACTIVATE */ if (class->activate) { gboolean ret; ret = class->activate (cell, @@ -579,7 +539,8 @@ PUSHs (sv_2mortal (newSViv (ret))); } break; - case 3: + case 7: /* deprecated parent_start_editing */ + case 3: /* START_EDITING */ if (class->start_editing) { GtkCellEditable * editable; editable = class->start_editing (cell,