Drag and Drop help

Hello Folks,

I notice that the ‘Drag and Drop Overview’ link in the documentation is
broken. My goal is to drag an image over another, larger image and have
it snap in place in a particular area of the larger image when dropped,
which also generates an event for further processing.

I’m having a bit of trouble getting started with that, especially since
there doesn’t seem to be an available overview.

I’ve seen the samples, but they aren’t quite what I’m after.

Any pointers are appreciated.

Thanks!

DZ

Hi

Daniel Zepeda wrote:

I notice that the ‘Drag and Drop Overview’ link in the documentation is
broken. My goal is to drag an image over another, larger image and have
it snap in place in a particular area of the larger image when dropped,
which also generates an event for further processing.

I think the approach here is to define your own subclass of
Wx::DropTarget which holds a BitmapDataObject. In this subclass you
supply your own on_drop or on_data methods, which receive the (x,y)
co-ordinates where the drop took place. You would then do appropriate
calculations to “snap” the image into wherever it should go. See the
events.rb sample for an illustration of how to generate your own custom
event types and send them for processing (using process_event).

For the source side, you’ll probably want Wx::DropSource, this should be
more straightforward. If you want a live animation of the image being
dragged, there is a pre-built class for this, Wx::DragImage. A simple
example of its use is demonstrated in bigdemo.rb.

I’m having a bit of trouble getting started with that, especially since
there doesn’t seem to be an available overview.

See also the wxWidgets drag and drop overview:
http://docs.wxwidgets.org/stable/wx_wxdndoverview.html

a

Ok, so first off, thank you for the help Alex, that got me started.

Here is what I’ve come up with so far:

http://gist.github.com/105742

It is nowhere near finished, and some things like the return values of
on_data, etc. are just there to get it going.

I sort of expected the image to be part of the “cursor” when you do the
drag-and-drop operation, like what you get when dragging from the OSX
Finder, a representation of the file, while dragging. But, all I’m
getting is an empty square with a pointer. Is that all you get by
default, or am I doing something wrong?

I thought maybe the image was too big, so I scaled, resized it down to
smaller than the square, but still just got the empty square.

I originally thought I was going to use a Wx::DragImage, but it turns
out that DropSource#do_drag_drop blocks mouse events, so trying to
incorporate the DragImage sample doesn’t work because evt_motion doesn’t
get triggered while do_drag_drop is active.

Now I’m thinking of using DropSource#give_feedback in conjunction with
DragImage, but give_feedback doesn’t give you mouse coordinates, so to
do that, I need to find some way of grabbing the mouse coordinates
within give_feedback so I can tell the image where to move.

At this point, what I’m thinking seems way too complicated and that is
usually a signal to me that I’m doing something wrong, so I want a
sanity check from the experts.

Again, any pointers is the right direction would be appreciated.

BTW, if you actually want to run the sample, you’ll need wxruby-logo.png
found in the samples/drawing directory under the wxRuby distribution. I
didn’t think it was a good idea to try to post that in the Gist.

Daniel Zepeda wrote:

Ok, so first off, thank you for the help Alex, that got me started.

Here is what I’ve come up with so far:

http://gist.github.com/105742

I like the way this works so far.

It is nowhere near finished, and some things like the return values of
on_data, etc. are just there to get it going.

I sort of expected the image to be part of the “cursor” when you do the
drag-and-drop operation, like what you get when dragging from the OSX
Finder, a representation of the file, while dragging. But, all I’m
getting is an empty square with a pointer. Is that all you get by
default, or am I doing something wrong?

No, I think that’s all you get. You can use DropSource#set_cursor to set
a cursor associated with a particular drag action. You can create a
Cursor from an arbitrary Image, but you’re limited to 32x32 pixels.

I thought maybe the image was too big, so I scaled, resized it down to
smaller than the square, but still just got the empty square.

I originally thought I was going to use a Wx::DragImage, but it turns
out that DropSource#do_drag_drop blocks mouse events, so trying to
incorporate the DragImage sample doesn’t work because evt_motion doesn’t
get triggered while do_drag_drop is active.

http://www.tebyan.net/index.aspx?pid=31159&BookID=22131&PageIndex=94&Language=3

and see next comment

Now I’m thinking of using DropSource#give_feedback in conjunction with
DragImage, but give_feedback doesn’t give you mouse coordinates, so to
do that, I need to find some way of grabbing the mouse coordinates
within give_feedback so I can tell the image where to move.

There are the global module functions Wx::get_mouse_position and
Wx::get_mouse_state

At this point, what I’m thinking seems way too complicated and that is
usually a signal to me that I’m doing something wrong, so I want a
sanity check from the experts.

I’m no expert on this, but I would have expected this not to be too
hard. However, other people using WX seem to be wondering the same
thing. See the following threads:

http://groups.google.com/group/comp.soft-sys.wxwindows/browse_thread/thread/fcc67efa1e6ea29f
http://lists.wxwidgets.org/pipermail/wx-dev/2003-February/030914.html

hth
alex

Hello,

I’ve worked on the original sample and updated the gist:

http://gist.github.com/105742

With some exceptions, this works on OS X, but running it in Windows
produces disappointing results.

I’ll point out where I’m having problems. Would you let me know if I’m
doing something wrong, or if these are bugs in wxRuby?

I’m just going to go through the file line by line and comment.

Lines 6-26:
This isn’t so important, but is at the top of the file, so gets
commented on first. I’ve worked up a basic DragResultHandler, it would
be nice if some form of this were included in wxRuby.

Line 49:
I don’t get a sunken border on Windows. It looks nice on OS X, but
Windows just has a flat featureless plane for the drop targets.

Lines 89,95:
I don’t have to call refresh on OS X for the backgrounds to light up,
but Windows doesn’t do anything unless I call refresh. Is this expected?

Line 131:
This doesn’t work on Windows or OS X. I get a “Wrong Argument” error. It
looks like the documentation says you should be able to do this, but
I’ve tried several permutations, and none of them works.

Lines 155-158:
On Windows, the give_feedback method is only called consistently when
the pointer is over the drop targets during a drag operation. It is
called intermittently when over the drop sources, and not at all
anywhere else. This works perfectly on OS X.

Line 179:
This is like trying to create a new image on line 131. The documentation
seems to say I should be able to do this, but it gives me an argument
error as well. Resorting to setting the alpha pixel-by-pixel as I do on
181-185 works, but it is ugly.

Lines 189-195:
I expected to just set the hotspot to half the width of the image, and
the full height of the image to get the image floating above the cursor.
This just doesn’t work. I have to use these non-sensical values to get
the effect I want on OS X. On Windows, the result is inconsistent,
sometimes I more-or-less get the effect I want, and other times the
image is way off to the side and down from where it should be, and other
times it is way off to the side and up from where it should be.

Line 202:
Works perfectly on OS X. On Windows, after I drag/drop one image, and I
then attempt to drag another image, if I move the pointer around “too
much” the program segfaults at this line. I can drag the image around
all I want on the first drag operation, but the second one always
segfaults when I move the pointer around “too much”.

Line 209:
As with the other mention of refresh above, I only have to call this on
Windows. Seems like I shouldn’t have to call it at all.

Lastly, a problem on OS X is that after a drag/drop operation, and
clearing the dialog, I have to click once anywhere in the window before
I can initiate another drag/drop. I thought it might be a focus problem,
so I tried different methods of resetting the focus, but it doesn’t seem
to make a difference. If I don’t use the MessageDialog, that is, I just
replace the dialog with a ‘puts’ in the event handler, I don’t have that
problem. This is only a problem on OS X.

Again, I’m unsure if I’m doing something wrong, or if these are bugs in
wxRuby, any pointers would be much appreciated.

Just a quick note on the Gist, you may notice I’ve included the image in
it now so you don’t have to go grab it from somewhere else.

Also, if this helps, on OS X, I’m using wxRuby 2.0.0, ruby 1.8.7
(2008-08-11 patchlevel 72) [i686-darwin9], built from ports, and on
Windows I’m using the same version of wxRuby and ruby 1.8.7 (2008-08-11
patchlevel 72) [i386-mswin32], which I downloaded from the Ruby website.
Since I’m going to use my template for packaging/distribution, using a
different ruby version wouldn’t be that much of a problem. Oh, and I’m
running Windows under Parallels 4 on OS X for these tests, if that makes
a difference.

Thanks!
DZ

Just wanted to make sure this was the final word. I guess the workaround
is to only use drag images in OSX. Kind of disappointing, but oh well,
everything seems harder in Windows, and it’s not the fault of Wx. I
wonder what GTK is like.

I’ll reply to what I can here…

On Sat, May 23, 2009 at 10:46 AM, Daniel Zepeda
[email protected]wrote:

doing something wrong, or if these are bugs in wxRuby?

I’m just going to go through the file line by line and comment.

Lines 6-26:
This isn’t so important, but is at the top of the file, so gets
commented on first. I’ve worked up a basic DragResultHandler, it would
be nice if some form of this were included in wxRuby.

I’ll see if we can get this in before our next push to release.

Line 49:
I don’t get a sunken border on Windows. It looks nice on OS X, but
Windows just has a flat featureless plane for the drop targets.

That’s a bug, you should get a Sunken frame when using that style on a
panel, or window, or anything of that sorts.

Lines 89,95:
I don’t have to call refresh on OS X for the backgrounds to light up,
but Windows doesn’t do anything unless I call refresh. Is this expected?

This is typical of Windows, it’s best to call refresh, or put in a
platform
detect in there. Windows requires a repaint, if you change any color
face
for any control, even if it’s panel, window, or frame. What’s going on,
is
that Windows isn’t preemptive in it’s refreshing of the windows
contents,
and doesn’t have a event hooks for when custom drawing is done. The
only
times Windows updates a panel, is when another window is moved over it.

Line 131:
This doesn’t work on Windows or OS X. I get a “Wrong Argument” error. It
looks like the documentation says you should be able to do this, but
I’ve tried several permutations, and none of them works.

That I couldn’t say if it works or not, I’ve never used it. You may try
Bitmap to, unless the format of the data is compressed / encoded in a
different format, such as PNG, JPG, GIF, etc, etc.

Lines 155-158:
On Windows, the give_feedback method is only called consistently when
the pointer is over the drop targets during a drag operation. It is
called intermittently when over the drop sources, and not at all
anywhere else. This works perfectly on OS X.

Limitation of Windows. (Alex is free to correct me on this one).

Line 179:
This is like trying to create a new image on line 131. The documentation
seems to say I should be able to do this, but it gives me an argument
error as well. Resorting to setting the alpha pixel-by-pixel as I do on
181-185 works, but it is ugly.

Couldn’t say on this one.

Line 202:
Works perfectly on OS X. On Windows, after I drag/drop one image, and I
then attempt to drag another image, if I move the pointer around “too
much” the program segfaults at this line. I can drag the image around
all I want on the first drag operation, but the second one always
segfaults when I move the pointer around “too much”.

These two wait for Alex to answer.

Line 209:
As with the other mention of refresh above, I only have to call this on
Windows. Seems like I shouldn’t have to call it at all.

Answered above.

Lastly, a problem on OS X is that after a drag/drop operation, and
clearing the dialog, I have to click once anywhere in the window before
I can initiate another drag/drop. I thought it might be a focus problem,
so I tried different methods of resetting the focus, but it doesn’t seem
to make a difference. If I don’t use the MessageDialog, that is, I just
replace the dialog with a ‘puts’ in the event handler, I don’t have that

problem. This is only a problem on OS X.

Another Alex question. Don’t have OS X.

Since I’m going to use my template for packaging/distribution, using a
different ruby version wouldn’t be that much of a problem. Oh, and I’m
running Windows under Parallels 4 on OS X for these tests, if that makes
a difference.

Yes, it makes a major Difference. It’s Microsoft’s way of saying, You
want
to run Windows on a Macintosh, you better well install it full blown,
not in
an emulator! :wink: J/k, no that shouldn’t make a difference. As long as
the
Virtual Machine program isn’t faulty, it should run without any
sqaubles.

http://rubyforge.org/mailman/listinfo/wxruby-users

hth,

Mario

Daniel

Daniel Zepeda wrote:

Just wanted to make sure this was the final word. I guess the workaround
is to only use drag images in OSX. Kind of disappointing, but oh well,
everything seems harder in Windows, and it’s not the fault of Wx. I
wonder what GTK is like.

I haven’t had a chance to look at the sample you posted yet - have been
moving house again etc. Can’t promise to have any useful comments but
will have a look when have some time to work through it.

a

Alex F. wrote:

Daniel

I haven’t had a chance to look at the sample you posted yet - have been
moving house again etc. Can’t promise to have any useful comments but
will have a look when have some time to work through it.

a

Hey that’s great Alex, thanks for giving me a heads up on your
situation. I know what you are going through, so best of luck, hope
things work out on the home front for you. I’m a patient man, whatever
time you can give me when you can give it to me is appreciated.

DZ