Gtk2
view release on metacpan or search on metacpan
examples/cellrenderer_popup.pl view on Meta::CPAN
# menu to start xpad from the left of the cell (just like the
# button graphic), and we'll start by centering it vertically.
# got all that?
my ($wx, $wy) = $treeview->get_bin_window->get_origin;
my ($tx, $ty) = $treeview->tree_to_widget_coords($cell_area->x, $cell_area->y);
my $visible = $treeview->get_visible_rect;
$x = $wx + $visible->x + $tx + xpad;
$y = $wy + $visible->y + $ty + $cell_area->height / 2 - 2;
# center the menu vertically around the selected item.
# this is inspired heavily by GtkOptionMenu.
my $active = $menu->get_active;
$y -= $active->get_child_requisition->height / 2 if $active;
foreach my $i ($menu->get_children) {
last if $i == $active;
$y -= $i->get_child_requisition->height if $i->visible;
}
# play nicely with rtl languages
if ($treeview->get_direction eq 'rtl') {
$x = $wx + $tx + $cell_area->width -
$menu->get_child_requisition->width;
}
return ($x, $y, 1);
}
sub editing_done {
my ($item, $info) = @_;
my ($cell, $editable) = @$info;
$cell->signal_emit ('edited', $item->{path}, $item->{index});
# see the evil trick description below
$editable->remove_widget;
}
sub START_EDITING {
my ($cell, $event, $widget, $path, $background_area, $cell_area, $flags) = @_;
my $menu = Gtk2::Menu->new;
my @data = @{ $cell->{list} };
# this is an evil trick. we're creating a custom widget and handling
# the editing ourselves, but the higher level code only thinks we're
# editing if we return an editable. so we return an editable. of
# course, we have to remove it in the menu activate callbacks so that
# it doesn't stick around.
my $editable = Gtk2::Entry->new;
for (my $i = 0 ; $i < @data ; $i++) {
my $item = Gtk2::MenuItem->new ($data[$i]);
$item->show;
$menu->append ($item);
$item->{path} = $path;
$item->{index} = $i;
$item->{text} = $data[$i];
#$item->signal_connect (activate => \&editing_done, $cell);
$item->signal_connect (activate => \&editing_done, [$cell, $editable]);
}
$menu->set_active ($cell->{index});
$menu->popup (undef, undef,
\&menu_pos_func, [$widget, $cell_area],
$event ? $event->button : 0,
$event ? $event->time : 0);
$item = $menu->get_active;
$menu->select_item ($item) if $item;
# see the evil trick mentioned above.
$editable;
}
##########################################################################
# driver code
package main;
use Glib qw(FALSE TRUE);
$window = Gtk2::Window->new;
$window->set_title ('cell renderer test');
$window->signal_connect (delete_event => sub { Gtk2->main_quit; FALSE; });
$vbox = Gtk2::VBox->new;
$window->add ($vbox);
$label = Gtk2::Label->new;
$label->set_markup ('<big>F-Words</big>');
$vbox->pack_start ($label, FALSE, FALSE, 0);
# create and load the model
$model = Gtk2::ListStore->new ('Glib::String', 'Glib::Scalar', 'Glib::Int');
foreach ([ 'foo', [qw/foo bar baz/]],
[ 'fluffy', [qw/muffy tuffy buffy willow/]],
[ 'flurble', [qw/murble swurble curble/]],
[ 'frob', [qw/blob clob plob mob rob gob glob wob dob/]],
[ 'frobnitz', [qw/fronbination that's sweepin' the nation/]],
[ 'repeated', [qw/fronbination that's sweepin' the nation the the the the/]],
# [ 'none', []],
# [ 'verymany', [(1..50)]],
[ 'ftang', [qw/quisinart/]],
[ 'fire truck', [qw/red white green yellow polka-dot/]]) {
my $iter = $model->append;
$model->set ($iter, 0, $_->[0], 1, $_->[1], 2, rand (@{$_->[1]}));
}
# now a view
$treeview = Gtk2::TreeView->new ($model);
$treeview->set_rules_hint (TRUE);
$treeview->set_reorderable (TRUE);
#
# regular editable text column for column 0, the string
#
$renderer = Gtk2::CellRendererText->new;
$renderer->set (editable => TRUE);;
$column = Gtk2::TreeViewColumn->new_with_attributes ('something', $renderer,
text => 0);
# this commits changes from the user's editing to the model. compare and
# contrast with the one for the popup, below.
$renderer->signal_connect (edited => sub {
my ($cell, $text_path, $new_text, $model) = @_;
my $path = Gtk2::TreePath->new_from_string ($text_path);
my $iter = $model->get_iter ($path);
$model->set ($iter, 0, $new_text);
}, $model);
$treeview->append_column ($column);
#
# text for col[1]
#
$renderer = Gtk2::CellRendererText->new;
$column = Gtk2::TreeViewColumn->new_with_attributes ('list', $renderer,);
# custom data func to show the list items from the scalar.
$column->set_cell_data_func ($renderer, sub {
my ($tree_column, $cell, $model, $iter) = @_;
my ($info) = $model->get ($iter, 1);
$cell->set (text => "[".join(", ", @$info)."]");
});
$treeview->append_column ($column);
#
# text for col[2]
#
$renderer = Gtk2::CellRendererText->new;
$column = Gtk2::TreeViewColumn->new_with_attributes ('index', $renderer,
text => 2);
$treeview->append_column ($column);
#
# custom cell renderer for cols 1 and 2, an editable popup menu
#
$renderer = Mup::CellRendererPopup->new;
$renderer->set (mode => 'editable');
$column = Gtk2::TreeViewColumn->new_with_attributes ('selector', $renderer,
list => 1,
'index' => 2,
);
# this handler commits the user's selection to the model. compare with
# the one for the typical text renderer -- the only difference is a var name.
$renderer->signal_connect (edited => sub {
my ($cell, $text_path, $new_index, $model) = @_;
my $path = Gtk2::TreePath->new_from_string ($text_path);
my $iter = $model->get_iter ($path);
$model->set ($iter, 2, $new_index);
}, $model);
$treeview->append_column ($column);
my $scroll = Gtk2::ScrolledWindow->new;
$scroll->set_policy ('never', 'automatic');
$scroll->add ($treeview);
$vbox->pack_start ($scroll, TRUE, TRUE, 0);
# since we have a scroller, we need to set some reasonable initial size.
# i'll set one that should have the window scroll a bit, to make sure we
# can easily test the popup behavior when the treeview is scrolled.
$window->set_default_size (-1, 150);
my $check = Gtk2::CheckButton->new ('_show boxes');
$check->set_active ($renderer->get ('show-box'));
$check->signal_connect (toggled => sub {
$renderer->set (show_box => $check->get_active);
$treeview->queue_draw;
});
$vbox->pack_start ($check, FALSE, FALSE, 0);
$window->show_all;
Gtk2->main;
( run in 0.587 second using v1.01-cache-2.11-cpan-364913b4093 )