Gtk2-Ex-ComboBox
view release on metacpan or search on metacpan
lib/Gtk2/Ex/ComboBox.pm view on Meta::CPAN
package Gtk2::Ex::ComboBox;
our $VERSION = '0.07';
use strict;
use warnings;
use Glib qw(TRUE FALSE);
use Gtk2::Ex::Simple::List;
use Gtk2::Ex::PopupWindow;
use Carp;
use Data::Dumper;
sub new {
my ($class, $parent, $type) = @_;
my $self = {};
bless ($self, $class);
my $slist = Gtk2::Ex::Simple::List->new (
'flag' => 'bool',
'' => 'text',
);
$self->{slist} = $slist;
$self->{type} = $type;
my $popup = Gtk2::Ex::PopupWindow->new($parent);
$self->{popup} = $popup;
$self->{signals} = undef;
my $frame = Gtk2::Frame->new;
$type = 'with-buttons' unless $type;
unless ($type eq 'with-buttons' or $type eq 'with-checkbox' or $type eq 'no-checkbox') {
carp "Error: Expecting 'with-buttons' or 'with-checkbox'. Got $type\n";
$type = 'with-buttons'; #default
}
if ($type eq 'with-buttons') {
my $vbox = $self->_make_selectable;
$frame->add($vbox);
} elsif ($type eq 'with-checkbox') {
my $vbox = $self->_make_checkable;
$frame->add($vbox);
} elsif ($type eq 'no-checkbox') {
my $scrolledwindow = Gtk2::ScrolledWindow->new;
$scrolledwindow->set_policy('automatic', 'automatic');
$scrolledwindow->add($slist);
$frame->add($scrolledwindow);
$slist->get_selection->signal_connect ('changed' =>
sub {
my @sel = $slist->get_selected_indices;
foreach my $line (@{$slist->{data}}) {
$line->[0] = FALSE;
}
foreach my $x (@sel) {
$slist->{data}->[$x]->[0] = TRUE;
}
}
);
}
$popup->{window}->add($frame);
$popup->{window}->set_default_size(200, 200);
return $self;
}
sub signal_connect {
my ($self, $signal, $callback) = @_;
$self->{signals}->{$signal} = $callback;
my $slist = $self->{slist};
my $type = $self->{type};
if ( $type eq 'with-buttons' or $type eq 'with-checkbox') {
$slist->get_model()->signal_connect ('row-changed' =>
sub {
&{ $self->{signals}->{'changed'} };
}
);
} elsif ( $type eq 'no-checkbox' ) {
$slist->get_selection->signal_connect ('changed' =>
sub {
&{ $self->{signals}->{'changed'} };
}
);
}
}
sub get_treeview {
my ($self) = @_;
return $self->{slist};
}
sub get_selected_values{
my ($self) = @_;
my $slist = $self->{slist};
my @selectedvalues;
my @unselectedvalues;
foreach my $x (@{$slist->{data}}) {
push @selectedvalues, $x->[1] if $x->[0];
push @unselectedvalues, $x->[1] if !$x->[0];
}
return { 'selected-values' => \@selectedvalues, 'unselected-values' => \@unselectedvalues };
}
sub get_selected_indices{
my ($self) = @_;
my $slist = $self->{slist};
my @selectedindices;
my @unselectedindices;
my $i = 0;
foreach my $x (@{$slist->{data}}) {
push @selectedindices, $i if $x->[0];
push @unselectedindices, $i if !$x->[0];
$i++;
}
return { 'selected-indices' => \@selectedindices, 'unselected-indices' => \@unselectedindices };
}
sub set_list_preselected {
my ($self, $list) = @_;
my $slist = $self->{slist};
@{$slist->{data}} = @$list;
if ($self->{type} eq 'no-checkbox') {
$slist->set_headers_visible(FALSE);
$slist->get_column(0)->set_visible(FALSE);
$slist->get_selection->set_mode ('multiple');
my $i = 0;
foreach my $x (@$list) {
$slist->select($i) if $x->[0];
$i++;
}
}
return 0;
}
sub set_list {
my ($self, $list) = @_;
my @temp;
foreach my $x (@$list) {
push @temp, [0, $x];
}
$self->set_list_preselected(\@temp);
return 0;
}
sub show {
my ($self) = @_;
$self->{popup}->show;
}
sub hide {
my ($self) = @_;
$self->{popup}->hide;
}
sub _make_selectable {
my ($self) = @_;
my $slist = $self->{slist};
$slist->set_headers_visible(FALSE);
my $label = Gtk2::Label->new('Select');
my $allbutton = Gtk2::Button->new_from_stock('Select All');
my $nonebutton = Gtk2::Button->new_from_stock('Select None');
my $okbutton = Gtk2::Button->new_from_stock('gtk-ok');
$allbutton->signal_connect ('button-release-event' =>
sub {
foreach my $line (@{$slist->{data}}) {
$line->[0] = TRUE;
}
}
);
$nonebutton->signal_connect ('button-release-event' =>
sub {
foreach my $line (@{$slist->{data}}) {
$line->[0] = FALSE;
}
}
);
$okbutton->signal_connect ('button-release-event' =>
sub {
$self->{popup}->hide;
}
);
my $scrolledwindow = Gtk2::ScrolledWindow->new;
$scrolledwindow->set_policy('automatic', 'automatic');
$scrolledwindow->add($slist);
my $hbox = Gtk2::HBox->new (TRUE, 0);
$hbox->pack_start ($allbutton, FALSE, TRUE, 0);
$hbox->pack_start ($nonebutton, FALSE, TRUE, 0);
my $vbox = Gtk2::VBox->new (FALSE, 0);
$vbox->pack_start ($hbox, FALSE, TRUE, 0);
$vbox->pack_start ($scrolledwindow, TRUE, TRUE, 0);
$vbox->pack_start ($okbutton, FALSE, TRUE, 0);
return $vbox;
}
sub _make_checkable {
my ($self) = @_;
my $slist = $self->{slist};
# Add a checkbutton to select all
$slist->set_headers_clickable(TRUE);
my $col = $slist->get_column(0);
my $check = Gtk2::CheckButton->new;
$col->set_widget($check);
$check->set_active(TRUE);
$check->show; # very important, show_all doesn't get this widget!
my $button = $col->get_widget; # not a button
do {
$button = $button->get_parent;
} until ($button->isa ('Gtk2::Button'));
$button->signal_connect (button_release_event =>
sub {
if ($check->get_active()) {
$check->set_active(FALSE);
} else {
$check->set_active(TRUE);
}
}
);
$check->signal_connect (toggled =>
sub {
my $flag = 0;
$flag = 1 if $check->get_active();
foreach my $line (@{$slist->{data}}) {
$line->[0] = $flag;
}
}
);
my $scrolledwindow = Gtk2::ScrolledWindow->new;
$scrolledwindow->set_policy('automatic', 'automatic');
$scrolledwindow->add($slist);
return $scrolledwindow;
}
1;
__END__
( run in 1.966 second using v1.01-cache-2.11-cpan-364913b4093 )