Context sensitive menus with GtkTreeView

A project I now maintain called GJay uses the GTK+ toolkit and has a GtkTreeView that shows the directories and the songs in them.  I was wanting to add a context sensitive menu on that view so that you could do things to the item you have right-clicked on; generally file specific things like give me information about this song or queue it to play.  My only problem was, how to do it?  A few Google searches showed things that were almost, but not quite, what I was after.  The main problem being either the documentation was incomplete or it assumed I was after the selected field (the row I may of left-clicked on) and not the one I right-clicked on to get this event.

This GtkTreeView uses a store where NAME_COLUMN is defined at 0, meaning it is the first column. The program uses this column to store the filename of the song.

So first I needed to create an event to kick things off, we need to connect the “button-press-event” to our tree_view, which calls a function in this case view_on_button_pressed.

 g_signal_connect(tree_view, "button-press-event",
   G_CALLBACK(view_on_button_pressed), NULL);
gboolean view_on_button_pressed(GtkWidget *tree_view,
                                GdkEventButton *event,
                                gpointer user_data) {
  GtkTreeSelection *selection;
  GtkTreePath *tree_path;
  GtkTreeModel *tree_model;
  GtkTreeIter tree_iter;
  gchar *name;

  if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
    tree_model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view));
    if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tree_view),
          (int)event->x, (int)event->y,
          &tree_path, NULL, NULL, NULL)) {
      if (gtk_tree_model_get_iter(tree_model, &tree_iter, tree_path)) {
        gtk_tree_model_get(tree_model, &tree_iter, NAME_COLUMN, &name, -1);
        g_print("rc name is %sn", name);
      }
    }
  }

So a breakdown of what my callback is doing:

  • Line 1:The callback’s widget is the GtkTreeView widget we connected the signal with
  • Line 10:Checks the event was a button press and button #3 (right button)
  • Line 11: Find the GtkTreeModel from the given GtkTreeView
  • Lines 12-14: Get the GtkTreePath that the right-click was sitting at by using the event coordinates.
  • Line 15: Convert the GtkTreePath into a GtkTreeIter
  • Line 16: Find the actual value we put into this row.

The program, now that it knows the song title, can then go off and generate a menu for that song.

Enhanced by Zemanta