Sign in to follow this  
mongrol

UI design resources

Recommended Posts

Hi folks, I'm at the stage where I'm coding a small UI framework to use in my game. However I'm struggling finding decent resources or articles on how to structure my code (C++) and the framework. I keep digging up articles on large and alreading existing frameworks like wxWidgets, QT etc. My aim is to produce a small, reusable framework for the various screens in my game. Buttons, Listviews containing buttons or other widgets and the associated responder chain or selector ring. Some placement smarts for packing, sensible keyboard navigation etc. Hardly rocket science I know but I'm sure there are tried and tested ways of approaching this. I'm asking for some help since I can tell there's a potential of getting it very wrong after a great deal of typing. :) Does anyone know of any articles about creating basic UI frameworks from the ground up?

Share this post


Link to post
Share on other sites
There are a couple of articles on this, but the ones I read were all a bit useless. In the end, what I did was look at the Swing and AWT API's and pretty much copied them (only the parts I needed, not the complex stuff). The actual implementation is of course completely different, but the API looks familiar. You can use any of the big UI libraries for this and just rip out and simplify the parts of the interface that make sense to you.

Another way to approach this could be to come up with how you want to use the UI first (for instance, you can look at how the World of Warcraft UI definition works, or cook up your own). Then you figure out how to get it on screen.

I would start with a few basic classes:
Widget - basic component that has size and position and can accept input events
Container - holds other widgets, can bring them to front or send to back, can figure out which widget the mouse input should go to
Graphics - interface between your renderer and your widgets

Back from when I was struggling with my own UI (which is still rather basic if usable), I remember that the parts I had most difficulty with was getting all the mouse focus and keyboard focus stuff done right. There's all kinds of fun to be had when you try to drag around a window with the mouse but the mouse goes outside the window and other edge cases like that. If you don't need that kind of behavior, you can save yourself some typing (and thinking).

Share this post


Link to post
Share on other sites
Thanks for that. Now after some musing I realise this is a lot easier (or should) than I originally thought. My current structure is quite simple. My game is purely keyboard driven so in my UI event loop I simply execute() the currently selected widget. The widget then returns an event which later on in my loop is turned into an action. This is where I'm doing it wrong. Ideally I should send the event into the widget where it then decides what to do. This means I can have widgets supporting different keypresses. A container can either change it's selected child widget or pass the keypress into the selected widget where it's executed like a top level widget. Simple.

However. Ideally I'd like to pass a function to my widgets at creation for them to execute against. This give's me flexability as buttons etc can then be used for anything. I tried to use function pointers for this but couldn't get them working properly as the functions I was trying to pass was in a singleton class (I know, I know). Is function pointers the best way to do approach this or is there a better way of having widgets execute arbitrary functions outside their class?

I realise this may be better off in the beginners forum.

Share this post


Link to post
Share on other sites
In Java we use anonymous inner classes for this (or you could attach a script to execute, maybe). In C++ you can probably use a named inner class instead (I have no clue really). I'm told that anonymous inner class in C++ can't access the outer class, which could be a limiting factor depending on what you want to do.

Basically look into ways of implementing Listener Pattern (or Observer Pattern, same thing) in C++.

Share this post


Link to post
Share on other sites
Quote:
Original post by mongrol
However. Ideally I'd like to pass a function to my widgets at creation for them to execute against. This give's me flexability as buttons etc can then be used for anything. I tried to use function pointers for this but couldn't get them working properly as the functions I was trying to pass was in a singleton class (I know, I know). Is function pointers the best way to do approach this or is there a better way of having widgets execute arbitrary functions outside their class?

I realise this may be better off in the beginners forum.


There're so many ways of doing it :) I would stick with calling functions. There are two ways to go. First, call a static function, which is quite simple, or call a given function on an object.

Ok, here's some code, I don't think that it will compile, but it will give you the direction. For further information take a look at Function Pointer Tutorial or google for "c++ function pointer".


class Handler
{

}

class MyHandler : Handler
{
int button1Pressed( int arg) {...}
int button2Pressed( int arg) {...}
int button3Pressed( int arg) {...}
}

// define a new function pointer of type HandlerFunc, return value is int and it needs one int argument
typedef int (Handler::*HandlerFunc)(int)
class Widget
{
// define function pointer and remember handler
Handler eventHandler;
HandlerFunc eventHandlerFunc;



// register handler
void registerEventHandler( Handler* pEventHandler, HandlerFunc pEventHandlerFunc)
{
eventHandler = pEventHandler;
eventHandlerFunc = pEventHandlerFunc;


}

// trigger event
void triggerEvent()
{
// call event handler function on given handler object
int result = (eventHandler->*eventHandlerFunc)(42);

}
}


// register handler somewhere in your code
MyHandler* myHandler = new MyHandler();
// we want that the given widget calls "button1Pressed" on myHandler, when the widget has been triggered
givenWidget.registerEventHandler(handler, &MyHandler::button1Pressed);

Share this post


Link to post
Share on other sites
The way I did (am doing) it:
Everything has its own calling functions:
drawing
mouse button down, up
mouse roll
mouse on/off
deactivate
mouse drag
key down
char down

That way you will have a very flexible system. There are generalized functions of course: for example radio-buttons, or edit boxes have the same functions, operating on the current item.

The mouse move "engine" of the GUI simply calculates the selected (mouse-on) item.
The event "engines" (mouse up, mouse roll, keyboard etc) execute the call functions of the selected item. Mouse up "engine" handles windowing (putting selected on top, if the topmost window isn't modal), and calls the mouse down function of the selected item.

This is a bit hard at the beginning, but quickly becomes very useful, so addig a new window/item is just 1 minute (including the refinements: sizes, layout, etc).

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