I'm having some major issues with the game I'm developing, called Adage. It will eventually be a hacker-type RTS, but it's still in the early stages and I'm having a big problem with the widget set. For some reason - and I've looked and looked but simply can't find it - every widget but the top-level Text widgets don't display/are black. I know that they're there, because I did manage to blindly 'click' a button, but they're completely invisible. This obviously wasn't the case while I was developing them - they worked fine - but I made some changes to the structure of the game and... here I am now.
Here's how the structure of the widget/window system currently stands. I used to have a WidgetManager class, but I just implemented the Window and WindowManager classes. Windows keep track of their child widgets and forward all the draw() and blit() calls they receive from WindowManager to their child/grandchild/great-grandchild/etc. widgets. The Window class obtains a list of each of its child widgets' children/grandchildren/etc. by calling Widget::get_children() on each of them, which has the Widget make a list of its children, calls get_children() on those widgets, and returns it all back to the caller.
The lists are all put together in such a way that each widget is drawn/blitted before its parent. That brings me to drawing and blitting. Each widget has its own surface (which is a SDL_Surface). When draw() is called for that widget, it simply draws itself to its own surface. Then, when blit() is called, it blits its surface to its parent's surface (which it has a pointer to). The simplest example is a Button, which has a Text child. draw() is called for the Text child widget first (because of the way the child list is built). This causes the text to simply be drawn on the Text's own surface. Then draw() is called for the Button, where the actual button (without a caption) is drawn on the Button's surface. Next Text::blit() is called, which blits the caption of the button on to the Button's surface - you now have the full contents of what the button is going to look like on that surface. Almost there. Button::blit() fires off, which blits the button onto the Window's surface. Finally, the Window blits itself to the global screen surface.
That's the basic rundown of how everything works. Widget is the base widget class and all widgets derive from it. The only widgets I have so far are Text, Button, and RichText. Ignore input.cpp/input.h - they aren't compiled in and I haven't touched him in a very long time (busy with other things). The source files are grouped in directories by category. No need to look at boost/ either; all the files are directly from the boost library and aren't modified.
You need the SDL and SDL-ttf libraries to compile the sources. A GNU Makefile is provided; for anything else, you just need to compile all the .cpp files and link the libraries and all the objects except widget/preview.whatever for the main binary, and all except main.whatever for the preview binary. Yes, there are two binaries created when you compile. The adage binary is what will become the actual game (although it's really just a test now), and the preview binary has the job of letting you see all the widgets I've created. The adage binary will be a blank window, but the preview has two blocks of text - these are the top-level Text widgets, which are the only thing that seem to display. Both of them should display more than that.
If you need me to clarify anything, please say so; I know it's complicated and a lot to ask to try and debug an entire project, but I really am pretty desperate. It's not as scary as it sounds (hopefully), so please try .
Sources are available in a zipfile, bzip2/tarball, and WebSVN, for viewing in your browser.