Basically, you need to know how GUI libraries work. In fact, you could even have a look on some of them to see how they get these things done (for example, you may have a look at GTK+ docs, or Qt docs to see the interface)
However, assuming that you're not building the whole GUI library, but rather some basic Window
/Text
/Image
/TextLabel
/Checkbox
/RadioButton
/Button
library, I am going to share one possible approach how to do it.
Intro - rendering & data storage
Let's say you have a Window
class. It already handles some basic functionality, like rendering and moving. The class also takes care of adding widgets. Widgets are Text
or Image
, for example.
class Window
{
...
void render() const;
void move(const Vector & offset);
void addWidget(const Widget newWidget); // Or you could use a reference, it depends on where do you want to store them/if you want to manipulate with them during their lifetime
...
}
Of course, you could be adding widgets to some grid cells, or you could give some offset relative to window on top of that.
Widget
class could look like this:
class Widget
{
...
virtual void render() const = 0;
...
}
I think it's clear for you now how you populate the window with the necessary information. Widget
- derived classed will contain them. For example:
class Text: public Widget
{
Text(const std::string);
~Text();
void render() const
...
}
// Somewhere else in your code
for (const int &obj : weapons)
windowListingAllTheWeapons.addWidget(Text(obj.getName()));
The widgets will be displayed by calling their render()
methods in the render()
method of the window, which stores all the widgets (or references/pointers to them).
Handling events
Now all you have to do is to add some handleEvents()
method to Window
, which will call handleEvents()
of its respective widgets. This may get complicated, but as long as you stay in one-layer-depth, it's easy-peasy.
handleEvents()
will take care of catching events which occurred in the area of the widget and Widget
will invoke onEvent()
methods (for example onClick()
, onHover()
, onMouseRelease()
, etc), which will be appropriately overrided in the derived classes.
Widget::handleEvents(Event & event) // I don't know exactly how SDL handles events. I assume here that all the mouse events caught in Window class get distributed based on their position
{
// this is kind-of-a-pseudo-code. I don't know SDL
if(event.type == Event::Type::MouseClick)
{
onMouseClick(Mouse::getPosition());
}
// Yeah, it's better to use switch for multiple options
}
Button::onMouseClick(const Vector & position)
{
this.setClicked()
this.invokeSomeOtherAction()
}
Disclaimer
This is not a tutorial on creating a GUI library. It's how I make GUI for small, not-GUI-heavy games. This is an overview of the process of creating quick'n'dirty GUI system. Anyone reading this, who is more interested in the topic should have a look at Observer pattern, Qt's Signal And Slot, MVC and should spend some time researching even more approaches on how to implement GUI.