Sign in to follow this  
gusso

Designing a GUI system for games, need help.

Recommended Posts

I'm going to start working on my own GUI library for my upcoming game/s. I have, however, quite a few questions regarding this. Specifically, which system should I implement to begin with?. Are event/message systems still the norm?, is there anything I should know? Ideally I would like to extend the base code creating different controls, etc. I would also like to have the possibility to use skins (textures) and flat controls (with color theme). However, what really puzzles me at this moment is the overall system for the management of events, messages, etc. Everything else seems quite trivial, although I'm sure it's not. Any suggestions?

Share this post


Link to post
Share on other sites
Some thoughts on overall structure of the management system:

Form a tree of controls, using the composite pattern. Panels etc can have children but buttons etc can't. Store a (smart) pointer to the root control in a Manager class. The Manager class should have members onClick, onKeyPress etc (choosing which messages to use requires some careful design), which by performing collision detection etc. forward the messages to the appropriate control by traversing the tree. The manager class will need some book-keeping data such as pointers (for example, boost::weak_ptr or your own equivalent) to currently selected control etc in order to be able to know where to forward keypress calls to.

All controls should also have methods onClick, onKeyPress etc. Don't fall into the trap of letting the Manager and Controls inherit from the same base class because they have somewhat similar event methods! They are NOT exactly the same and it is likely you will want to change the set of available messages and their signature in the manager and controls independently of one another. The onClick etc of your controls are part of the internal message representation of your GUI system. The onClick etc of your manager class are typically just raw forwarding of windows events to your manager system.

The final aspect is how to deal with messages from controls. A common method is to let the user inherit from a button and overriding the onClick method to get a button with a particular behavior. The template method pattern can be useful here: there are always some things a button needs to do when clicked (such as changing appearance), so don't just make one onClick method. Instead, make two! One which is never overridden and called internally by the manager, and another, which is automatically called by the internally used method, and it is this one that the user overrides.

Hope this helps!

Share this post


Link to post
Share on other sites
Thanks it does help, although I'm not going to use OOP. That's why I'm having extra trouble thinking about this.

Overall, what are the most important systems I should be focusing on to begin with?


Share this post


Link to post
Share on other sites
I've had some moderate success (read: it worked mostly how I wanted it to) writing Solariad's GUI by emulating AWT/Swing and using the MVC pattern. I also kept separate pointers to the widgets that had keyboard focus and mouse focus.

As a side note, rather than having just onClick, your widgets will probably want to handle onMouseDown, onMouseUp, and onMouseOver, otherwise you can neither style them differently for when a user clicks and does not release, nor can you implement dragging. Of course, if you don't care about some of those things, you can simplify your design somewhat. Otherwise, you have such interesting situations as a user pressing the mouse over a button and then dragging the cursor outside the button, which you then need to remember to unpress upon focus loss.

My top Manager class (called Desktop) also handled mouse clicks if no one else did. It seemed like a good place to handle scene picking.

I handled skinning by creating a class called UISkin which knew all texture coordinates of widget backgrounds (for instance, BUTTON_TOP_LEFT_CORNER) and held a reference to a Texture object representing the skin. The widgets used this information to paint themselves. This part was a bit of a temporary hack, though.

The way events are handled is that widgets expose listener registration, and you subscribe listeners (Observer pattern). The default behavior sends notification to a widget's listeners whenever something interesting occurs (scroll bar dragged, button clicked, whatever else).

Getting events about the model to the widgets is a bit more difficult (at least, it was for me). What you can do is have your controller object either poll the model or subscribe to the model's events and then update the widget. The controller is also the one who updates the model whenever it receives any interesting events from the widget (through the listeners it added to the widgets when they were initially created).

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