UPDATE MAR 6,2006.... please see simpler example in
Re^3: popup menu in Gtk2::SimpleList below
I'm sure it can be done, but I don't have an example handy at the moment. But, if you look at the perldoc for Gtk2::SimpleList, there is a method
Gtk2::SimpleList->add_column_type ($type_name, ...)
$type_name (string)
Which lets you add any custom type column, and you want to add a CellRendererCombo. Now it just so happens, that a Gtk2-perl developer , Daniel Kasak just posted a sample script to the Gtk2-perl maillist, where he questioned whether such a combo cell acted buggy in a plain ListStore. You could either drop the requirement for SimpleList and go with ListStore, or pull the drop down combo model code from the script below, and add it as a column type to your SimpleList. I'll see if I can get it working later today, if not, muppet on the maillist would know. (but I hate to overwork the poor guy, :-) )
So here is the ListStore example, from which you could extract the combo model for the drop down.
#!/usr/bin/perl
use warnings;
use strict;
use Gtk2 -init;
use Glib qw/TRUE FALSE/;
# Danial Kasak posted this as having
# some sort of bug, but it works fine for me.
# if you select a number in the 3rd column combobox,
# then hit dump, before hitting enter in the cell,
# or click somewhere in the treeview, the number
# change won't take effect. Seems like a feature to me :-)
my $window = Gtk2::Window->new( "toplevel" );
$window->signal_connect( "destroy", sub { Gtk2->main_quit(); } );
my $vbox = Gtk2::VBox->new( 0, 5 );
my $model = Gtk2::ListStore->new( "Glib::String", "Glib::String", "Gli
+b::Int" );
$model->set( $model->append, 0, "Hi", 1, "There", 2, 5 );
my $renderer_1 = Gtk2::CellRendererText->new;
$renderer_1->set( editable => TRUE );
$renderer_1->signal_connect( edited => sub { &process_editing( @_, 0 )
+; } );
my $renderer_2 = Gtk2::CellRendererText->new;
$renderer_2->set( editable => TRUE );
$renderer_2->signal_connect( edited => sub { &process_editing( @_, 1 )
+; } );
my $column_1 = Gtk2::TreeViewColumn->new_with_attributes(
"Some Text",
$renderer_1,
'text' => 0
);
my $column_2 = Gtk2::TreeViewColumn->new_with_attributes(
"More Text",
$renderer_2,
'text' => 1
);
my $combo_model = Gtk2::ListStore->new( "Glib::Int", "Glib::String" );
foreach my $thingy ( [ 1, "one" ], [ 2, "two" ], [ 3, "three" ], [ 4,
+"four" ],
[ 5, "five" ] )
{
$combo_model->set( $combo_model->append, 0, $$thingy[ 0 ], 1,
$$thingy[ 1 ] );
}
my $renderer_3 = Gtk2::CellRendererCombo->new;
$renderer_3->set(
editable => TRUE,
text_column => 1,
has_entry => TRUE,
model => $combo_model
);
$renderer_3->signal_connect( edited => sub { &process_editing( @_, 2 )
+; } );
my $column_3 =
Gtk2::TreeViewColumn->new_with_attributes( "A Combo", $renderer_3, te
+xt => 2 );
$column_3->set_cell_data_func( $renderer_3, sub { &render_combo_cell(
+@_ ); } );
my $treeview = Gtk2::TreeView->new( $model );
$treeview->set_rules_hint( TRUE );
$treeview->append_column( $column_1 );
$treeview->append_column( $column_2 );
$treeview->append_column( $column_3 );
my $sw = Gtk2::ScrolledWindow->new( undef, undef );
$sw->set_shadow_type( "etched-in" );
$sw->set_policy( "never", "always" );
$sw->add( $treeview );
$vbox->pack_start( $sw, TRUE, TRUE, 0 );
my $button = Gtk2::Button->new( "Dump Values" );
$button->signal_connect( "clicked" => sub { &dump_values( @_ ); } );
$vbox->pack_start( $button, TRUE, TRUE, 0 );
$window->add( $vbox );
$window->show_all;
Gtk2->main;
sub process_editing {
my ( $renderer, $text_path, $new_text, $columnno ) = @_;
my $path = Gtk2::TreePath->new_from_string( $text_path );
my $iter = $model->get_iter( $path );
if ( $columnno == 2 )
{ # Column 2 is a combo - we need to fetch the ID from the combo
+'s model
my $combo_model;
$combo_model = $renderer->get( "model" );
my $combo_iter = $combo_model->get_iter_first;
my $found_match = FALSE;
while ( $combo_iter ) {
if ( $combo_model->get( $combo_iter, 1 ) eq $new_text ) {
$found_match = TRUE;
$new_text =
$combo_model->get( $combo_iter, 0 )
; # It's possible that this is a bad idea
last;
}
$combo_iter = $combo_model->iter_next( $combo_iter );
}
# If we haven't found a match, default to a zero
if ( !$found_match ) {
$new_text = 0;
}
}
$model->set( $iter, $columnno, $new_text );
}
sub dump_values {
my $iter = $model->get_iter_first;
print "Column 0 contains: " . $model->get( $iter, 0 ) . "\n";
print "Column 1 contains: " . $model->get( $iter, 1 ) . "\n";
print "Column 2 contains: " . $model->get( $iter, 2 ) . "\n";
print "\n";
}
sub render_combo_cell {
my ( $tree_column, $renderer, $model, $iter ) = @_;
# Get the ID that represents the text value to display
my $key_value = $model->get( $iter, 2 );
# Loop through our combo's model and find a match for the above ID to
+get our text value
my $combo_iter = $combo_model->get_iter_first;
my $found_match = FALSE;
while ( $combo_iter ) {
if ( $combo_model->get( $combo_iter, 0 )
&& $key_value
&& $combo_model->get( $combo_iter, 0 ) == $key_value )
{
$found_match = TRUE;
$renderer->set( text => $combo_model->get( $combo_iter, 1 ) )
+;
last;
}
$combo_iter = $combo_model->iter_next( $combo_iter );
}
# If we haven't found a match, default to displaying an empty value
if ( !$found_match ) {
$renderer->set( text => "" );
}
}
I'm not really a human, but I play one on earth.
flash japh
|