GUI system - HopsonCommunity/Community-Game GitHub Wiki

How does the GUI system work?

The UI class

The UI class handles updating and rendering of its components. Every frame, input is detected, and if the mouse hovers, clicks or clicks and holds on an element, the hover(int x, int y), click(int x, int y) or clickAndHold(int x, int y) functions are getting called on the element. If the cursor doesn't hover or click an element, nothing() will be called. After updating, the UI renders its components. To add a component like button or slider, call addComponent() with a class instance that has UIComponentBase as its base class.

Creating new UI elements with UIComponentBase

UIComponentBase is the base class of every UI element. The constructor needs a rectangle which defines the position and width/height of the component. It is needed so that the interaction-functions(hover, click, clickAndHold) get the relative position to their top-left corner as their argument.

UIComponentBase has 5 virtual function, which have to be overriden by the child object.

  • void hover(int x, int y): This function will be called when the cursor hovers over the UI element. x and y are relative position to the top-left corner of the UI element.
  • void click(int x, int y): This function will be called when the user clicks onto a UI element. x and y are relative position to the top-left corner of the UI element.
  • void clickAndHold(int x, int y): This function will be called when the user holds onto a UI element, and will only be called after click(). x and y are relative position to the top-left corner of the UI element.
  • void none(): This function will be called if the curser isn't ontop of the UI element. Use that function to reset the sprite to a non-pressed and non-hovered state.
  • void render(sf::RenderWindow& window): This function will be called to render the UI element to the window specified. Use m_transform of the base to calculate the sprite position. You can also render multiple sprites, as seen in the slider class

Using the UI system in code

Using buttons

Buttons are easy to use. You define the label of the button, its dimensions and position, and set a callback.

Setting a label

Create a new UI::Label object and pass is as the first argument of the constructor

Setting the dimensions and position

Use an sf::Rect<int> instance to define the position and pass it as the second argument to the constructor.

Setting the callback

The callback will be called when the user clicks on the button. If you just want a static function to be a callback, just pass &FunctionName to the constructor. However, if the function you want as a callback is the member of a class, you have to use std::bind to bind the function pointer to a class. Use std::bind(&Class::Function, pointerToTheInstance).

Example: You have a class Foo and you want UIButton to call bar. Inside the foo class, just do std::bind(&Foo::bar, this).

Attention: The function has to have the return type void and has to accept no arguments.

Pass the callback as the third argument to the constructor.

Example of a button construction: m_button = UI::UIButton(UI::Label(sf::Text("Test Button", app->getResources().fonts.get("SourceCodePro-Regular"), 18)), sf::Rect<int>(10, 10, 150, 50), std::bind(&SPlaying::buttonCallback, this))

⚠️ **GitHub.com Fallback** ⚠️