use warnings;
use strict;
use 5.10.0;
use List::Util qw( sum );
use Term::Choose qw( choose );
use Term::Choose::Util qw( term_size insert_sep );
use Term::ReadKey qw( GetTerminalSize );
my $number = _choose_a_number( 7, { current => 100000 } );
say $number;
print "ENTER to continue:"; <STDIN>;
$number = _choose_a_number( 7, { simple => 1, back => 'OK', current => 100000 } );
say $number;
sub _choose_a_number {
my ( $digits, $opt ) = @_;
my $thsd_sep = ',';
my $clear = 1;
my $mouse = 0;
my $name = defined $opt->{name} ? $opt->{name} : '';
my $back = defined $opt->{back} ? $opt->{back} : 'BACK';
my $back_short = '<<';
my $confirm = 'CONFIRM';
my $reset = 'reset';
my $simple = $opt->{simple};
my $tab = ' - ';
my $gcs_tab = Unicode::GCString->new( "$tab" );
my $len_tab = $gcs_tab->columns;
my $longest = $digits;
$longest += int( ( $digits - 1 ) / 3 );
my @choices_range = ();
for my $di ( 0 .. $digits - 1 ) {
my $begin = 1 . '0' x $di;
$begin = 0 if $di == 0;
$begin = insert_sep( $begin, $thsd_sep );
( my $end = $begin ) =~ s/^[01]/9/;
unshift @choices_range, sprintf " %*s%s%*s", $longest, $begin, $tab, $longest, $end;
}
my $confirm_tmp = sprintf "%-*s", $longest * 2 + $len_tab, $confirm;
my $back_tmp = sprintf "%-*s", $longest * 2 + $len_tab, $back;
my $term_width = ( term_size() )[0];
my $gcs_longest_range = Unicode::GCString->new( "$choices_range[0]" );
if ( $gcs_longest_range->columns > $term_width ) {
@choices_range = ();
for my $di ( 0 .. $digits - 1 ) {
my $begin = 1 . '0' x $di;
$begin = 0 if $di == 0;
$begin = insert_sep( $begin, $thsd_sep );
unshift @choices_range, sprintf "%*s", $longest, $begin;
}
$confirm_tmp = $confirm;
$back_tmp = $back;
}
my %numbers;
my $result;
my $undef = '--';
NUMBER: while ( 1 ) {
my $new_result = defined $result ? $result : $undef;
my $prompt = '';
if ( exists $opt->{current} ) {
$opt->{current} = defined $opt->{current} ? insert_sep( $opt->{current}, $thsd_sep ) : $undef;
$prompt .= sprintf "%s%*s\n", 'Current ' . $name . ': ', $longest, $opt->{current};
$prompt .= sprintf "%s%*s\n\n", ' New ' . $name . ': ', $longest, $new_result;
}
else {
$prompt = sprintf "%s%*s\n\n", $name . ': ', $longest, $new_result;
}
my @pre = ( undef, $simple ? () : $confirm_tmp );
my $range = choose(
[ @pre, @choices_range ],
{ prompt => $prompt, layout => 3, justify => 1, mouse => $mouse,
clear_screen => $clear, undef => $back_tmp }
);
if ( ! defined $range ) {
if ( $simple && defined $result ) {
$result =~ s/\Q$thsd_sep\E//g if $thsd_sep ne '';
return $result;
}
else {
return;
}
}
if ( $range eq $confirm_tmp ) {
return if ! defined $result;
$result =~ s/\Q$thsd_sep\E//g if $thsd_sep ne '';
return $result;
}
my $zeros = ( split /\s*-\s*/, $range )[0];
$zeros =~ s/^\s*\d//;
( my $zeros_no_sep = $zeros ) =~ s/\Q$thsd_sep\E//g if $thsd_sep ne '';
my $count_zeros = length $zeros_no_sep;
my @choices = $count_zeros ? map( $_ . $zeros, 1 .. 9 ) : ( 0 .. 9 );
my $number = choose(
[ undef, @choices, $reset ],
{ prompt => $prompt, layout => 1, justify => 2, order => 0,
mouse => $mouse, clear_screen => $clear, undef => $back_short }
);
next if ! defined $number;
if ( $number eq $reset ) {
delete $numbers{$count_zeros};
}
else {
$number =~ s/\Q$thsd_sep\E//g if $thsd_sep ne '';
$numbers{$count_zeros} = $number;
}
$result = sum( @numbers{keys %numbers} );
$result = insert_sep( $result, $thsd_sep );
}
}