Sign in to follow this  
martinuk

What would be a good algorithm for button event detection?

Recommended Posts

martinuk    132
Currently, I am using the STL <list> in C++ to hold all buttons in my program, each time a mouse left button is down, it will go through the list to find the mouse click point (x,y) is inside any button rectangle for detect whether the mouse is clicked on a Button. I know this probably the simplest way of doing it, and there should a better and faster way of doing it?

Share this post


Link to post
Share on other sites
Lord_Evil    680
Depends on how many buttons you have.
Assuming you don't use any gui library, you could use a 2D bounding box hierarchy to "cull" non-clicked buttons. I do something similar (for now just a container hierarchy) in order to detect the hovered component each time the gui or the mouse moves.

Share this post


Link to post
Share on other sites
phresnel    953
As long as you only have a handful of buttons (and not hundreds of them) just stick with that linear list. You will anyways only click very now and then on them, and there won't be noticable delay between click and reaction.

Share this post


Link to post
Share on other sites
kyoryu    224
Quote:
Original post by phresnel
As long as you only have a handful of buttons (and not hundreds of them) just stick with that linear list. You will anyways only click very now and then on them, and there won't be noticable delay between click and reaction.


Premature optimization is the root of all evil.

Share this post


Link to post
Share on other sites
tneva82    127
Quote:
Original post by phresnel
As long as you only have a handful of buttons (and not hundreds of them) just stick with that linear list. You will anyways only click very now and then on them, and there won't be noticable delay between click and reaction.


Amen.

But on related note on my GUI library(which I made to see a) wether I could do it and b) what work it involves) what I find to be bigger issue locating correct GUI element from ID fastly(for sending message to it). Not bad when there's only few but as program is used and more GUI elements are used it COULD get clunky.

Would changing list<GUIObject*> to two separate entities, list<GUIObject*> for those which don't need unique identifier(mainly text labels that don't get changed) and map<int, GUIObject*> for the rest work faster? Is there any faster method than looping through all or is it in the end equally fast/slow?

Not that this is particulary big problem(I think this won't be most likely bottleneck) but since this came up and I use map elsewhere for similar purpose(and here it COULD contain thousands of elements from which to find right one...) thought I might ask just on same.

BTW for original poster. If any of your buttons are grouped that could end up saving some time. My GUI library has buttons(and other elements) able to be child of others(buttons inside windows etc). So when mouse is clicked I go through list of what could be called root elements. If click happened within their space they go through their childs. They in turn go through their childs if any until finally I find last child which has the click area inside it(and above others so element top most takes responsibility over those below it) or that it was within root element itself. Obviously once I find the child I break the loop. If something like that works for you should atleast cut down a bit the search time if you haven't done it like this already.

Not that I particulary cared about efficiency when I designed that but it seemed most logical way to do it.

Share this post


Link to post
Share on other sites
Telgin    200
For the simple games that I've written, I do basically that (there is a list of GUI objects that I traverse and just brute force check each one). Even with a fair amount of GUI objects in the list, I haven't noticed any slow down, but I probably should profile it some day to see how fast it really is.

A simple method to improve performance would definitely be to group the objects. I did something akin to this in a project and it too seemed to work alright (all subjective of course). Instead of a simple list you could have a heirarchical tree of objects. Buttons would be attached to a window, for instance. When you get a mouse click event, you could trivially cut down on the amount of click checks involved. Each parent window could for instance check if the mouse pointer is inside itself, and if not don't pass the event along to child buttons.

Share this post


Link to post
Share on other sites
Maybe you could use a try-throw-catch method in there?

[You can delete your double posts by clicking "edit" and then checking the 'Delete?' box at the top and submitting the form. I've taken the liberty of doing it for you. - Zahlman]

[Edited by - Zahlman on April 30, 2009 9:01:39 PM]

Share this post


Link to post
Share on other sites
EJH    315
Yeah you'd probably need 100+ buttons before simple linear search would start becoming unfeasible. I usually group buttons by screen, so only active screens have their buttons checked.

Also you will probably, if not already, run into the issue where mouse buttons can press GUI buttons, fire a weapon, or pick 3D game objects. You'll need a quick way to know if the mouse is over a GUI button (e.g. so their gun doesn't fire when they press a HUD GUI element).

An easy way to do is just make an easily accessible boolean flag "MouseIsOverUIElement" that is set to false at the beginning of each frame, and set to true whenever a UI element detects that the mouse is over it. That way you don't have to requery every button every time the player fires or picks a 3D object.

Oh and the last thing: you should probably use C++ Vector, not List, because it is much faster for access.

Share this post


Link to post
Share on other sites
kingcools    122
maybe you could sort that list, so that the top buttons are in lower positions(or the other way around if you like that), so you could start searching the list at another position, saving some time.

Share this post


Link to post
Share on other sites
zedz    291
>>Yeah you'd probably need 100+ buttons before simple linear search would start becoming unfeasible.

100!, Ild guess in the range 10,000->10,000,000 (i.e I have no idea but its certainly far far more than 100) before u notice

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this