Create  Edit  FrontPage  Index  Search  Changes  History  RSS  Back  Login

tut-treeview-selection-contextmenu Diff - Ruby-GNOME2 Project Website

  • Added parts are displayed like this.
  • Deleted parts are displayed like this.

= Context Menus
{{link "tut-treeview-selection-doubleclick", nil, "tut-treeview", "tut-treeview-resources"}}

Context menus are context-dependent menus that pop up when a user right-clicks on a list or tree and usually let the user do something with the selected items or manipulate the list or tree in other ways.

Right-clicks on a tree view are caught just like mouse button clicks are caught with any other widgets, namely by connecting to the tree view's "button_press_event" signal handler (which is a Gtk::Widget signal, and as Gtk::TreeView is derived from Gtk::Widget it has this signal as well). Additionally, you should also connect to the "popup-menu" signal, so users can access your context menu without a mouse. The "popup-menu" signal is emitted when the user presses Shift-F10. Also, you should make sure that all actions provided in your context menu can also be performed by other means such as the application's main menu. See the ((<GNOME Human Interface Guidelines (HIG)|URL: http://developer.gnome.org/projects/gup/hig/>)) for more details. Straight from the a-snippet-of-code-says-more-than-a-thousand-words-department, some code to look at:

  # Create a menu
  menu = Gtk::Menu.new

  # Add an item with a silly callback
  item = Gtk::MenuItem.new("Do Something")
  item.signal_connect("activate") { puts "Did something!" }
  menu.append(item)

  menu.show_all

  # Popup the menu on right click
  view.signal_connect("button_press_event") do |widget, event|
    if event.kind_of? Gdk::EventButton and event.button == 3
      menu.popup(nil, nil, event.button, event.time)
    end
  end

  # Popup the menu on Shift-F10
  view.signal_connect("popup_menu") { menu.popup(nil, nil, 0, Gdk::Event::CURRENT_TIME) }

Following is a program you have already seen in this tutorial, however, now the above ((*Context Menu*)) is included in it:

#!/usr/bin/env ruby
require 'gtk2'

# Add three columns to the GtkTreeView. All three of the
# columns will be displayed as text, although one is a boolean
# value and another is an integer.
def setup_tree_view(treeview)
   # Create a new GtkCellRendererText, add it to the tree
   # view column and append the column to the tree view.
   renderer = Gtk::CellRendererText.new
   renderer.foreground = "#ff0000"
   column   = Gtk::TreeViewColumn.new("Buy", renderer,  :text => $buy_it)BUY_IT)
   treeview.append_column(column)
   renderer = Gtk::CellRendererText.new
   column   = Gtk::TreeViewColumn.new("Count", renderer, :text => $quantity)QUANTITY)
   treeview.append_column(column)
   renderer = Gtk::CellRendererText.new
   column   = Gtk::TreeViewColumn.new("Product", renderer, :text => $product)PRODUCT)
   treeview.append_column(column)
end

window = Gtk::Window.new("Grocery List")
window.resizable = true
window.border_width = 10

window.signal_connect('destroy') { Gtk.main_quit }
window.set_size_request(250, 165)

class GroceryItem
   attr_accessor :buy, :quantity, :product
   def initialize(b, q, p); @buy, @quantity, @product = b, q, p; end
end
$buy_it BUY_IT = 0; $quantity QUANTITY = 1; $product PRODUCT = 2

list = Array.new
list[0] = GroceryItem.new(true,  1, "Paper Towels")
list[1] = GroceryItem.new(true,  2, "Bread")
list[2] = GroceryItem.new(false, 1, "Butter")
list[3] = GroceryItem.new(true,  1, "Milk")
list[4] = GroceryItem.new(false, 3, "Chips")
list[5] = GroceryItem.new(true,  4, "Soda")

treeview = Gtk::TreeView.new
setup_tree_view(treeview)

# Create a new tree model with three columns, as Boolean,
# integer and string.
store = Gtk::ListStore.new(TrueClass, Integer, String)

# Add all of the products to the GtkListStore.
list.each_with_index do |e, i|
     iter = store.append

     iter[$buy_it] iter[BUY_IT]   = list[i].buy       # same as: >>> # store.set_value(iter, $buy_it, BUY_IT,   list[i].buy)
     iter[$quantity] iter[QUANTITY] = list[i].quantity  # same as: >>> # store.set_value(iter, $quantity, QUANTITY, list[i].quantity)
     iter[$product] iter[PRODUCT] = list[i].product   # same as: >>> # store.set_value(iter, $product, PRODUCT, list[i].product)
end

# Add the tree model to the tree view
treeview.model = store

### Context Menu section ---------------------------------------------------- (start) -----
# Create a menu
menu = Gtk::Menu.new

# Add an item with a silly callback
item = Gtk::MenuItem.new("Do Something")
item.signal_connect("activate") { puts "Did something!" }
menu.append(item)

menu.show_all

# Popup the menu on right click
treeview.signal_connect("button_press_event") do |widget, event|
   if event.kind_of? Gdk::EventButton and event.button == 3
     menu.popup(nil, nil, event.button, event.time)
   end
end

# Popup the menu on Shift-F10
treeview.signal_connect("popup_menu") { menu.popup(nil, nil, 0, Gdk::Event::CURRENT_TIME) }
### Context Menu section ------------------------------------------------------ (end) -----

scrolled_win = Gtk::ScrolledWindow.new
scrolled_win.add(treeview)
scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)

window.add(scrolled_win)
window.show_all
Gtk.main