Hi!
I''m having some trouble using a ListCtrl as a drag & drop source. I
select a row and then try to drag it, but nothing happens. The
evt_list_begin_drag doesn''t seem to trigger.
I''ve found no good examples of it anywhere, except an old sample that
seems to have been a part of wxruby 0.6.0 that I found here:
http://www.koders.com/ruby/fid431E286522E3E0DEE10CFA48B571A48A0B1BE9EE.aspx?s=kevin+smith+dragdrop#L1
I know it''s old, but after (briefly) comparing it to the current
documentation I can''t see why the code shouldn''t work... Or at
least
trigger the evt_list_begin_drag. I hope I am mistaken, and that
someone can point out some easy fix... I need to drag rows in a
ListCtrl and either drop on the same ListCtrl or a TreeCtrl, but as
the evt_list_begin_drag doesn''t seem to trigger, I''m sort of
stuck.
Neither the drag & drop samples that ship with the wxruby gem nor any
mailing list discussion I''ve found seem to cover what I''m
after.
I''ve run the code basically unmodified (just changing the requires to
''rubygems'' and ''wx'' instead of
''wxruby'', and removing '':'' characters
on the case-when so it works in Ruby 1.9) on OS X 10.5.7 both with
ruby 1.8.6 (p287) and the wxruby 1.9.9 gem, and with ruby 1.9.1 (p129)
and the wxruby-ruby19 2.0.0 gem, and neither work. The latter is my
preferred target.
Any help getting this to work would be *greatly* appreciated! A code
sample that works (atleast on someone elses machine) with a ListCtrl
as a drag & drop source and target would be superb, so I could try the
same sample, and if it doesn''t work try to figure out why.
I''ve pasted
the sample I tried at the end of the mail, modified as noted above for
convenience if anyone has the time to try it out.
Best regards and thanks in advance,
Mathias
Code sample follows:
# dragdrop.rb sample by Kevin Smith
#require ''wxruby''
require ''rubygems''
require ''wx''
class DragListBox < Wx::ListCtrl
def initialize(parent)
super(parent, -1, Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE,
Wx::LC_REPORT | Wx::LC_SINGLE_SEL)
insert_column(0, ''Fruits'')
evt_list_begin_drag(get_id) do | e | on_drag(e) end
end
def append(text)
row = get_item_count
insert_item(row, text)
set_item_text(row, text)
end
def get_selected_row
return get_next_item(-1, Wx::LIST_NEXT_ALL, Wx::LIST_STATE_SELECTED)
end
def on_drag(event)
selected_row = get_selected_row
if(selected_row < 0)
puts("nothing to drag")
return
end
data = Wx::TextDataObject.new(get_item_text(selected_row))
dragSource = Wx::DropSource.new(self);
dragSource.set_data(data);
result = dragSource.do_drag_drop(Wx::DRAG_ALLOW_MOVE)
case result
when Wx::DRAG_NONE
puts("Drop was rejected")
when Wx::DRAG_CANCEL
puts("Drag canceled by user")
when Wx::DRAG_COPY
puts("Copied")
when Wx::DRAG_MOVE
puts("Moved")
delete_item(selected_row)
else
puts("ERROR or Unknown result!")
end
end
end
class MyDropTarget < Wx::TextDropTarget
def initialize(owner)
super()
@owner = owner
@owner.set_drop_target(self)
end
def on_drop_text(x, y, text)
puts("Accepting drop of #{text} at #{x}, #{y}")
@owner.handle_drop(text)
return true
end
end
class DropListBox < Wx::ListBox
def initialize(parent)
super(parent, -1)
target = MyDropTarget.new(self)
end
def handle_drop(text)
append(text)
end
end
class MyFrame < Wx::Frame
def initialize(title)
super(nil, -1, title)
list1 = DragListBox.new(self)
list1.append(''Apple'')
list1.append(''Banana'')
list1.append(''Cranberry'')
list2 = DropListBox.new(self)
lists = Wx::BoxSizer.new(Wx::HORIZONTAL)
lists.add(list1, 1, Wx::EXPAND)
lists.add(list2, 1, Wx::EXPAND)
instructions = Wx::StaticText.new(self, -1,
"You can drag items from the left list to the right\n" +
"(or to any window in your system that accepts text drops.\n"
+
"If you hold down shift while releasing, the item \n" +
"will be MOVED instead of COPIED\n")
main_sizer = Wx::BoxSizer.new(Wx::VERTICAL)
main_sizer.add(instructions, 0, Wx::EXPAND)
main_sizer.add(lists, 1, Wx::EXPAND)
set_sizer(main_sizer)
end
end
class DragDropApp < Wx::App
def on_init
frame = MyFrame.new("wxRuby Drag and Drop App")
frame.show
end
end
a = DragDropApp.new
a.main_loop()