use Data::Dumper; our @ISA = ('Tk::Frame'); Tk::Widget->Construct('MyScrollableEdit'); sub Populate{ my $self = shift; my $args = $_[0]; my $data = delete($args->{-data}) || []; my $rows = delete($args->{-rows}) || 10; $self->SUPER::Populate($args); my @labels = (); my @entries = (); for (0..$rows-1){ my $l = $self->Label(-textvariable => \$data->[$_]{label}, -anchor=> 'e' ); my $w = $self->Entry(-textvariable => \$data->[$_]{value}); $l->grid($w,-sticky=>'e', -pady=>3, -padx=>2); $w->gridConfigure(-sticky=>'ew'); push @labels, $l; push @entries, $w; } $self->ConfigSpecs(-data => ['PASSIVE', undef, undef, $data], -rows => ['PASSIVE', undef, undef, $rows], -labels => ['PASSIVE',undef, undef, \@labels], -entries=> ['PASSIVE',undef, undef, \@entries], -offset => ['PASSIVE',undef, undef, 0], ); } sub yview{ my $self = shift; #print Dumper \@_; my $sb = shift; my $data = $self->cget('-data'); my $rows = $self->cget('-rows'); my $entries = $self->cget('-entries'); my $labels = $self->cget('-labels'); my $offset = $self->cget('-offset'); my $visible = @$data / $rows; my $max_offset = @$data - $rows; my $units; if ($_[0] eq 'scroll'){ $units = $_[1]; if ($_[2] ne 'units'){# page $units = $units * ($rows-3); } } elsif ($_[0] eq 'moveto'){ $units = @$data * $_[1] - $offset; } else{ $units = $_[0]; } $offset = int($offset + $units); if ($offset < 0){$offset = 0} elsif ($offset > $max_offset){$offset = $max_offset} for (0..$rows-1){ my $row = $offset + $_; $entries->[$_]->configure(-textvariable => \$data->[$row]{value}); $labels->[$_]->configure(-textvariable => \$data->[$row]{label}); } $self->configure(-offset => $offset); my $first = $offset / @$data ; my $last = ($offset + $rows) / @$data ; $sb->set($first, $last); }