Finding elements in a custom GUI

Started by
2 comments, last by ApochPiQ 12 years, 1 month ago
By GUI, I mean the in-game interface. I'm curious how people manage the elements that compose a UI (such as lines of text on a window), such that you can find and change them later.

For example, let's say you parse your UI layout from XML, and create a memory model of the elements. Then later, during gameplay, you want to update a line of text to, say, display the HP of a character the player clicked on. How do you find which element to modify?

The only thing that comes to mind is a string map (std::map<std::string,int>), and have the game code hardcoded to find a particular element by name. But for me, a red flag goes up whenever I think a map is the solution, so I'm curious if this is how others would do it as well, or if there are better ways to lay them out in memory to be easily found from some sort of identifier.
Advertisement

The only thing that comes to mind is a string map (std::map<std::string,int>), and have the game code hardcoded to find a particular element by name. But for me, a red flag goes up whenever I think a map is the solution


Why? Sounds reasonable to me, at least in the absence of additional requirements.
If your UI is a typical "2D scenegraph" hierarchic system and it's guaranteed that the elements are always read, created and added to the parent elements in the same order, you could also go by the child indices of the UI elements. For example we could say that the 2nd child element of the player HUD is always the health, and the 3rd is the XP. Of course now you're just hardcoding another thing instead of name. I wouldn't necessarily think of this as a better way, just alternative.
The standard solution to this is to define an enum or some set of constants in your code, which is automatically generated by the UI editing tool. This associates a string (FOO_BUTTON) with an id number (42) in whatever way your language of choice best supports.

If you allocate these IDs linearly, ie. starting at 0 and counting up by 1, you can use a simple array to hold (smart) pointers to the actual widget objects associated with each control. So your access code looks like:

MyControls[FOO_BUTTON]->SetText("blah");

Et voila.


This is more or less how everybody does it; some people may use reflection instead of an enum, some may use a dictionary/map instead of a flat array, whatever. The point is, you basically have a mapping from one form of ID that your code understands (constant/enum names in this case) to a different form that is represented by your UI data structures (the flat MyControls array in this case) and you're done.

Do whatever feels natural. It's a UI toolkit, a std::map isn't going to kill you on performance or memory usage.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement