Guidance on simple drag and drop

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Guidance on simple drag and drop

jon bird
Hi,

I'm after a brief bit of guidance on implementing a simple drag and drop
within an application. I came across this article which had some useful
tips in it:

https://groups.google.com/forum/#!topic/wx-users/BmFEVrij7XA

in my case this is between a listbox and a text ctrl but I don't think
the actual control matter too much. Since it's purely within the
application, I think as Vadim suggests in this article, using
wxDropSource/DropTarget is probably overkill and suggests a couple of
other classes wxMouseEventsManager and wxDragImage which can assist with
this but the documentation isn't totally clear to me on how all this
hangs together.

Here's my initial stab:

class JSelectorMouseEventManager : public wxMouseEventsManager
{
public :
  JSelectorMouseEventManager(wxListBox *win) :
wxMouseEventsManager(win), m_JingleSelector(win)
  {}

private :

  int MouseHitTest(const wxPoint& pos)
  {
    return m_JingleSelector->HitTest(pos);
  }

  bool MouseClicked(int item)
  {
    return false;
  }

  // called to start dragging the given item, should generate the
appropriate
  // BEGIN_DRAG event and return false if dragging this item was
forbidden
  bool MouseDragBegin(int item, const wxPoint& pos)
  {
    DragImage = new wxDragImage(m_JingleSelector->GetString(item));
    DragImage->BeginDrag(pos, wxTheApp->GetTopWindow(), false);
    DragImage->Show();
    return true;
  }

  // called while the item is being dragged, should normally update the
  // feedback on screen (usually using wxOverlay)
  void MouseDragging(int item, const wxPoint& pos)
  {
    DragImage->Move(pos);
  }

  // called when the mouse is released after dragging the item
  void MouseDragEnd(int item, const wxPoint& pos)
  {
    DragImage->EndDrag();
    delete DragImage;
  }

  // called when mouse capture is lost while dragging the item, should
remove
  // the visual feedback drawn by MouseDragging()
  void MouseDragCancelled(int item)
  {
    DragImage->EndDrag();
    delete DragImage;
  }

private :
  wxListBox* m_JingleSelector=nullptr;
  wxDragImage *DragImage=nullptr;

};

The window handle I pass in is that of the listbox which is the drag
source. This seems to work in a basic sense in that MouseDragBegin is
invoked when I start the drag and MouseDragEnd is called when I release
the button. The major problem I have though is that with this in place,
the normal behaviour of the listbox is inhibited, that is I can't select
items with the mouse. I'm guessing it's something I need to do with
MouseClicked but I'm not sure what.

The 2nd, more thorny issue is that of how to use wxDragImage - I've had
a stab here and it seems to start off ok but throws an assertion when I
release the mouse button regarding the mouse not being captured.

Rgs,


Jon.

--
== jon bird - software engineer
== <reply to address _may_ be invalid, real mail below>
== <reduce rsi, stop using the shift key>
== posted as: news 'at' onastick 'dot' clara.co.uk

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wx-users
Reply | Threaded
Open this post in threaded view
|

Re: Guidance on simple drag and drop

Vadim Zeitlin-4
On Thu, 19 Jan 2017 20:46:48 +0000 jon bird wrote:

jb> I'm after a brief bit of guidance on implementing a simple drag and drop
jb> within an application. I came across this article which had some useful
jb> tips in it:
jb>
jb> https://groups.google.com/forum/#!topic/wx-users/BmFEVrij7XA
jb>
jb> in my case this is between a listbox and a text ctrl but I don't think
jb> the actual control matter too much. Since it's purely within the
jb> application, I think as Vadim suggests in this article, using
jb> wxDropSource/DropTarget is probably overkill and suggests a couple of
jb> other classes wxMouseEventsManager and wxDragImage which can assist with
jb> this but the documentation isn't totally clear to me on how all this
jb> hangs together.

 Actually, when using native controls, using the standard drag-and-drop
support might be a better idea because we're not supposed to interfere in
their mouse handling -- as you've discovered.

jb> The major problem I have though is that with this in place, the normal
jb> behaviour of the listbox is inhibited, that is I can't select items
jb> with the mouse. I'm guessing it's something I need to do with
jb> MouseClicked but I'm not sure what.

 I'm afraid the problem is at wxMouseEventsManager level, it should skip
the event in its OnLeftUp() if MouseClicked() returns false. It's even
documented (in the comment) to do it, but it doesn't, really. Please try
changing it there and see if it helps.

 But, again, even if it does, fighting with the native controls for mouse
input is always going to be tricky. wxMouseEventsManager is really meant
for implementing generic controls, not being used with the native ones.

jb> The 2nd, more thorny issue is that of how to use wxDragImage - I've had
jb> a stab here and it seems to start off ok but throws an assertion when I
jb> release the mouse button regarding the mouse not being captured.

 Sorry, I can't really help with this beyond referring you to the dragimage
sample which works fine, AFAIK.

 Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
               http://www.tt-solutions.com/

attachment0 (203 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Guidance on simple drag and drop

jon bird
In article <[hidden email]>, Vadim Zeitlin
<[hidden email]> writes
>On Thu, 19 Jan 2017 20:46:48 +0000 jon bird wrote:
>
>jb> I'm after a brief bit of guidance on implementing a simple drag and drop
>jb> within an application. I came across this article which had some useful
>jb> tips in it:
>jb>

[...]

>
> Actually, when using native controls, using the standard drag-and-drop
>support might be a better idea because we're not supposed to interfere in
>their mouse handling -- as you've discovered.
>
>jb> The major problem I have though is that with this in place, the normal
>jb> behaviour of the listbox is inhibited, that is I can't select items
>jb> with the mouse. I'm guessing it's something I need to do with
>jb> MouseClicked but I'm not sure what.
>
> I'm afraid the problem is at wxMouseEventsManager level, it should skip
>the event in its OnLeftUp() if MouseClicked() returns false. It's even
>documented (in the comment) to do it, but it doesn't, really. Please try
>changing it there and see if it helps.
>
> But, again, even if it does, fighting with the native controls for mouse
>input is always going to be tricky. wxMouseEventsManager is really meant
>for implementing generic controls, not being used with the native ones.
>

Understood and this was my first approach before discovering there
seemed to be a "simpler" way of accomplishing it between controls in the
same app. Again though I was still struggling to understand the correct
approach on starting the drag process, the documentation, whilst
indicating that some controls provide helper events in the form of
things like EVT_TREE_BEGIN_DRAG for the most part you need to synthesize
this yourself.

My initial attempts on overriding the LH mouse down event & kicking the
drag off had a similar effect to that I mentioned earlier in that they
prevent the control from operation in it's normal manner. My guess is
that I'm going to have to do something a bit cleverer here in terms of
only kicking the operation off once mouse movement is detected. Is this
the standard approach or am I missing something?

Rgs.


Jon.

--
== jon bird - software engineer
== <reply to address _may_ be invalid, real mail below>
== <reduce rsi, stop using the shift key>
== posted as: news 'at' onastick 'dot' clara.co.uk

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wx-users
Reply | Threaded
Open this post in threaded view
|

Re[2]: Guidance on simple drag and drop

Vadim Zeitlin-4
On Sat, 21 Jan 2017 10:50:50 +0000 jon bird wrote:

jb> Understood and this was my first approach before discovering there
jb> seemed to be a "simpler" way of accomplishing it between controls in the
jb> same app. Again though I was still struggling to understand the correct
jb> approach on starting the drag process, the documentation, whilst
jb> indicating that some controls provide helper events in the form of
jb> things like EVT_TREE_BEGIN_DRAG for the most part you need to synthesize
jb> this yourself.

 Just in case this is not described clearly enough in the documentation:
the built-in tree drag-and-drop support via EVT_TREE_BEGIN_DRAG and company
is limited to dragging the items inside the tree itself. You won't be able
to drag something from the tree to another control using this mechanism.

jb> My initial attempts on overriding the LH mouse down event & kicking the
jb> drag off had a similar effect to that I mentioned earlier in that they
jb> prevent the control from operation in it's normal manner. My guess is
jb> that I'm going to have to do something a bit cleverer here in terms of
jb> only kicking the operation off once mouse movement is detected. Is this
jb> the standard approach or am I missing something?

 To use EVT_TREE_BEGIN_DRAG you don't need to handle any mouse events at
all, but you do need to explicitly Allow() the event in your handler as
these events are disabled by default (we don't want to allow the user
rearrange items in arbitrary trees where the program might not be ready to
handle it). I think the sample shows how to do it.

 Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
               http://www.tt-solutions.com/

attachment0 (203 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Guidance on simple drag and drop

jon bird
In article <[hidden email]>, Vadim Zeitlin
<[hidden email]> writes

>On Sat, 21 Jan 2017 10:50:50 +0000 jon bird wrote:
>
>jb> Understood and this was my first approach before discovering there
>jb> seemed to be a "simpler" way of accomplishing it between controls in the
>jb> same app. Again though I was still struggling to understand the correct
>jb> approach on starting the drag process, the documentation, whilst
>jb> indicating that some controls provide helper events in the form of
>jb> things like EVT_TREE_BEGIN_DRAG for the most part you need to synthesize
>jb> this yourself.
>
> Just in case this is not described clearly enough in the documentation:
>the built-in tree drag-and-drop support via EVT_TREE_BEGIN_DRAG and company
>is limited to dragging the items inside the tree itself. You won't be able
>to drag something from the tree to another control using this mechanism.
>
> To use EVT_TREE_BEGIN_DRAG you don't need to handle any mouse events at
>all, but you do need to explicitly Allow() the event in your handler as
>these events are disabled by default (we don't want to allow the user
>rearrange items in arbitrary trees where the program might not be ready to
>handle it). I think the sample shows how to do it.
>

I think we may be at crossed purposes here, I mentioned
EVT_TREE_BEGIN_DRAG as an example of what appeared to be helper events
that some controls emitted in assisting with performing drag and drop as
part of a more general query as to the right approach for initiating the
"drag" part. However you have cleared up the fact that these are
intended for dragging inside items within a control & not what I'm after
(which is drag and drop between a listbox and a text control) so that is
useful to know.

So my original question still stands with regard to the best/correct way
of starting this whilst allowing the listbox to function normally ie
this:

>jb> My initial attempts on overriding the LH mouse down event & kicking the
>jb> drag off had a similar effect to that I mentioned earlier in that they
>jb> prevent the control from operation in it's normal manner. My guess is
>jb> that I'm going to have to do something a bit cleverer here in terms of
>jb> only kicking the operation off once mouse movement is detected. Is this
>jb> the standard approach or am I missing something?
>

Rgs,


Jon.

--
== jon bird - software engineer
== <reply to address _may_ be invalid, real mail below>
== <reduce rsi, stop using the shift key>
== posted as: news 'at' onastick 'dot' clara.co.uk

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wx-users
Reply | Threaded
Open this post in threaded view
|

Re[2]: Guidance on simple drag and drop

Vadim Zeitlin-4
On Mon, 23 Jan 2017 19:25:43 +0000 jon bird wrote:

jb> So my original question still stands with regard to the best/correct way
jb> of starting this whilst allowing the listbox to function normally ie
jb> this:
jb>
jb> >jb> My initial attempts on overriding the LH mouse down event & kicking the
jb> >jb> drag off had a similar effect to that I mentioned earlier in that they
jb> >jb> prevent the control from operation in it's normal manner. My guess is
jb> >jb> that I'm going to have to do something a bit cleverer here in terms of
jb> >jb> only kicking the operation off once mouse movement is detected. Is this
jb> >jb> the standard approach or am I missing something?

 I thought I had answered this in my Jan 20 reply, so I can't really add
anything to it: when using native controls it would be better to rely on
the standard drag-and-drop classes rather than trying to implement it
manually. In this particular case, I think your own implementation would
work if you fixed the wxMouseEventsManager bug, but, again, in general, a
better idea is to not do this at all.

 Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
               http://www.tt-solutions.com/

attachment0 (203 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Guidance on simple drag and drop

jon bird
In article <[hidden email]>, Vadim Zeitlin
<[hidden email]> writes

>On Mon, 23 Jan 2017 19:25:43 +0000 jon bird wrote:
>
>jb> So my original question still stands with regard to the best/correct way
>jb> of starting this whilst allowing the listbox to function normally ie
>jb> this:
>jb>
>jb> >jb> My initial attempts on overriding the LH mouse down event &
>jb> >jb>kicking the
>jb> >jb> drag off had a similar effect to that I mentioned earlier in that they
>jb> >jb> prevent the control from operation in it's normal manner. My guess is
>jb> >jb> that I'm going to have to do something a bit cleverer here in terms of
>jb> >jb> only kicking the operation off once mouse movement is
>jb> >jb>detected. Is this
>jb> >jb> the standard approach or am I missing something?
>
> I thought I had answered this in my Jan 20 reply, so I can't really add
>anything to it: when using native controls it would be better to rely on
>the standard drag-and-drop classes rather than trying to implement it
>manually. In this particular case, I think your own implementation would
>work if you fixed the wxMouseEventsManager bug, but, again, in general, a
>better idea is to not do this at all.
>
Ah, ok I think I'm not making myself clear or I've missed something
fundamental. So I've read up on using the standard drag and drop
classes, wxDropSource, wxDropTarget etc. and that seems reasonably
clear. However what isn't clear is how you actually *start* the drag
operation. The problem is the book is particularly vague on this
subject:

"Note that the following describes what happens after your application
has decided that a drag is starting—the logic to detect the mouse
motion that indicates the start of a drag is left entirely up to the
application. Some controls help you by generating an event when dragging
is starting, so you don’t have to code the logic yourself (which could
potentially interfere with the native mouse behavior for the control)."

It's the final sentence there that I think is the problem - wxListCtrl
as we've clarified doesn't generate an event when the drag starts so
based on this, I need to code the logic myself presumably. The question
is how/what is the best way of doing this to (as the book says) avoids
interfering with the native mouse behavior for the control. As I
mentioned, my attempts thus far have caused that exact problem, they
disrupt the normal behaviour of the control.


Rgs,


Jon.

--
== jon bird - software engineer
== <reply to address _may_ be invalid, real mail below>
== <reduce rsi, stop using the shift key>
== posted as: news 'at' onastick 'dot' clara.co.uk

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wx-users
Reply | Threaded
Open this post in threaded view
|

Re[2]: Guidance on simple drag and drop

Vadim Zeitlin-4
On Sat, 4 Feb 2017 12:19:53 +0000 jon bird wrote:

jb> Ah, ok I think I'm not making myself clear or I've missed something
jb> fundamental. So I've read up on using the standard drag and drop
jb> classes, wxDropSource, wxDropTarget etc. and that seems reasonably
jb> clear. However what isn't clear is how you actually start the drag
jb> operation.

 Oops, sorry, it's not you, it's me, I keep getting lost in this discussion
and somehow I was thinking about dropping data all this time even though
you had been clearly speaking about starting to drag.

jb> As I mentioned, my attempts thus far have caused that exact problem,
jb> they disrupt the normal behaviour of the control.

 I think that if you catch all the relevant mouse events (so at least
wxEVT_LEFT_DOWN, wxEVT_LEFT_UP and wxEVT_MOTION) and do _not_ skip them
when starting to drag/while dragging, things should work. The problem is
that you can't use wxMouseEventsManager in its current state with a native
control because it doesn't skip the event even when you don't handle it. As
I said, I'd try fixing this and rechecking if it works for you because
otherwise you'd have to redo everything it does, which is not completely
trivial.

 Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
               http://www.tt-solutions.com/

attachment0 (203 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Guidance on simple drag and drop

jon bird
In article <[hidden email]>, Vadim Zeitlin
<[hidden email]> writes

>On Sat, 4 Feb 2017 12:19:53 +0000 jon bird wrote:
>
>jb> Ah, ok I think I'm not making myself clear or I've missed something
>jb> fundamental. So I've read up on using the standard drag and drop
>jb> classes, wxDropSource, wxDropTarget etc. and that seems reasonably
>jb> clear. However what isn't clear is how you actually start the drag
>jb> operation.
>
> Oops, sorry, it's not you, it's me, I keep getting lost in this discussion
>and somehow I was thinking about dropping data all this time even though
>you had been clearly speaking about starting to drag.
>
>jb> As I mentioned, my attempts thus far have caused that exact problem,
>jb> they disrupt the normal behaviour of the control.
>
> I think that if you catch all the relevant mouse events (so at least
>wxEVT_LEFT_DOWN, wxEVT_LEFT_UP and wxEVT_MOTION) and do _not_ skip them
>when starting to drag/while dragging, things should work. The problem is
>that you can't use wxMouseEventsManager in its current state with a native
>control because it doesn't skip the event even when you don't handle it. As
>I said, I'd try fixing this and rechecking if it works for you because
>otherwise you'd have to redo everything it does, which is not completely
>trivial.
>
Ok, that gives me something to go on. This particular task is very much
a background activity so not something I'm pursuing actively right now.
I'm sure when I do, more questions will be forthcoming but thanks for
now.

Rgs,


Jon.

--
== jon bird - software engineer
== <reply to address _may_ be invalid, real mail below>
== <reduce rsi, stop using the shift key>
== posted as: news 'at' onastick 'dot' clara.co.uk

--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to [hidden email]
or visit http://groups.google.com/group/wx-users