Re: chaining to superclass in CUSTOM_TAG_START



muppet <scott asofyet org> writes:

And then how do you decide on the semantics of when to chain up and
when not?

I'd imagine always chaining would be pretty natural for buildable.
Probably let the subclass get first crack at the tag so it could
override, then to the superclass.

Though I notice there'd be some nonsense needed in the custom_tag_end.
If you handled the tag yourself then you do your own cleanups, but if
you chained up then you chain up again.  GtkContainer in
gtk_container_buildable_custom_tag_end() decides that by looking at the
tag name a second time, knowing it takes <packing> and chains for
anything else.  But that looks like a great way for mistakes creep in!
:-)

The obvious thing, putting the control into the hands of the widget  
author, is just as irritiatingly complicated.

Yep, and might mean wrapping GMarkupParser (something I see has been
deliberately avoided) if such a value gets returned via perl code (even
if never actually manipulated).

(... We have to do rather deep black magic to get this to work in
Gtk2::CellRenderer.)

Speaking of renderers, I arrived at this looking to have buildability in
a new widget implementing the GtkCellLayout interface.  The core widgets
with that interface take renderers as children and add an "<attributes>"
tag (examples under GtkCellLayout and GtkTreeView).  I thought I could
do the same.  gtkcelllayout.c has parser/setter code for that, but it's
not exposed to the public.  Thus, mostly working, ...


sub ADD_CHILD {
  my ($self, $builder, $child, $type) = @_;
  $self->pack_start ($child, 0);
}

sub CUSTOM_TAG_START {
  my ($self, $builder, $child, $tagname) = @_;
  if ($child && $tagname eq 'attributes') {
    return Gtk2::Ex::CellLayout::BuildAttributes->new (cell_layout => $self,
                                                       cell_renderer=> $child);
  } else {
    return undef;
  }
}

package Gtk2::Ex::CellLayout::BuildAttributes;
use strict;
use warnings;
use Gtk2;

sub new {
  my ($class, %self) = @_;
  return bless \%self, $class;
}

sub START_ELEMENT {
  my ($self, $context, $element_name, $attributes) = @_;

  if ($element_name eq 'attributes') {
    # nothing to do in the intro bit

  } elsif ($element_name eq 'attribute') {
    $self->{'attr_name'} = $attributes->{'name'};

  } else {
    # this is a g_warning like GtkCellLayout attributes_start_element() uses,
    # not sure if a "carp" would be more helpful
    Glib->warning (undef, "Unsupported tag for Gtk2::Ex::CellLayout::Base \"$element_name\"\n");
  }
}

sub TEXT {
  my ($self, $context, $text) = @_;
  if ($self->{'attr_name'}) {
    # add_attribute will complain for us if $text isn't a string of digits
    $self->{'cell_layout'}->add_attribute ($self->{'cell_renderer'},
                                           $self->{'attr_name'}, $text);
    $self->{'attr_name'} = undef;
  }
}

# This is called at each closing </attribute> etc.  We don't need to do
# anything, but the Gtk2-Perl code in Gtk2::Buildable insists we provide a
# method.
#
sub END_ELEMENT {
}



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