summaryrefslogtreecommitdiffstats
path: root/perl-install/interactive_gtk.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perl-install/interactive_gtk.pm')
-rw-r--r--perl-install/interactive_gtk.pm328
1 files changed, 9 insertions, 319 deletions
diff --git a/perl-install/interactive_gtk.pm b/perl-install/interactive_gtk.pm
index d4de36eb6..935766470 100644
--- a/perl-install/interactive_gtk.pm
+++ b/perl-install/interactive_gtk.pm
@@ -7,341 +7,31 @@ use vars qw(@ISA);
@ISA = qw(interactive);
use interactive;
-use common qw(:common :functional);
+use common qw(:common);
use my_gtk qw(:helpers :wrappers);
1;
-sub new {
- $::windowheight ||= 400 if $::isStandalone;
- goto &interactive::new;
-}
-sub suspend { my ($o) = @_; $o->{suspended} = common::setVirtual(1) }
-sub resume { my ($o) = @_; common::setVirtual(delete $o->{suspended}) }
-
-sub exit {
- c::_exit($_[0]) #- workaround
-}
-
sub ask_from_listW {
my ($o, $title, $messages, $l, $def) = @_;
- ask_from_list_with_helpW($o, $title, $messages, $l, undef, $def);
-}
-
-sub ask_from_list_with_helpW {
- my ($o, $title, $messages, $l, $help, $def) = @_;
- my $r;
- my $w = my_gtk->new(first(deref($title)), %$o);
- $w->{retval} = $def || $l->[0]; #- nearly especially for the X test case (see timeout in Xconfigurator.pm)
- if (@$l < 5) {
- my $defW;
- my $tips = new Gtk::Tooltips;
+ if (@$l < 5 && sum(map { length $_ } @$l) < 70) {
+ my $w = my_gtk->new($title);
my $f = sub { $w->{retval} = $_[1]; Gtk->main_quit };
gtkadd($w->{window},
- gtkpack(create_box_with_title($w, @$messages),
- gtkadd(@$l < 3 && sum(map { length $_ } @$l) < 60 ? create_hbox() : create_vbox(),
+ gtkpack(create_box_with_title($o, @$messages),
+ gtkadd(create_hbox(),
map {
my $b = new Gtk::Button($_);
- $tips->set_tip($b, $help->{$_}) if $help && $help->{$_};
$b->signal_connect(clicked => [ $f, $_ ]);
- $_ eq $def and $defW = $b;
+ $_ eq $def and $def = $b;
$b;
} @$l),
),
);
- $defW->grab_focus if $defW;
- $w->{rwindow}->set_position('center') if $::isStandalone;
- $r = $w->main;
- } else {
- #- use ask_from_list_with_help only when needed, as key bindings are
- #- dropped by List (CList does not seems to accepts Tooltips).
- $help ? $w->_ask_from_list_with_help($title, $messages, $l, $help, $def) :
- $w->_ask_from_list($title, $messages, $l, $def);
- $r = $w->main;
- }
- $r or die "ask_from_list cancel";
-}
-
-sub ask_from_treelistW {
- my ($o, $title, $messages, $separator, $l, $def) = @_;
- my $sep = quotemeta $separator;
- my $w = my_gtk->new($title);
- my $tree = Gtk::CTree->new(1, 0);
-
- my %wtree;
- my $parent; $parent = sub {
- if (my $w = $wtree{"$_[0]$separator"}) { return $w }
- my $s;
- foreach (split $sep, $_[0]) {
- $wtree{"$s$_$separator"} ||=
- $tree->insert_node($s ? $parent->($s) : undef, undef, [$_], 5, (undef) x 4, 0, 0);
- $s .= "$_$separator";
- }
- $wtree{$s};
- };
- my ($root, $leaf, $wdef, $ndef);
- foreach (@$l) {
- ($root, $leaf) = /(.*)$sep(.+)/ or ($root, $leaf) = ('', $_);
- my $node = $tree->insert_node($parent->($root), undef, [$leaf], 5, (undef) x 4, 1, 0);
-
- if ($def eq $_) {
- $wdef = $node;
- my $s; $tree->expand($wtree{$s .= "$_$separator"}) foreach split $sep, $root;
- foreach my $nb (1 .. @$l) {
- if ($tree->node_nth($nb) == $node) {
- $tree->set_focus_row($ndef = $nb);
- last;
- }
- }
- }
- }
- undef %wtree;
-
- my $curr;
- my $leave = sub {
- $curr->row->is_leaf or return;
- my @l; for (; $curr; $curr = $curr->row->parent) {
- unshift @l, first $tree->node_get_pixtext($curr, 0);
- }
- $w->{retval} = join $separator, @l;
- Gtk->main_quit;
- };
- $w->{ok_clicked} = $leave;
- $w->{cancel_clicked} = sub { $w->destroy; die "ask_from_list cancel" }; #- make sure windows doesn't live any more.
- gtkadd($w->{window},
- gtkpack($w->create_box_with_title(@$messages),
- gtkpack_(new Gtk::VBox(0,7),
- 1, gtkset_usize(createScrolledWindow($tree), 300, min(350, $::windowheight - 60)),
- 0, $w->create_okcancel)));
- $tree->set_column_auto_resize(0, 1);
- $tree->set_selection_mode('browse');
- $tree->signal_connect(tree_select_row => sub { $curr = $_[1]; });
- $tree->signal_connect(button_press_event => sub { &$leave if $_[1]{type} =~ /^2/ });
- $tree->signal_connect(key_press_event => sub {
- my ($w, $e) = @_;
- my $c = chr($e->{keyval} & 0xff);
- $curr or return;
- if ($e->{keyval} >= 0x100 ? $c eq "\r" || $c eq "\x8d" : $c eq ' ') {
- if ($curr->row->is_leaf) { &$leave }
- else { $tree->toggle_expansion($curr) }
- }
- 1;
- });
-
- $tree->grab_focus;
- $tree->set_row_height($tree->style->font->ascent + $tree->style->font->descent + 1);
- $w->{rwindow}->show;
-
- if ($wdef) {
- $tree->select($wdef);
- $tree->node_moveto($wdef, 0, 0.5, 0);
- }
-
-
- $w->main or die "ask_from_list cancel";
-}
-
-sub ask_many_from_list_with_help_refW {
- my ($o, $title, $messages, @L) = @_;
- my $w = my_gtk->new('', %$o);
- my $tips = new Gtk::Tooltips;
- my @boxes = map {
- my $l = $_;
- my $box = gtkpack(new Gtk::VBox(0,0),
- map_index {
- my $i = $::i;
- my $o = Gtk::CheckButton->new($_);
- $tips->set_tip($o, $l->[1][$i]) if $l->[1][$i];
- $o->set_active(${$l->[2][$i]});
- $o->signal_connect(clicked => sub { invbool $l->[2][$i] });
- $o;
- } @{$l->[0]});
- @{$l->[0]} > 11 ? gtkset_usize(createScrolledWindow($box), 0, 250) : $box;
- } @L;
- gtkadd($w->{window},
- gtkpack_(create_box_with_title($w, @$messages),
- (map {; 1, $_ } @boxes),
- 0, $w->create_okcancel,
- )
- );
- $w->{ok}->grab_focus;
- $w->main;
-}
-
-sub ask_from_entries_refW {
- my ($o, $title, $messages, $l, $val, %hcallback) = @_;
- my ($title_, @okcancel) = deref($title);
- my $ignore = 0; #-to handle recursivity
-
- my $w = my_gtk->new($title_, %$o);
- #-the widgets
- my @widgets = map {
- my $i = $_;
- if ($i->{type} eq "list") {
- my $w = new Gtk::Combo;
- $w->set_use_arrows_always(1);
- $w->entry->set_editable(!$i->{not_edit});
- $w->set_popdown_strings(@{$i->{list}});
- $w->disable_activate;
- $w;
- } elsif ($i->{type} eq "bool") {
- my $w = Gtk::CheckButton->new($i->{text});
- $w->set_active(${$i->{val}});
- $w->signal_connect(clicked => sub { $ignore or invbool \${$i->{val}} });
- $w;
- } elsif ($i->{type} eq "range") {
- my $adj = create_adjustment(${$i->{val}}, $i->{min}, $i->{max});
- $adj->signal_connect(value_changed => sub { ${$i->{val}} = $adj->get_value });
- my $w = new Gtk::HScale($adj);
- $w->set_digits(0);
- $w;
- } else {
- new Gtk::Entry;
- }
- } @{$val};
- my $ok = $w->create_okcancel(@okcancel);
-
- sub widget {
- my ($w, $ref) = @_;
- ($ref->{type} eq "list" && @{$ref->{list}}) ? $w->entry : $w
- }
- my @updates = mapn {
- my ($w, $ref) = @_;
- sub {
- $ref->{type} =~ /bool|range/ and return;
- ${$ref->{val}} = widget($w, $ref)->get_text;
- };
- } \@widgets, $val;
-
- my @updates_inv = mapn {
- my ($w, $ref) = @_;
- sub {
- $ref->{type} eq "bool" ?
- $w->set_active(${$ref->{val}}) :
- $ref->{type} eq "bool" ?
- $w->get_adjustment->set_value(${$ref->{val}}) :
- widget($w, $ref)->set_text(${$ref->{val}})
- };
- } \@widgets, $val;
-
-
- for (my $i = 0; $i < @$l; $i++) {
- my $ind = $i; #-cos lexical bindings pb !!
- my $widget = widget($widgets[$i], $val->[$i]);
- my $changed_callback = sub {
- return if $ignore; #-handle recursive deadlock
- &{$updates[$ind]};
- if ($hcallback{changed}) {
- &{$hcallback{changed}}($ind);
- #update all the value
- $ignore = 1;
- &$_ foreach @updates_inv;
- $ignore = 0;
- };
- };
- my $may_go_to_next = sub {
- my ($W, $e) = @_;
- if (($e->{keyval} & 0x7f) == 0xd) {
- $W->signal_emit_stop("key_press_event");
- if ($ind == $#$l) {
- @$l == 1 ? $w->{ok}->clicked : $w->{ok}->grab_focus;
- } else {
- widget($widgets[$ind+1],$val->[$ind+1])->grab_focus;
- }
- }
- };
-
- if ($hcallback{focus_out}) {
- my $focusout_callback = sub {
- return if $ignore;
- &{$hcallback{focus_out}}($ind);
- #update all the value
- $ignore = 1;
- &$_ foreach @updates_inv;
- $ignore = 0;
- };
- $widget->signal_connect(focus_out_event => $focusout_callback);
- }
- if (ref $widget eq "Gtk::HScale") {
- $widget->signal_connect(key_press_event => $may_go_to_next);
- }
- if (ref $widget eq "Gtk::Entry") {
- $widget->signal_connect(changed => $changed_callback);
- $widget->signal_connect(key_press_event => $may_go_to_next);
- $widget->set_text(${$val->[$i]{val}});
- $widget->set_visibility(0) if $val->[$i]{hidden};
- }
- &{$updates[$i]};
- }
-
- my @entry_list = mapn { [($_[0], $_[1])]} $l, \@widgets;
-
- gtkadd($w->{window},
- gtkpack(
- create_box_with_title($w, @$messages),
- create_packtable({}, @entry_list),
- $ok
- ));
- widget($widgets[0],$val->[0])->grab_focus();
- if ($hcallback{complete}) {
- my $callback = sub {
- my ($error, $focus) = &{$hcallback{complete}};
- #-update all the value
- $ignore = 1;
- foreach (@updates_inv) { &{$_};}
- $ignore = 0;
- if ($error) {
- $focus ||= 0;
- widget($widgets[$focus], $val->[$focus])->grab_focus();
- } else {
- return 1;
- }
- };
- #$w->{ok}->signal_connect(clicked => $callback)
- $w->main($callback);
+ $def->grab_focus if $def;
+ $w->main;
} else {
- $w->main();
- }
-}
-
-
-sub wait_messageW($$$) {
- my ($o, $title, $messages) = @_;
-
- my $w = my_gtk->new($title, %$o, grab => 1);
- gtkadd($w->{window}, my $hbox = new Gtk::HBox(0,0));
- $hbox->pack_start(my $box = new Gtk::VBox(0,0), 1, 1, 10);
- $box->pack_start($_, 1, 1, 4) foreach my @l = map { new Gtk::Label($_) } @$messages;
-
- ($w->{wait_messageW} = $l[$#l])->signal_connect(expose_event => sub { $w->{displayed} = 1 });
- $w->{rwindow}->set_position('center') if $::isStandalone;
- $w->{window}->show_all;
- $w->sync until $w->{displayed};
- $w;
-}
-sub wait_message_nextW {
- my ($o, $messages, $w) = @_;
- my $msg = join "\n", @$messages;
- return if $msg eq $w->{wait_messageW}->get; #- needed otherwise no expose_event :(
- $w->{displayed} = 0;
- $w->{wait_messageW}->set($msg);
- $w->flush until $w->{displayed};
-}
-sub wait_message_endW {
- my ($o, $w) = @_;
- $w->destroy;
-}
-
-sub kill {
- my ($o) = @_;
- $o->{before_killing} ||= 0;
-
- while (my $e = shift @tempory::objects) { $e->destroy }
- while (@interactive::objects > $o->{before_killing}) {
- my $w = pop @interactive::objects;
- $w->destroy;
+ my_gtk::ask_from_list($title, $messages, $l, $def);
}
- @my_gtk::grabbed = ();
- $o->{before_killing} = @interactive::objects;
}