package Gtk2::Ex::CellLayout::Base; use strict; use warnings; use Carp; sub __celllayout_base__init { my ($self) = @_; require Tie::RefHash; $self->{'cell_list'} ||= do { my %cell_info_hash = (); tie %cell_info_hash, 'Tie::RefHash'; $self->{'cell_info_hash'} = \%cell_info_hash; []; }; } sub __celllayout_base__cinfo { my ($self, $cell) = @_; __celllayout_base__init ($self); my $cinfo = $self->{'cell_info_hash'}->{$cell}; if (! $cinfo) { croak "cannot add_attribute for cell not packed into layout"; } return $cinfo; } #------------------------------------------------------------------------------ sub _cell_list_changed { my ($self) = @_; $self->queue_draw; } sub _cell_attributes_changed { my ($self) = @_; $self->queue_draw; } sub _cell_list_ref { my ($self) = @_; __celllayout_base__init ($self); return $self->{'cell_list'}; } # setup the renderer to draw model row $n sub _cell_setup { my ($self, $cell, $n) = @_; my $model = $self->{'model'}; my $cinfo = __celllayout_base__cinfo ($self, $cell); if (! defined $cinfo) { return; } my $iter = $model->iter_nth_child (undef, $n); if (my $func = $cinfo->{'func'}) { &$func ($self, $cell, $model, $iter, $cinfo->{'funcdata'}); return; } my $ahash = $cinfo->{'attributes'} || {}; if (! %$ahash) { return; } $cell->set (map { my $name = $_; my $col = $ahash->{$_}; my $value = $model->get_value ($iter, $col); ($name, $value) } keys %$ahash); } #------------------------------------------------------------------------------ # gtk_cell_layout_add_attribute sub add_attribute { my ($self, $cell, $attribute, $column) = @_; my $cinfo = __celllayout_base__cinfo ($self, $cell); my $ahash = ($cinfo->{'attributes'} ||= {}); $ahash->{$attribute} = $column; $self->_cell_attributes_changed; } # gtk_cell_layout_set_attributes sub set_attributes { my ($self, $cell, %ahash) = @_; my $cinfo = __celllayout_base__cinfo ($self, $cell); $cinfo->{'attributes'} = \%ahash; $self->_cell_attributes_changed; } # gtk_cell_layout_set_cell_data_func sub set_cell_data_func { my ($self, $cell, $func, $funcdata) = @_; my $cinfo = __celllayout_base__cinfo ($self, $cell); $cinfo->{'func'} = $func; $cinfo->{'funcdata'} = $funcdata; $self->_cell_attributes_changed; } # gtk_cell_layout_get_cells sub get_cells { my ($self) = @_; return @{$self->{'cell_list'}}; } # gtk_cell_layout_clear sub clear { my ($self) = @_; __celllayout_base__init ($self); $self->{'cell_list'} = []; $self->{'cell_info_hash'} = (); $self->_cell_list_changed; } # gtk_cell_layout_clear_attributes sub clear_attributes { my ($self) = @_; foreach my $cinfo (@{$self->{'cell_info_hash'}}) { delete $cinfo->{'attributes'}; } $self->_attributes_changed; } # gtk_cell_layout_pack_start sub pack_start { my ($self, $cell, $expand) = @_; __celllayout_base__init ($self); if (exists $self->{'cell_info_hash'}->{$cell}) { croak "cannot pack a cell renderer into a layout more than once"; } push @{$self->{'cell_list'}}, $cell; $self->{'cell_info_hash'}->{$cell} = {}; $self->_cell_list_changed; } # gtk_cell_layout_pack_end sub pack_end { my ($self, $cell, $expand) = @_; __celllayout_base__init ($self); if (exists $self->{'cell_info_hash'}->{$cell}) { croak "cannot pack a cell renderer into a layout more than once"; } unshift @{$self->{'cell_list'}}, $cell; $self->{'cell_info_hash'}->{$cell} = {}; $self->_cell_list_changed; } # gtk_cell_layout_reorder sub reorder { my ($self, $cell, $position) = @_; __celllayout_base__init ($self); my $cell_list = $self->{'cell_list'}; foreach my $i (0 .. $#$cell_list) { if ($cell_list->[$i] == $cell) { splice @$cell_list, $i, 1; splice @$cell_list, $position, 1, $cell; $self->_cell_list_changed; return; } } croak "cannot reorder cell renderer not already packed into the layout"; } 1; __END__