1. Computing

An SDL GUI for Empire

The design of a GUI

By

Screenshot of Empire Mapgen

The next few SDL tutorials will take a side step from pure Empire coding and look at implementing a Graphical User Interface (GUI). This will be needed for Empire so it's worth looking at on its own.

Note, if you are creating your own SDL project (for these sources in Visual Studio 2010 or Visual C++ Express 2010), then you should see How to setup Visual Studio 2010/Visual C++ 2010 Express with SDL.

SDL Has No Native GUI

We've seen in previous Empire tutorials how to use the mouse and keyboard but think how clumsy Windows would be if we had to code everything from scratch. Unfortunately with SDL we do, but that's good in a way. We can leave out all the messy stuff and focus on developing a simple GUI library.

We want to be able to easily create a panel and populate it with working controls. What controls do we need?

Note there's no code with this tutorial. The next one will have some working controls and will include the code.

What Controls are needed?

Not the full functionality of Windows GUI, that's for sure. A few buttons, check boxes, a list of clickable text, labels etc.

Below is my suggested list. If you want more controls then within a tutorial or two you should have the knowledge and code to create your own. If you do, why not send me the code and I'll add it to this and give you credit.

List of Desired GUI Controls

This is what I think we need. By the end of implementing these, I may come up with an extra one or two but for now this is the list.

  • A plain panel
  • A simple button. Something you click to do something.
  • A clickable text command.
  • A check box. Something you can tick or untick
  • A clickable list box. We'll keep it simple so no scrolling.
  • A popup box asking a question.
  • A Text entry box.
  • A text label
  • Display an image (not technically a control).

That's quite a list. I know a panel isn't really a control (technically controls should be clickable) nor is a displayable graphic but it's useful to have. Remember we're not trying to reimplement Windows here, just creating a GUI toolbox.

Using the GUI

If I get this right it should be easy to include a library then make calls to create a "Form" (Not a Windows form,- my name for Panel with GUI controls) then add the controls, along with functions they call when clicked etc. Something like:

#include "sdlgui.h"
...
ppanel = createpanel(x,y,width,height,color,false);
pcontrol prodbtn = ppanel-> addbutton("Set Production",x,y,width,height,color, &addproduction);
pcontrol checkautoprod = ppanel->addcheckbox("Auto Production",width,&autoprod);
...
gui.add(ppanel);

First we create a panel. The last parameter is a modal/non modal flag. If true then all input stops until this form is closed. It's for use in a right click popup on units and cities in Empire.

The createpanel() returns a pointer that is used for adding controls to this panel. All the add controls function return a pointer to themselves. You may not need this For instance the addcheckbox ()function is passed the name of an int variable (autoprod). If you check the Auto Production checkbox, then autoprod is set to 1 etc.

Having a pointer though lets you alter labels etc, or even the checkbox variable and you can have the panel remove the control from it's list (see below).

How in this GUI implemented?

Each of the controls is implemented as a struct, holding pointers for event handlers, checkbox variables, self draw functions, text labels plus variables for the various state values, width, height and x,y positions.

The panel holds a single linked list of these structs and has a function render() that walks the struct list and tells each control to render itself. It's a little like object oriented programming.

By default the library provides functions to render each type of control and plugs it into the render function pointer in the struct. You can alter it to point to your own function should you wish making it bit like virtual functions.

The main technique I use here is function pointers.

There's no GUI designer provided with this (anyone care to write one?), you have to manually figure out the size of controls with a bit of "suck it and see".

Fonts and Text

Just a word about this. Previously I've used my own mono width, single size font but that is a bit 1980s. So we'll be using SDL_TTF and some open fonts from the GNU Free UCS Outline fonts. Hurray for GNU!

This is not quite as quick to execute as my mono width font but it will make it look nicer and let us use different font sizes. I'm still looking to have the scrolling map (and control panel) running at 60 fps.

In the next tutorial I'll have a simple working example with some of the controls.

©2014 About.com. All rights reserved.