While thinking about creating interesting content for my blog after not having posted anything for a while, I taught that blogging about my progress on my quest to make my very own GUI engine from scratch might gather the interest of some people like it was the case on the unofficial French SFML’s discord.
So here it is! Since I started this GUI engine a while ago, I might not be able to cover as much details as I could have when I was freshly programming it. I will however try to explain it in details and if any questions arises, the Disqus comments thingy at the bottom should be there!
At it’s core, the engine is designed to allow me to create games using the SFML Library. I always liked to create things from scratch and this engine is no exception. The main idea is that a class will take care of the window as well as it’s loop and will contain a finite state machine. A small variety of states can actually be fed to this state machine to this day:
- Abstract State: This state is nothing more than a few functions like
draw(elapsedTime). It doesn’t really do anything and is usually there to serve as a boilerplate for any upcoming states that one might want to create.
- Abstract UI State: This one is very similar to the above state however the key difference is that it embeds a container of uiComponents and a few key functions that takes care of calling the proper functions for those interface components such as
trigger()when an item is hovered or clicked/triggered.
With those states, I -or anyone using this library- should be able to make simple game using my GUI engine. One point of which I truly appreciate is that the UI components only require to be instantiated once and depending on their role, might not need extra care after the state has been instantiated except when changing its content or something among those lines, but no extra checking for the Window’s events or extra resizes.
Since this is my 2nd attempt at creating a GUI engine, I already had some constraints I discovered while creating the very first GUI Engine.
The main flaws were that if any event was to happen and that any UI component would have been above or under an other UI component or any other sensitive area (for mouse events), it would have triggered everything in the zone! So I required a way to stop the propagation of the events once it would hit a component. With this problem in mind, I tinkered around and managed to implement a solution that works for now. I think however that when I will start implementing more complicated components such as drag and drop-able components, I might face some issues.
The other issue is that components relied heavily on some kind of utility class that I would add to almost every component class that did not do much. It could have been replaced by a singleton or could have been made in a better way. This utility allowed me to place my components on the window using a percentage ratio of the window, allowing the rest of the game to keep its original size but having a GUI that scales up or down depending on the window’s size. One of the solutions that came to my mind were that I should just drop the way I used to place the components, completely forgetting about using percentage on the game’s window. However, by mixing that utility class to a point class, it allowed me to create dynamic anchor on my windows. Elements could now be created with positions that could be either fixed/precise positions in pixels (or at least, SFML’s window’s units) as well as percentage of the Window.
Demo of two buttons using percentage and precise anchor types for position and size.
To this day, some features are still missing the Library for me or anyone to use it in a efficient or enjoyable fashion. I just added today a way to have anchors that can depend on other anchors to determine a position or size, but there is still some unsolved problems lying around them or some aspects that I would like to change to its usability. But that is a subject for an other post.
I hope you enjoyed
my first non-“Hello world” post I put on a blog for the last 2 years this blog post :).