Simpler drag example / restricting drag to area?

I'm fairly new to wxWindows, and therefore aren't sure if this is a
Python-specific question or not. It sounds like, from the documentation,
the there are a few changes in the Python API for dragging, so I'm
starting the question here. If this isn't right, let me know, and I'll
take this to the wx-users list.

I'm creating a program where there will be several simple graphics that
can be moved around within a box. They aren't being dropped on each
other or anything like that; it's just a scratch area where someone can
rearrange them to get a sense of how they'd look in different
arrangements.

The drop program in the demo area handles highlighting the object being
dropped onto (eg a the King lights up if you drop the Queen on her), and
may also include functionality specific to the non-square-shaped star
and the text. Therefore, it's probably more complicated than I need.

I think I've figured out how to take out the light-when-dropped on code,
and can easily take out the text and masked star. My question is: is
this the way to go to build my simple re-arrange app? Or is a lot of the
code in this example to support the flexibility needed for these
features, and there's a really simple way to handle just moving things
around? Does anyone have an example of a simpler drag-image program?

Second:

I don't want users to be able to drag objects off the side of the
screen. Ideally, I'd really like to limit them to a particular area. It
*looks* like I could do this by adding a wxRect as the final parameter
for BeginDrag, ie:

  self.dragImage.BeginDrag(hotspot, self, 0)

becoming:

  self.dragImage.BeginDrag(hotspot, self, 0, wxRect(10,10,500,500))

would restrict to a rectangle at (10,10,510,510).

However, this doesn't seem to have any discernable effect. Is this
broken? Or am I misunderstanding the API for BeginDrag?

I have figured that I can put code in the OnLeftUp method to set the
dragShape pos to the min/max x/y values I want, so that at the end of
the dragging period, the object is left at the edge of the screen,
rather than off, but this is only semi-satisfactory: I'd prefer that the
user is preventing from dragging them out of an area at all, rather than
just having them snap back at the end.

Any ideas or answers would be appreciated!

Thanks,

- j.

Joel Burton wrote:

If this isn't right, let me know, and I'll
take this to the wx-users list.

If you're writing Python code, then this is the right list... even if
the answer would be the same for C++.

I'm creating a program where there will be several simple graphics that
can be moved around within a box. They aren't being dropped on each
other or anything like that; it's just a scratch area where someone can
rearrange them to get a sense of how they'd look in different
arrangements.

The drop program in the demo area handles highlighting the object being
dropped onto (eg a the King lights up if you drop the Queen on her), and
may also include functionality specific to the non-square-shaped star
and the text. Therefore, it's probably more complicated than I need.

I think I've figured out how to take out the light-when-dropped on code,
and can easily take out the text and masked star. My question is: is
this the way to go to build my simple re-arrange app?

It's not THE way, but it's a good way.

Does anyone have an example of a simpler drag-image program?

Probably not. The demo examle is pretty simnple, really.

I don't want users to be able to drag objects off the side of the
screen. Ideally, I'd really like to limit them to a particular area. It
*looks* like I could do this by adding a wxRect as the final parameter
for BeginDrag, ie:

  self.dragImage.BeginDrag(hotspot, self, 0)

becoming:

  self.dragImage.BeginDrag(hotspot, self, 0, wxRect(10,10,500,500))

would restrict to a rectangle at (10,10,510,510).

However, this doesn't seem to have any discernable effect. Is this
broken? Or am I misunderstanding the API for BeginDrag?

Take a look at the code for BeginDrag. As a newbie, it might take
alittle while to figure it out, but you'll learn in the process. Off
hand, I have no idea what it is supposed to do.

I have figured that I can put code in the OnLeftUp method to set the
dragShape pos to the min/max x/y values I want, so that at the end of
the dragging period, the object is left at the edge of the screen,
rather than off, but this is only semi-satisfactory: I'd prefer that the
user is preventing from dragging them out of an area at all, rather than
just having them snap back at the end.

You're close. if you put something in the OnMove (or something like
that, sorry I don't have the demo code available) method, you can catch
when the object is about to be moved off the screen, and then continue
to draw it at that spot, rather than have it follow the mouse out of the
window.

you're on the right track...

-Chris

-- --
Christopher Barker, Ph.D.
Oceanographer
                                                
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

If you're writing Python code, then this is the right list... even if
the answer would be the same for C++.

Thanks, Chris, and thanks for your suggestions. Read on for
clarifications.

> I don't want users to be able to drag objects off the side of the
> screen. Ideally, I'd really like to limit them to a particular area. It
> *looks* like I could do this by adding a wxRect as the final parameter
> for BeginDrag, ie:
>
> self.dragImage.BeginDrag(hotspot, self, 0)
>
> becoming:
>
> self.dragImage.BeginDrag(hotspot, self, 0, wxRect(10,10,500,500))
>
> would restrict to a rectangle at (10,10,510,510).
>
> However, this doesn't seem to have any discernable effect. Is this
> broken? Or am I misunderstanding the API for BeginDrag?

Take a look at the code for BeginDrag. As a newbie, it might take
alittle while to figure it out, but you'll learn in the process. Off
hand, I have no idea what it is supposed to do.

Ummm. The code for BeginDrag is, AFAICT, in the core C++ library. It's
not part of the Python code making up the demonstration. If you were
suggesting that the C++ library code would help me, I'm afraid I'm over
my head there.

According to the API:

"""
wxDragImage::BeginDrag
bool BeginDrag(const wxPoint& hotspot, wxWindow* window, bool fullScreen
= false, wxRect* rect = NULL)

...

rect

                If non-NULL, specifies the rectangle (in screen
                coordinates) that bounds the dragging operation.
                Specifying this can make the operation more efficient by
                cutting down on the area under consideration, and it can
                also make a visual difference since the drag is clipped
                to this area.
"""

I've tried to pass a wxRect to it, but this seems to have no effect. Am
I misunderstanding this API call, or is this not functioning?

You're close. if you put something in the OnMove (or something like
that, sorry I don't have the demo code available) method, you can catch
when the object is about to be moved off the screen, and then continue
to draw it at that spot, rather than have it follow the mouse out of the
window.

I had tried OnMove before posting, but I'm stuck a bit on where I'm
supposed to find/set the object's current coordinates.

In the demo's onMotion, in the second stanza (the part about already
having a shape we're dragging, not the part about starting a new drag):

We have the dragImage and the dragShape.

dragShape has the .pos it had where the shape started (which makes
sense, since, AFAICT, this object is only used to represent the shape
while not being dragged).

dragImage doesn't have any attributes that I can figure out that would
give me it's coordinates.

I can look at evt.GetPosition(), but this tells me the *mouse* position,
not the object position. I can (somewhat kludgily) stop the mouse from
going off the screen, but given that the mouse could be grabbing the
bottom right hand of the object, the object would still be 90% off the
screen.

It's not obvious to me how to find out where on the object the mouse is;
if I knew that, I could figure out if the mouse+object would be
offscreen and stop it there.

Thanks for any followup help anyone can provide.

- j.

···

On Tue, 2003-10-07 at 16:32, Chris Barker wrote:

Joel Burton wrote:

···

On Tue, 2003-10-07 at 16:32, Chris Barker wrote:

If you're writing Python code, then this is the right list... even if
the answer would be the same for C++.

Thanks, Chris, and thanks for your suggestions. Read on for
clarifications.

I don't want users to be able to drag objects off the side of the
screen. Ideally, I'd really like to limit them to a particular area. It
*looks* like I could do this by adding a wxRect as the final parameter
for BeginDrag, ie:

self.dragImage.BeginDrag(hotspot, self, 0)

becoming:

self.dragImage.BeginDrag(hotspot, self, 0, wxRect(10,10,500,500))

would restrict to a rectangle at (10,10,510,510).

However, this doesn't seem to have any discernable effect. Is this
broken? Or am I misunderstanding the API for BeginDrag?

Take a look at the code for BeginDrag. As a newbie, it might take
alittle while to figure it out, but you'll learn in the process. Off
hand, I have no idea what it is supposed to do.

Ummm. The code for BeginDrag is, AFAICT, in the core C++ library. It's
not part of the Python code making up the demonstration. If you were
suggesting that the C++ library code would help me, I'm afraid I'm over
my head there.

According to the API:

"""
wxDragImage::BeginDrag
bool BeginDrag(const wxPoint& hotspot, wxWindow* window, bool fullScreen
= false, wxRect* rect = NULL)

...

rect

                If non-NULL, specifies the rectangle (in screen
                coordinates) that bounds the dragging operation.
                Specifying this can make the operation more efficient by
                cutting down on the area under consideration, and it can
                also make a visual difference since the drag is clipped
                to this area.
"""

I've tried to pass a wxRect to it, but this seems to have no effect. Am
I misunderstanding this API call, or is this not functioning?

You're close. if you put something in the OnMove (or something like
that, sorry I don't have the demo code available) method, you can catch
when the object is about to be moved off the screen, and then continue
to draw it at that spot, rather than have it follow the mouse out of the
window.

I had tried OnMove before posting, but I'm stuck a bit on where I'm
supposed to find/set the object's current coordinates.

In the demo's onMotion, in the second stanza (the part about already
having a shape we're dragging, not the part about starting a new drag):

We have the dragImage and the dragShape.

dragShape has the .pos it had where the shape started (which makes
sense, since, AFAICT, this object is only used to represent the shape
while not being dragged).

dragImage doesn't have any attributes that I can figure out that would
give me it's coordinates.

I can look at evt.GetPosition(), but this tells me the *mouse* position,
not the object position. I can (somewhat kludgily) stop the mouse from
going off the screen, but given that the mouse could be grabbing the
bottom right hand of the object, the object would still be 90% off the
screen.

It's not obvious to me how to find out where on the object the mouse is;
if I knew that, I could figure out if the mouse+object would be
offscreen and stop it there.

Thanks for any followup help anyone can provide.

- j.

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwindows.org
For additional commands, e-mail: wxPython-users-help@lists.wxwindows.org

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

[ Sorry for the last message with no reply, I fumble fingered it.]

Joel Burton wrote:

Ummm. The code for BeginDrag is, AFAICT, in the core C++ library. It's
not part of the Python code making up the demonstration. If you were
suggesting that the C++ library code would help me, I'm afraid I'm over
my head there.

Other than the language difference it is basically the same as wxPython. The same class names and methods names are used in most cases, and it's not really that hard to get an idea of what's going on.

http://cvs.wxwindows.org/viewcvs.cgi/wxWindows/src/generic/dragimgg.cpp?rev=1.12&content-type=text/vnd.viewcvs-markup

According to the API:

"""
wxDragImage::BeginDrag
bool BeginDrag(const wxPoint& hotspot, wxWindow* window, bool fullScreen
= false, wxRect* rect = NULL)

...

rect

                If non-NULL, specifies the rectangle (in screen
                coordinates) that bounds the dragging operation.
                Specifying this can make the operation more efficient by
                cutting down on the area under consideration, and it can
                also make a visual difference since the drag is clipped
                to this area.
"""

I've tried to pass a wxRect to it, but this seems to have no effect. Am
I misunderstanding this API call, or is this not functioning?

It only clips the drawing of the image to that rect, (it's used in a call to SetClippingRegion.) It does not limit the dragging of the image in any way. You can limit it yourself since your code is calling the Move method.

You're close. if you put something in the OnMove (or something like
that, sorry I don't have the demo code available) method, you can catch
when the object is about to be moved off the screen, and then continue
to draw it at that spot, rather than have it follow the mouse out of the
window.

I had tried OnMove before posting, but I'm stuck a bit on where I'm
supposed to find/set the object's current coordinates.

In the demo's onMotion, in the second stanza (the part about already
having a shape we're dragging, not the part about starting a new drag):

We have the dragImage and the dragShape.

dragShape has the .pos it had where the shape started (which makes
sense, since, AFAICT, this object is only used to represent the shape
while not being dragged).

dragImage doesn't have any attributes that I can figure out that would
give me it's coordinates.

I can look at evt.GetPosition(), but this tells me the *mouse* position,
not the object position.

But that is also what is used to Move it:

    self.dragImage.Move(evt.GetPosition())

I can (somewhat kludgily) stop the mouse from
going off the screen, but given that the mouse could be grabbing the
bottom right hand of the object, the object would still be 90% off the
screen.

But you set the hotspot when you call BeginDrag and it is calculated as the offset from the origin of the object to the mouse position. Just use it in reverse to determine from the current mouse pos where the origin is now.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!