From: Clifford Heath Date: 2006-10-17T14:10:13+09:00 Subject: Gtk: Writing a CellRenderer in Ruby (Repost from the ruby-gnome2 developers list, where there seems to be no-one home) Folk, I've subclassed the CellRendererPixbuf to make a renderer that has a "state" property that displays an appropriate icon for each state, and I want to add mouse button event handlers to it. Problem is, there doesn't seem to be any way to get the TreeView object which is the necessary Widget. In the C API, the _GtkTreeView object (in gtktreeview.h), there's a "parent" member, but no supported way of accessing it. What am I missing? Is there some standard Gtk method or property for getting the parent of a Gtk::Object? If not, why not? The code, such as it is, is below. The images for are simply loaded from . Clifford Heath. module Gtk class CellRendererIconSet < CellRendererPixbuf type_register install_property(GLib::Param::String.new( "state", "state", "The state of an IconSet", "", GLib::Param::READABLE|GLib::Param::WRITABLE)) def initialize(*args) super() @state = nil @states = {} if (args.size > 0) states = args[0] if (states.is_a? Hash) @states = states elsif (states.is_a? Array) states.each{|s| @states[s] = nil } end # More handling needed here... end # and here... end attr_reader :state def state=(s) throw "CellRendererIconSet: no such state #{s.inspect} in #{@states}" if !@states.include?(s) @state = s self.pixbuf=(icon) end def icon(s = nil) s ||= @state puts "loading icon for #{s}" if (!@states[s]) # Needs a directory path from which to load here: @states[s] ||= Gdk::Pixbuf.new(s.to_s.downcase+".png") end end end I want to move something like the following code into the class: treeview.add_events(Gdk::Event::BUTTON_PRESS_MASK) treeview.signal_connect("button_press_event") { |w, e| path, column, cell_x, cell_y = treeview.get_path_at_pos(e.x, e.y) puts "button #{e.button} at (#{e.x}, #{e.y}) row #{path}, column #{column}, at (#{cell_x}, #{cell_y})" next if column != self on_click(path, e.button, e.state) } ... so I can then write (or similar with signals): def on_click(path, button, state) next if e.button != 3 # Get current state and calculate next state: storeRow = store[path] state = storeRow[Column::IconState] newstate = States[(States.index(state)+1) % States.size] storeRow[Column::IconState] = newstate true end