111 lines
2.4 KiB
Perl
111 lines
2.4 KiB
Perl
package TUI;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use diagnostics;
|
|
|
|
use Curses::UI;
|
|
|
|
# Singleton
|
|
my $_cui;
|
|
|
|
sub init_cui {
|
|
if ( !defined $_cui ) {
|
|
$_cui = new Curses::UI(
|
|
-color_support => 1,
|
|
-mouse_support => 1,
|
|
|
|
# -clear_on_exit => 1,
|
|
);
|
|
}
|
|
|
|
return $_cui;
|
|
}
|
|
|
|
sub select_from_list {
|
|
my ( $title, $multiselect, @items ) = @_;
|
|
die "No items to choose from" unless @items;
|
|
|
|
my @values = $multiselect ? ( '__ALL__', @items ) : @items;
|
|
my %labels =
|
|
$multiselect
|
|
? ( '__ALL__' => '[ALL]', map { $_ => $_ } @items, )
|
|
: map { $_ => $_ } @items;
|
|
|
|
my @selection;
|
|
my @selection_order; # multiselect only: items in toggle order
|
|
|
|
my $cui = init_cui();
|
|
my $win = $cui->add( 'root', 'Window', );
|
|
|
|
my $listbox;
|
|
$listbox = $win->add(
|
|
'item_list',
|
|
'Listbox',
|
|
-title => $title,
|
|
-border => 1,
|
|
-values => \@values,
|
|
-labels => \%labels,
|
|
-multi => $multiselect == 1,
|
|
-radio => $multiselect == 0,
|
|
-padbottom => 1,
|
|
-onchange => sub {
|
|
return unless $multiselect;
|
|
my %now = map { $_ => 1 } $listbox->get();
|
|
|
|
# Append newly selected items in toggle order
|
|
for my $item (@items) {
|
|
if ( $now{$item} && !grep { $_ eq $item } @selection_order ) {
|
|
push @selection_order, $item;
|
|
}
|
|
}
|
|
|
|
# Drop deselected items
|
|
@selection_order = grep { $now{$_} } @selection_order;
|
|
},
|
|
);
|
|
|
|
$win->add(
|
|
'info', 'Label',
|
|
-y => -1,
|
|
-text => "Space/Enter = toggle, C = confirm, Q = quit",
|
|
);
|
|
|
|
$listbox->clear_binding('loose-focus');
|
|
|
|
$listbox->set_binding(
|
|
sub {
|
|
my @picked = $listbox->get();
|
|
if ( $multiselect && grep { $_ eq '__ALL__' } @picked ) {
|
|
@selection = @items;
|
|
}
|
|
elsif ($multiselect) {
|
|
@selection = @selection_order;
|
|
}
|
|
else {
|
|
@selection = @picked;
|
|
}
|
|
$cui->mainloopExit();
|
|
},
|
|
'c',
|
|
);
|
|
|
|
$listbox->set_binding(
|
|
sub {
|
|
@selection = ();
|
|
$cui->mainloopExit();
|
|
},
|
|
'q',
|
|
);
|
|
|
|
$listbox->focus();
|
|
$cui->mainloop();
|
|
|
|
$cui->leave_curses();
|
|
$cui->delete('root');
|
|
|
|
return @selection;
|
|
}
|
|
|
|
1;
|