A Comparison of GUI Libraries for SFML: TGUI vs SFGUI vs IMGui and more

Tutorials Reviews

SFML is an excellent library that can be used to create 2D games in C++. It’s an abstraction over OpenGL and various system APIs, presenting a consistent and nice interface.

There are many different approaches and use-cases to creating GUIs which a standard approach embedded in SFML would not be able to cover, which is why SFML leaves it to other libraries. Additionally, whilst the S in SFML stands for Simple, GUI code rarely is.

There are many different options to choose from when attempting to implement GUIs, some of these will be detailed below.

Homegrown Solution

A full GUI library is likely to be overkill for most simple uses, such as those comprising of buttons and text boxes. These can be implemented rather simply using SFML’s graphics and input APIs. SFML already provides a nice cross-platform API for text input and clipboards.

Creating a GUI system with SFML

Dear ImGui

ImGui is a very easy to use library designed for use in prototyping and tools, but not for GUIs which are used by a typical end user, such as those that appear during gameplay.

It enables fast iteration, and prefers ease-of-use and simplicity over performance and customisability.

The Immediate Mode GUI pattern combines the rendering and the event handling of a GUI element. This is constrasted to event-based GUI libraries, where you first set up the elements, and then subscribe to receive events on them.

ImGui::Text("Hello, world %d", 123);
if (ImGui::Button("Save"))
    MySaveFunction();
ImGui::InputText("string", buf, IM_ARRAYSIZE(buf));
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);

ImGui Tutorial GitHub

Simple Fast GUI (SFGUI)

SFGUI provides a fully-functional automatic layouting system, with element bounds being allocated using an approach using requisition and allocation. Put simply: child elements request a minimum size called a requisition, and then parents allocate the final size for their children. This approach makes making responsive GUIs much easier.

SFGUI doesn’t provide much documentation other than the tutorials. The source has Doxygen documentation, but this isn’t hosted anywhere. Additionally, SFGUI only receives the bare-minimum maintenance to remain working. The last update which implemented a feature or fixed a bug was in June 2018. Admittedly, SFGUI is pretty stable with very few noticeable bugs, but has some gaping omissions such as tooltip and copy+paste support.

I didn’t get far enough to investigate the theming capabilities of SFGUI.

GitHub

Texus GUI (TGUI)

While Texus GUI does also provide some container-based formatting, such as a grid element, it is predominantly a constraint-based method of implementing GUIs. The position and size of elements is controlled using a custom domain-specific language (DSL).

widget->setPosition({"ButtonName.right + 50", "ButtonName.top"});
widget->setSize({"min(&.w, &.h * 4/3)", "min(&.h, &.w * 3/4)"});

Styling is done using stylesheets, written in a different custom DSL, to set up Renderers.

Button {
    Texture         = "button.png" Part(2, 104, 190, 49) Middle(10, 10, 170, 29);
    TextureHover    = "button.png" Part(2, 155, 190, 45) Middle(10, 10, 170, 25);
    TextureDown     = "button.png" Part(2, 202, 190, 45) Middle(10, 10, 170, 25);
    TextureFocused  = "button.png" Part(2, 155, 190, 45) Middle(10, 10, 170, 25);
    TextureDisabled = "button.png" Part(2, 2, 195, 49) Middle(10, 10, 175, 29);
    TextColor       = rgb(250, 250, 250);
    TextColorDisabled = rgb(100, 100, 100);
}

TGUI does appear to lack some code reuse for each element, which can make theming hit and miss. For example, I discovered that not all elements which have backgrounds support the same style properties to customise the background.

TGUI also only has a single active maintainer, the original creator Texus, who is very responsive to bug and feature requests.

TGUI is fairly well documented, with tutorials and a Doxygen site.

Website GitHub Doxygen Tutorials Discord

Crazy Eddy GUI (CEGUI)

CEGUI is a library which isn’t specific to SFML, and because of this has a much larger user-base than any of the other options. It has a team of maintainers, rather than a single person.

CEGUI uses outdated C++, and it shows in the API. There’s a lot of manual pointer use, and a lot of ugly APIs. This was an immediate killer for me, so I didn’t go further than this when investigating this library.

BitBucket Docs

Conclusion

Whilst I prefer the container-based requisition-allocation approach of SFGUI, the benefits of a well-maintained library are apparent which is why I use TGUI. I am considering switching back to SFGUI and maintaining it myself, but fear that this is too much of a distraction from making my game.

In this post, I tried to collect and convey the merits each approach but I may have made some mistakes. Please contact me, if you have any comments, I’ll publish them below and make corrections.