What would be a good algorithm for button event detection?

Started by
9 comments, last by zedz 14 years, 11 months ago
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?
Advertisement
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.
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!
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.
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.
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.
haven't done any grouping yet, and it does make sense so will give it a shot.
cheers
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.
Success requires no explanation. Failure allows none.
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]
Holy crap, you can read!
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.
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.

This topic is closed to new replies.

Advertisement