/usr/local/CPAN/RT-Client-Console/RT/Client/Console/Session/Progress.pm
package RT::Client::Console::Session::Progress;
use strict;
use warnings;
use parent qw(RT::Client::Console::Session);
use POE;
my @progress_texts = ();
# class method
# progress session creation
sub create {
my ($class) = @_;
$class->SUPER::create(
'progress_draw',
inline_states => {
init => sub {
my ($kernel, $heap) = @_[ KERNEL, HEAP ];
},
draw => sub {
my ( $kernel, $heap) = @_[ KERNEL, HEAP ];
my $draw_x = 0;
my @toremove = ();
my $curses_handler = $class->get_curses_handler();
my $label = Curses::Widgets::Label->new({
BORDER => 0,
X => 0,
Y => $heap->{screen_h} - 1,
COLUMNS => $heap->{screen_w},
LINES => 1,
VALUE => '',
FOREGROUND => 'black',
BACKGROUND => 'black',
});
$label->draw($curses_handler);
foreach my $pos (0..@progress_texts-1) {
my ($text, $erase) = @{$progress_texts[$pos]};
length $text or next;
if ($erase) {
push @toremove, $pos;
} else {
$label = Curses::Widgets::Label->new({
BORDER => 0,
LINES => 1,
COLUMNS => length($text),
Y => $heap->{screen_h} - 1,
X => $draw_x,
VALUE => $text,
FOREGROUND => 'white',
BACKGROUND => 'red',
});
$label->draw($curses_handler);
$draw_x += length($text) + 1;
}
}
foreach(@toremove) {
splice(@progress_texts, $_, 1);
}
},
},
);
}
# add an asynchronous progress session
sub add_progress {
my ($class, %args) = @_;
my $progress_text = ['', 0];
push @progress_texts, $progress_text;
my $progress_session = POE::Session->create(
inline_states => {
_start => sub {
my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
$heap->{value} = 0;
$args{initially}->();
$kernel->yield('draw');
$kernel->yield('code');
},
code => sub {
my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
if ($args{code}->()) {
$heap->{value}++;
$kernel->yield('draw');
$kernel->yield('code');
} else {
$args{finally}->();
$kernel->yield('draw', 1);
}
},
draw => sub {
my ( $kernel, $heap, $erase ) = @_[ KERNEL, HEAP, ARG0 ];
my $value = $args{caption}->() . ':' . int($heap->{value}*100/($args{steps_nb}->()||1)) . '%';
$erase and $value = ' ' x length $value;
$progress_text->[0] = $value;
$progress_text->[1] = $erase;
$kernel->post('key_handler', 'draw_all');
},
},
);
}
# add an asynchronous progress session
sub add_and_execute {
my ($class, $text, $code) = @_;
my $progress_text = [$text, 0];
push @progress_texts, $progress_text;
$poe_kernel->call('progress_draw', 'draw');
my @ret;
eval { @ret = wantarray ? $code->() : scalar($code->()) };
my $save_error = $@;
$progress_text->[0] = ' ' x length $text;
$progress_text->[1] = 1;
$poe_kernel->call('progress_draw', 'draw');
$save_error and die $save_error;
return @ret;
}
1;