Mouse wheel events in a grid cell editor?

I’m trying to do some advanced editing using Grids. I’ve created my own
editors and updating view and model both works fine so far. Thanks to
whoever made this possible. I like wxRuby more each day!

Now I’d like to catch mousewheel events in order to increment/decrement
a grid cell editor.

I’ve tried installing a handler in begin_edit of my editor and removing
it again in end_edit.

I’ve attempted to

(a) install an event handler on the grid and forward it to an
editor-specific method

(b) install an event handler on the editor control

Neither approach worked. Any suggestions?

Thanks in advance,
Tony


class MyEditor < Wx::GridCellChoiceEditor
def initialize
super
end

def begin_edit row, col, grid
get_control().evt_mousewheel {|e| on_wheel e }
grid.evt_mousewheel {|e| on_wheel e }
end

def on_wheel event
p event
end

def end_edit row, col, grid
# TODO: unsubscribe evt handler
super
end
end

On 24/02/2010 19:39, Tony M. wrote:

I’m trying to do some advanced editing using Grids. I’ve created my own
editors and updating view and model both works fine so far. Thanks to
whoever made this possible. I like wxRuby more each day!

Thanks - Wx::Grid is a really nice class - complex, but powerful.

(b) install an event handler on the editor control

I would have expected (a) to work - mouse events are fired on whichever
is the topmost control where the mouse is. For an editor control, the
mouse pointer may not be on top of the control itself.

Does the evt_mousewheel fire correctly if you have it as a constant
event handler for the Grid?

You could try using the method Window#capture_mouse to force mouse input
to be directed to a particular window - either the grid or the editor
control - to see if this helps.

Failing that, please post a complete, runnable but minimal example with
the problem and I’ll see if I can help

alex

thanks for the reply. The problem appears to be that, once the editor is
instantiated, the grid will receive the wheel events everywhere except
where the editor is visible.

I would have expected (a) to work - mouse events are fired on whichever
is the topmost control where the mouse is. For an editor control, the
mouse pointer may not be on top of the control itself.

it would appear that is the case - which may be why the grid receives
the wheel events but not the editor.

Does the evt_mousewheel fire correctly if you have it as a constant
event handler for the Grid?

yes

You could try using the method Window#capture_mouse to force mouse input
to be directed to a particular window - either the grid or the editor
control - to see if this helps.

I will have to try that - digging into it now.

Failing that, please post a complete, runnable but minimal example with
the problem and I’ll see if I can help

attached. I will let you know as soon as I found out anything regarding
the capture_mouse method.

tony


(I’m getting an “application error” from the webserver when I try to
attach a file so I’m adding it here and reporting the bug to the
webmaster)

#!/usr/bin/env arch -i386 ruby
begin
require ‘rubygems’
rescue LoadError
end
require ‘wx’

class MyGridTable < Wx::GridTableBase
attr_reader :cols, :rows
def initialize(rows, cols)
super()
@rows = rows
@cols = cols
end

def get_number_rows
@rows
end

def get_number_cols
@cols
end

def get_value(row, col)
(col + @cols * row).to_s
end

def get_attr(row, col, attr_kind)
Wx::GridCellAttr.new
end

def is_empty_cell(row, col)
false
end

def set_value(x, y, val)
puts “Attempting to change cell (#{x}, #{y}) to ‘#{val}’”
end

def get_type_name(row, col)
“FOOBAR”
end
end

class MyEditor < Wx::GridCellChoiceEditor
def initialize
super([‘7’,‘13’,‘23’,‘42’])
end

def begin_edit row, col, grid
puts “begin edit”
grid.evt_mousewheel {|e| on_wheel e }
super
end

def on_wheel event
p event
end

def end_edit(row, col, grid)
puts “end edit”
# TODO: how to unsubscribe?
super
end
end

class GridFrame < Wx::Frame
def initialize()
super(nil, :title => ‘Mousewheel example’, :size => [600, 300])
main_sizer = Wx::VBoxSizer.new

@grid = Wx::Grid.new(self)

@grid.register_data_type( "FOOBAR",
                          Wx::GridCellStringRenderer.new,
                          MyEditor.new )

@grid.table = MyGridTable.new(10, 10)
main_sizer.add(@grid, 1, Wx::EXPAND|Wx::ALL, 5)
self.sizer = main_sizer

end
end

Wx::App.run do
GridFrame.new.show
end

You could try using the method Window#capture_mouse to force mouse input
to be directed to a particular window - either the grid or the editor
control - to see if this helps.

I’m a bit puzzled my how the capture_mouse method might work on the grid
cells.

Since the cell editors don’t subclass Wx::Window, the only chance would
be to capture the mouse on the control itself and subsequently connect
the control to the mouse event:

class MyEditor < Wx::GridCellNumberEditor

def initialize
super 0, 100
end

def begin_edit row, col, grid
control = get_control()
control.capture_mouse()
connect(control.wx_id, Wx::ID_ANY, Wx::EVT_MOUSEWHEEL) { |e| p e }
super
end

def end_edit row, col, grid
control = get_control
control.release_mouse
super
end

end

… however this doesn’t do anything for me (no output). Please help.

Thanks,
Tony