Mouse Events on Rectangles?

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
ninja9578
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 236
Joined: Thu Jan 29, 2009 3:33 pm

Mouse Events on Rectangles?

Post by ninja9578 » Wed Feb 04, 2009 9:20 pm

Is it possible to have a mouse event for a rectangle?

I've got a few rectangles on the window, and it would be nice if I could program a callback for each one if say: the mouse is clicked on it, or the mouse passes over it...

Is there a way to do that?

I know the obvious way is to make one mouse event callback and then have it search through the rectangles and see which one was pressed, but that would be very dirty and slow.

JimFairway
wxWorld Domination!
wxWorld Domination!
Posts: 1059
Joined: Sun Dec 30, 2007 6:40 pm
Location: Canada

Post by JimFairway » Wed Feb 04, 2009 9:35 pm

Hi,

Could you lay down some wxPanels instead and trigger the events from the panel?

Jim
OS: Vista SP1, wxWidgets 2.8.7.

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Post by Auria » Wed Feb 04, 2009 10:18 pm

Hi,

maybe you could define what exactly is a "rectangle"? Is it some component, is it drawn on a panel?
I know the obvious way is to make one mouse event callback and then have it search through the rectangles and see which one was pressed, but that would be very dirty and slow.
I have no idea why you say it would be slow; videogames do collision detections hundreds of time per seconds and they are not slow.

ninja9578
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 236
Joined: Thu Jan 29, 2009 3:33 pm

Post by ninja9578 » Thu Feb 05, 2009 3:03 pm

No, video games use picking, not collision detection.

The rectangles are various objects displayed on the screen. They range from wxRects to wxBitmaps. I could overlay wxRects over them that don't get drawn and would just be used for bounding boxes.

User avatar
Disch
Experienced Solver
Experienced Solver
Posts: 99
Joined: Wed Oct 17, 2007 2:01 am

Re: Mouse Events on Rectangles?

Post by Disch » Thu Feb 05, 2009 3:31 pm

ninja9578 wrote:I know the obvious way is to make one mouse event callback and then have it search through the rectangles and see which one was pressed, but that would be very dirty and slow.
This isn't really slow... this is essentially what the OS does anyway (how else can it figure out which window of which program to send the event to).

And yeah games do crazy amounts of work like this. Every time an object moves it needs to check to see if it collided with not only surface areas of the world map, but also with other objects. This becomes potentially several thousand collision checks every second.

Ever since I worked on an NES emulator, and seeing all the work that it entailed -- I'm dumbfounded how bloody fast modern computers are. Even low end ones.

----

Anyway back on point. If you're worried about speed issues you can employ some game programming collision tricks. Like doing a rough check before you actually check the bounding box. Perhaps enclose each rectangle in a circle and do a circle-point check before doing an actual bounding box check.

Code: Select all

MyBox::MyBox(const wxPoint& pos,const wxPoint& siz)
{
  const wxPoint half_siz(siz.x / 2,siz.y / 2);

  center = pos + half_siz;

  radius_sq = (half_siz.x * half_siz.x) + (half_siz.y * half_siz.y);
}

bool MyBox::PointInBox(const wxPoint& pt)
{
  // coarse circle check
  wxPoint p(pt-center);
  int distsq = (p.x * p.x) + (p.y * p.y);

  if(distsq > radius_sq)
    return false;        // outside of bounding circle

  // else, do bounding box check
}
Though now that I think about it, this isn't very practical for point-box collision detection (seems like overkill -- probably not any faster). It's more suited for box-box collision or collision between more complex shapes.

Another approach would be to divide the entire surface into "sectors" of a specific size and have each sector contain a list of the rectangles it contains. This way you can just do some simple calculations on the mouse coord (if the sectors are 256x256 pixels, just divide mouse coords by 256) to get the sector, then you only have to do collision checks with the boxes contained in that sector. This approach is more practical if the rectangles are stationary, but can get a little tricky if the rectangles are moving around a lot because you'd have to update the sectors' lists.

Anyway I wouldn't worry about speed issues for something like this unless you experience them. Generally this kind of thing is pretty quick -- drawing and bulk memory movement is what's slow... not minor calculations like this.

ninja9578
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 236
Joined: Thu Jan 29, 2009 3:33 pm

Post by ninja9578 » Thu Feb 05, 2009 4:21 pm

Thanks for the info. I realized now that some of my objects are going to be irregular shapes, so I've decided to use picking instead. I'm posting a new thread about the best way to do that now.

Post Reply