In the long term we'd like to get rid of Qt/KDE widgets in boson as far as possible (note: Qt/KDE _widgets_ but we will still depend on Qt/KDE for a lot of other things).
To achieve this we will need an OpenGL widget library.
There are a couple of such libraries out there, but since we make heavy use of widgets in boson, we have special requirements. For example we need lineedits, pushbuttons, checkboxes, textedits, sliders, ...
Also keep in mind that boson consists of more than the game itself, e.g. the unit editor or the boinfo program. We can safely stay at Qt/KDE widgets for these, but we would probably have a lot of duplicated work then. But e.g. the options dialog definitely has to be OpenGL based, as it is part of the actual game. Same about the startup widgets.
A while ago I wrote a list of requirements that I think an OpenGL Widget toolkit has to fullfill for us: WidgetToolkitRequirements
Unfortunately there are only very few libraries out there that fullfill at least most of the important requirements. All that I am aware of:
These two libraries are at least "interesting".
plib fullfills all of the core requirements:
- easy to use (from an API POV)
- provides the most important widgets
- it is a very wide spread game library. most linux gamers will have this installed anyway.
- it is actively maintained
- many applications use it (a lot of sample code)
- documentation is pretty good
However there are a few issues that plib is very bad at.
- it doesn't support layouts. that is fixable, as writing a layout subsystem isn't so hard (and I have done that for plib already)
- advanced widgets aren't supported. we don't even have tab widgets.
- the menubar doesn't support submenus. this is probably the biggest issue, because it is very hard to implement this manually in boson (due to the way the plib menubar is designed)
There are a few other issues that clearly show that the focus in plib is on the scenegraph library, but not on the widget library. There are many small issues that are very uncomfortable and that you face only when working with it for a while (and with advanced requirements as we have them). Usually they cannot fixed easily without changing plib code.
On the other hand we have libufo.
libufo is very powerful. It is designed as a widget library only and therefore that is where it's focus is. Even by looking at the class structure only you can see that the authors intend to provide a very ambitious and complete widget library.
And I think they even succeeded.
libufo provides most widgets that we may need (a few exceptions do of course exist.. but they are less important). Especially libufo provides the widgets that would be hard (as in "a lot of work") to implement in plib. E.g. the menubar should support submenus, too (note: in reality this feature may not be implemented. but since the set of available libraries is very small, I am very flexible at it. If I need such things I may even implement it on my own in the library and provide patches or so. The point is that the design of libufo supports such features).
Furthermore libufo is comparable to Qt in many aspects - especially in feature completeness.
Some other nice things:
- rendering can completely be customised (in plib only partially as far as I can see)
- technically superior to plib (as described above)
- supports layouts (saves us a lot of work)
However there are a few important issues with libufo, too:
- headers use a .hpp suffix
- hardly documented. this is not a big problem (we learned to use lib3ds, so we can use nearly everything
)
- uses STL. Fortunately STL classes are usually not needed when using it - but sometimes they are.
- uses a namespace (and additionally class prefixes. weird.)
- no GPL application using libufo is existing (non GPL neither). therefore no real sample code available.
- very experimental code (due to the fact that noone actually uses it)
- not wide spread. none of our users will have it installed. no rpm/deb packages available
- very big (source is about 2MB). that size prevents us from providing a copy in our own CVS (which would make a lot of sense as distributions don't provide libufo)
I have written some proof of concept code for both libraries already. From this I can say a couple of things about them now:
- plib is easier to use. puMouse(e.x(), e.y()) and you have implemented the mouse move event. in libufo it is a single line, too, but you have already written the plib line (which is obvious, clearly named and easy to find) a long time before you have found out in which libufo class the method is that you need to call.
- plib often works better. puDisplay() and your widgets are displayed. it's that simple. in libufo it's context->repaint() and then you spend the rest of the evening searching for the reason why your widgets don't appear. This comes from the simple fact that libufo is not used in real applications, but only in a few test programs that use libufo only. In this case for example libufo called glViewport() and didn't reset it back to the original value. So if you have your own GL code, you need to fix that manually.
- These fixes are usually easy, but finding them often is not.
- again plib is easier to use: use widget->setCallback(callback) and provide a callback function that uses a puObject* parameter. That's all you need for things like mouse clicks on a button. libufo uses it's own signal/slot system (that is of course incompatible to Qt). That's definitely a more powerful system, but also more complex and it's harder to code that cleanly (I expect bugs in libufo, as it is untested code). It takes definitely more time to find out how to get mouse clicks working with libufo. And to actually use them once you've learned how.
- libufo provides the most important stuff. Either spend a couple of hours writing a widget that you need for plib - or just use the widget that is available in libufo. Ok, maybe libufo is not that complete, but it provides more widgets than plib does (at least if you count only those that we might actually use)
- libufo is definitely more comfortable to use usually. Sometimes that is so extreme that I could say here: "libufo is easier to use". E.g. in libufo you do object->setText(string); where string is a normal QString - or maybe object->setText(string.latin1()). In plib the same would crash. plib wants you to allocate the memory for the string on your own and expects you to keep that memory for as long as the widget still uses it.
- again libufo is more feature complete: it has many things that we don't really need but that would be "nice to have". For example usable input checking - e.g. we want a lineedit that takes numbers < 100 and > 10 only. That is "pretty" easy with libufo. It can be coded with libufo without too much work (I think at least) whereas it is nearly impossible with plib - without modifying plib code.
So all in all I would say: plib is the better choice for getting this job done asap. It is easier to use and whenever it is not, it is easy to write a workaround.
But libufo is better for getting this job done right. The code design makes many things that are impossible with plib nearly trivial with libufo. Furthermore we have a better chance of getting patches into libufo. plib probably needs to provide at least source compatibility (simply because it is so wide spread), whereas that would not be required for libufo.
Conclusion:
I guess we go for libufo.
Biggest problem is that nobody has that library. I propose we provide a copy of the required .tar.gz file in our file releases for a while - at least until someone packages rpm and deb packages.