Archive for March, 2006

Context menus for Gtk.TreeView headers

Friday, March 24th, 2006

[The following mini-HOWTO is posted in the hopes of saving someone else the trouble of figuring out all this magic later]

This past week at work, I came upon the interesting problem of adding a right click menu to the *header* of a Gtk.TreeView. The issue being that TreeViewColumn is not infact a Gtk.Widget, but merely a Gtk.Object, exposes no Child or Children property like a Gtk.Bin or Gtk.Container, and is generally relatively API limited.

The following code snippet was adopted from some random bug on the GNOME bugzilla that I’m now failing to locate and link to. The full example in Boo can be found here. I have a version in C# as well, but it’s not nicely formatted, and lacks the inline comments that the above Boo version has.

The basic gist of the trick is to set TreeViewColumn.Widget to a new Gtk.Label instance:

col.Widget = Label (”Right Click Me!”)
col.Widget.Show ()

and then iterating over the Parent Gtk.Widgets of the label until you find one that is an instance of a Gtk.Button:

parent_widget = col.Widget.Parent
parent_button = parent_widget as Button
while (parent_widget != null and parent_button == null):
    parent_widget = parent_widget.Parent
    parent_button = parent_widget as Button

This Button will actually be the one used for the header, and you can connect to the ButtonPressEvent here, and in that handler do any menu pop up, etc. that you desire:

if parent_button is not null:
    parent_button.ButtonPressEvent += OnHeaderButtonPress

In your handler, you can then pop up a menu if it’s the correct button, etc:

[GLib.ConnectBefore]
def OnHeaderButtonPress (o as object, e as ButtonPressEventArgs):
    if e.Event.Button == 3:
        menu.Popup ()
        e.RetVal = false

Couple of gotchyas:

  • You *must* add the TreeViewColumn to the TreeView before doing any of the custom widget parent stuff. The column doesn’t do most of the setup unless this has happened first.
  • Make sure you use [GLib.ConnectBefore] on your method attaching to the ButtonPressEvent, so it gets called before TreeViewColumn’s handler does, otherwise you’ll never even see the event. Similarly, if you handle the event, you’ll want to set args.RetVal = false to stop propogation of the event.
  • There’ s no guarantee this won’t break if the gtk+ folks change the internals of GtkTreeViewColumn.
  • Your TreeView must have HeadersVisible and HeadersClickable true.

Checkout the full Boo code for all the magic, with inline comments.

UPDATE: As Joe pointed out in the comments, you can actually optimize the ‘find the parent button’ process by using Gtk.Widget.GetAncestor (GLib.GType). There’s a new version of the full boo file found here. Thanks Joe!

still spinnin’, muine work, step brother home, and movin’

Thursday, March 23rd, 2006

For those of you reading who doubted me, I’m still spinnin’ things. Add it to your RSS feeds, cause who knows what will end up in motion next.

In Muine news, CVS has supported gstreamer 0.10 for a few weeks now, and lots of small fixes, etc have been commited since the last release. Hoping to a new release soon to push out the new gstreamer support, etc. I’ve not had much time for the bigger features I posted about recently, but I have gotten my gnome-vfs work progressing well, and even working for a few select cases. Groups stuff I’ve had no time for, but will hopefully come back to soon.

My step brother, Matt, finally returned home from his second tour in Iraq this sunday. I drove down to San Diego to be with my step mother, grand step mother, and niece to greet him when he got off the plane. A giant relief to have him home safe and sound.
In other news, I’m moving out of my current luxurious and lonely 3 bedroom apartment into a new place in Irvine, which should be a pleasant change, if annoying to execute. Photos and whatnot of the place hopefully will follow soon.

SoCal, loneliness, and ex-GFs

Saturday, March 4th, 2006

All things that can drive one to drink. Much like me right now.