App-Chart
view release on metacpan or search on metacpan
misc/t-reorder.pl view on Meta::CPAN
my $offset = 0;
foreach my $newpos (0 .. $#$aref) {
my $oldpos = $aref->[$newpos];
if ($newpos != $oldpos + $offset) {
my $item = $children[$oldpos];
move (\@widget, $item, $newpos);
$offset -= ($newpos <=> $oldpos+$offset);
}
if (DEBUG) { print " ",join(' ', map {$_->[0]} @widget),
" newpos $newpos offset $offset\n"; }
}
}
# print Dumper ($aref);
# print Dumper (\@widget);
if (DEBUG) {
print join(' ',@$aref), ' -> ', join(' ',map{$_->[0]}@widget), "\n";
}
foreach my $i (0 .. $#$aref) {
my $got = $widget[$i]->[0] - 10;
my $want = $aref->[$i];
if ($got != $want) {
print " wrong at $i (got $got, want $want)\n";
print Dumper($aref);
print Dumper(\@widget);
exit 0;
}
}
}
# [-1..-1]
foreach my $perm (@perms) {
reorder ($perm);
}
exit 0;
#------------------------------------------------------------------------------
# reorder helper
#
# make_reorder_test() returns a code ref procedure to test whether
# successive entries in a TreeModel style reorder array need to be applied.
#
# The procedure should be called $test->($newpos,$oldpos) on newpos values 0
# to N successively, with oldpos the position before any reordering. It
# returns true if a move should be applied. Eg.
#
# $test = make_reorder_test();
# foreach my $newpos (0 .. $#$reorder_array) {
# my $oldpos = $reorder_array->[$newpos];
# if ($test->($newpos,$oldpos)) {
# my $item = $original_items[$oldpos];
# move ($item, $newpos);
# }
# }
#
# The move is expected to be in the style of Gtk2::Menu::reorder_child(),
# shifting items at and beyond $newpos upwards.
#
# Basically $test keeps track of how much items at and beyond newpos have
# been moved up due to that shifting. If an item is in its correct position
# due to that shifting then there's no need for a move() call.
#
# This move call suppression is geared towards Gtk2::Menu::reorder_child()
# because as of Gtk 2.12 that function doesn't notice when a reorder request
# is asking for an unchanged position, it does some linear time linked-list
# searches anyway, and looping that over 0 to N ends up as O(N^2) time. A
# loop over 0 to N is not optimal, but it's simple, and in particular the
# supression test
sub make_reorder_test {
my $offset = 0;
return sub {
my ($newpos, $oldpos) = @_;
my $cmp = ($oldpos+$offset <=> $newpos);
$offset += $cmp;
return $cmp;
}
}
# When visible, shuffle around according to reorder array.
# For a big lot of moves maybe a re-setup would be better, though for a
# small shuffle in the list a $menu->reorder_child should be best.
#
my ($tearoff, @children) = _tearoff_and_children ($self);
if (@children < @$aref) {
carp __PACKAGE__.': oops, reorder array bigger than num children ('
. scalar(@$aref) . ',' . scalar(@children) . ')';
_recover_after_inconsistency ($self);
return;
}
my $test = make_reorder_test();
foreach my $newpos (0 .. $#$aref) {
my $oldpos = $aref->[$newpos];
if ($test->($newpos,$oldpos)) {
my $item = $children[$oldpos];
if ($item) {
$self->reorder_child ($item, $newpos + $tearoff);
} else {
carp __PACKAGE__.": oops, reorder array bad oldpos $oldpos";
_recover_after_inconsistency ($self);
return;
}
}
}
( run in 0.920 second using v1.01-cache-2.11-cpan-7fcb06a456a )