In my WIP ui system (which was started with Xith but has moved to my own engine since), I run against the choice you are talking about.
It turns up that, as soon as you start some complex widgets like a game UI, automatic resizing behaviors are not satisfying (either fixed ot not). I choosed to use a design similar to the one of Swing (LayoutManager interfaces for container widget and LayoutConstraint for contained widget) and it solved everything.
The layout classes are really easy to develop and they are much more flexible. So I think you should think about using this type of design.
Good luck
Vincent
Note : by the way, here are a few of the problems I encountered that, I think, are quite usual when building an ui system ;
. Requirements ;
I found that the requirements for a game ui are rather higher than for a more traditionnal ui system. In particular ;
- you have to handle 2D objects as well as 3D
- you have to have a very powerfull skinning system or the ui will only work for one game…
- you must be able to adapt to different screen resolutions
- your system must be able to live beside itself and the OS ui (for example when you have a non fullscreen application with more than one view canvas)
- you have to design an efficient ressource manager since OpenGL needs you to handle it (texture leaks, vertex buffer leaks,…)
It appeared that these requirements should be taken in account from the beginning of the design since they have quite a big impact on it and were difficult to add in the system later.
. General hierarchy ;
I tryed different hierarchy and finally ended with a main Shell object which was the main container. The shell object was in charge of forwarding canvas events to widgets. It was also in charge of keeping track of the focus.
I had to split the hierarchy betwwen IWidget2D and IWidget3D obviously corresponding to 3D objects (for example a player in the game) and 2D objects (for example abutton).
When events occured in the canvas, the shell would first check if the event should be routed to the IWidget2D object hierarchy (simple 2D math) and, if not, then perform picking in the scene (ray casting and bounding volume checking).
. Skinning ;
I started with a somewhat unflexible skinning system. I finally moved to a factory pattern for skinning ; the skin is a factory wich creates the basic widgets (button, list, frame, …) and ui parts (title bar, frame border,…).
A default factory implementation provides default implementation for complex widget (frames, list,…) using the ui parts which are not implemented in the default factory implementation (abstract methods which are implemented by skins).
. Widget hierarchy against Scenegraph hierarchy ;
I made some mistakes by not keeping in mind that Widgets are Scenegraph node but there hierarchy is not the one of the scenegraph.