Implementing GInterfaces in Perl



With CVS HEAD of Glib and Gtk2 (which will probably become 1.034 tomorrow after i've had some sleep), it is now possible to implement GInterfaces in Perl code. This is the last of the Really Big Features that need to get in before 1.040.

"What is muppet babbling about now?" you wonder...


The short answer: you can now implement TreeModels and other interface types in Perl.


The long answer:

GLib's type system supports only single inheritance, for some good technical reasons that make you shudder in horror at the thought of what C++ compilers must actually be doing. As a workaround, a single type may implement any number of "GInterface"s. A GInterface is really just a vtable which can have signals (and in 2.4, properties).

In Perl, multiple inheritance is easy -- just add the other class to @ISA. So that's what we do; GInterface types simply get prepended to an object type's @ISA by startup code.

The harder part is marshalling the vtable functions from C to Perl, which is where this simple but hard-to-explain change comes in.

By adding an extra key to the Glib::Object::Subclass line used to create your own Glib::Object, you can trigger perl to call some ALL_CAPS_NAMED methods that provide the actual implementations behind the methods of interface types. (This should all look similar in spirit to the CellRenderer vfunc stuff.)

Maybe this will explain it more easily:

  package Mup::MultilineEntry;
  # add the Gtk2::CellEditable interface to a Gtk2::TextView.

  use Gtk2;
  use Glib qw(TRUE);

  use Glib::Object::Subclass
      Gtk2::TextView::,
      interfaces => [ Gtk2::CellEditable:: ],
      ;

  # override the CellEditable vfuncs that do the actual work
  sub START_EDITING { warn "start editing\n"; }
  sub EDITING_DONE { warn "editing done\n"; }
  sub REMOVE_WIDGET { warn "remove widget\n"; }

  # some convenience methods for user code
  sub set_text { shift->get_buffer->set_text (shift); }
  sub get_text {
      my $buffer = shift->get_buffer;
      $buffer->get_text ($buffer->get_start_iter,
                         $buffer->get_end_iter, TRUE);
  }


Currently, only Gtk2::CellEditable and Gtk2::TreeModel are implemented. I also added two examples which demonstrate the process:

  examples/customlist.pl
        gtk2-perl port of the custom model from the treeview tutorial.

  examples/customrenderer.pl
        multi-line editable cells in a tree view.



I've just committed code that i've been knocking around for three or four months, so i feel kinda accomplished at the moment. Big thanks to Bjarne Steinsbo for very helpful conversation and rationalization, and for fixing the TreeIters to keep them from leaking like crazy. I did some rather crude leak testing and the iters' SVs do not appear to leak at all.

--
I bring the rock, and provided it is fiscally responsible, I will bring the funk as well. And that's fo-shizzle.
        -- Saturday Night Live




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