Tag: GtkTreeView

  • 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