1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
#!/usr/bin/env perl 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 } ); # 1 say $number; print "ENTER to continue:"; <STDIN>; $number = _choose_a_number( 7, { simple => 1, back => 'OK', current => 100000 } ); # 2 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 ); # Choose 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 ); # Choose 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 ); } }