Re: Popup menus for GtkTreeView




On Feb 24, 2006, at 11:41 PM, Federico Mena Quintero wrote:

I want a context-sensitive menu in a GtkTreeView.

[normal connect to button-press-event doesn't allow the selection to update]

[connect-after to button-press-event doesn't run because the default handler returns TRUE]

[normal connect to button-press-event, change selection, and then pop up menu doesn't handle modifiers correctly]

[normal connect to button-press-event, forcibly propagate the event to the treeview, and then pop up the menu works but is quite nasty.]


When i have had to do this i wind up using either a connection to event-after and filtering for button-press-event, or just connecting to button-release-event. In either case, this lets the normal button- press-event handling run unmolested, since it seems to be a little cranky. Popping up the menu on button-release-event is a bit dirty, as users don't tend to expect that.

It really depends on whether you want the user to be able to pop up the context menu on unselected items. I'm assuming you don't want this.

Here's some working code as a proof of concept:

-=-=-=-
#!/usr/bin/perl -w

use strict;
use Gtk2 -init;
use Glib qw(:constants);

my $model = Gtk2::ListStore->new ('Glib::String');
$model->set ($model->append, 0, $_)
	foreach ('Trogdor was a man',
		 'Or maybe he was a dragon-man',
		 'Or maybe he was just a dragon',
		 'But either way he was still TROGDOR!',
		 'TROGDOR!',
		 'Burninating the countryside',
		 'Burninating the villages',
		 'Burninating the peasants',
		 'And their thatch-roofed cottages',
		 'THATCH-ROOFED COTTAGES!');

my $treeview = Gtk2::TreeView->new ($model);
#
# Pop up a context menu in event-after, to allow the treeview's selection
# to change normally in button-press-event before we do our work.
#
$treeview->signal_connect (event_after => sub {
	my ($widget, $event) = @_;
	if ($event->type eq 'button-press' and
	    $event->button == 3) {
		my ($model, $iter) = $treeview->get_selection->get_selected;
		my $string = $model->get ($iter, 0);
		my $menu = Gtk2::Menu->new;
		my $item = Gtk2::MenuItem->new ($string);
		$menu->append ($item);
 		$item->show;
		$menu->popup (undef, undef, undef, undef,
			      $event->button, $event->time);
	}
	return FALSE;
});

# the rest is boring boilerplate.
$treeview->insert_column_with_attributes
			(-1, 'foo', Gtk2::CellRendererText->new, text => 0);
my $scrolled = Gtk2::ScrolledWindow->new;
$scrolled->add ($treeview);
my $window = Gtk2::Window->new;
$window->add ($scrolled);
$window->show_all;
$window->signal_connect (destroy => sub { Gtk2->main_quit });
Gtk2->main;
__END__
-=-=-=-=-=-=-


Then I press Shift-F10 and since I'm a good citizen and implemented
the ::popup_menu signal, I get a menu. But the motherfucker is far away
from the selected row!  Now GTK+ is really abusing me in ways to which
we didn't consent.

Can't help you there... my code above is also broken in that respect.


We need a signal in GtkTreeView like this:

[tree_popup_menu description]

Thoughts?

That sounds useful, as it is a lot of tedious work to get this stuff right normally, and as you described, it is rather bizarre in the first place.

Would it not be easier just to have TreeView not return TRUE in the default handler for button-press-event? I thought that default handlers were pretty much never supposed to return TRUE...


--
To type! perchance to fart! ay, there's the stench;
For in that type of death what nostrils may come
When we have laid off this green coil,
Must give us eye....
  -- http://www.madlibs.org/





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]