diff --git a/.vscode/settings.json b/.vscode/settings.json
index 3ca748198cece50e56ba3045077895a9bb52d950..970fe196c03e8b3ef674f1e6e840c593b0b67def 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -74,6 +74,15 @@
         "xmemory": "cpp",
         "xtr1common": "cpp",
         "xtree": "cpp",
-        "xutility": "cpp"
+        "xutility": "cpp",
+        "bitset": "cpp",
+        "codecvt": "cpp",
+        "condition_variable": "cpp",
+        "deque": "cpp",
+        "future": "cpp",
+        "queue": "cpp",
+        "random": "cpp",
+        "set": "cpp",
+        "stack": "cpp"
     }
 }
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a001a6bfb2a6ef5a69c435d87e2fc358fea1a4ba..e578234beccfe2c7489b67bfa2bff0e314a6884c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -63,8 +63,8 @@ find_package(OpenGL REQUIRED)
 # Add subdirectory for the GLApp library
 add_subdirectory(src)
 
-# Build the example, off by default
-option(BUILD_EXAMPLE "Build the hello world example" OFF)
+# Build the example, on by default
+option(BUILD_EXAMPLE "Build the hello world example" ON)
 if(BUILD_EXAMPLE)
     add_subdirectory(Example)
 endif()
diff --git a/Example/GLAppHelloWorld.cpp b/Example/GLAppHelloWorld.cpp
index ef3b1a6d8a37bed9920941624e5bac808d67b968..31b63955b097b715ad5e22f366ee4fce19169167 100644
--- a/Example/GLAppHelloWorld.cpp
+++ b/Example/GLAppHelloWorld.cpp
@@ -32,6 +32,8 @@
 #include "GLApp/GLTitledPanel.h"
 #include "GLApp/GLSpinner.h"
 #include "GLApp/GLInputBox.h"
+#include "GLApp/GLRadioButton.h"
+#include "GLApp/GLRadioGroup.h"
 
 #include "GradientWindow.h"
 #include "TabWindow.h"
@@ -83,6 +85,12 @@ GLAppHelloWorld::~GLAppHelloWorld() {
     //SAFE_DELETE(formulaXCloseablePanel);
     SAFE_DELETE(functionPanel);
 
+    SAFE_DELETE(radio1);
+    SAFE_DELETE(radio2);
+    SAFE_DELETE(radio3);
+    SAFE_DELETE(radio4);
+    SAFE_DELETE(showSelectedRadioButton);
+
     SAFE_DELETE(gradientWindow);
     SAFE_DELETE(colorPickerTabWindow);
 }
@@ -136,6 +144,12 @@ void GLAppHelloWorld::ProcessMessage(GLComponent* src, int message) {
             }
             return;
         }
+        if (src == showSelectedRadioButton) {
+            int selectedRadioInd = parentRadioGroup->GetSelectedIndex(); // Replace with GetSelected() to get the selected GLRadioButton object
+            GLMessageBox::Display(
+                fmt::format("Selected radio button index: {}", selectedRadioInd).c_str(), 
+                "Radio button", GLDLG_OK, GLDLG_ICONINFO);
+        }
         break;
     case MSG_TOGGLE:
         if (src == textToggle) {
@@ -198,6 +212,16 @@ void GLAppHelloWorld::ProcessMessage(GLComponent* src, int message) {
             formulaXCloseablePanel->SetBounds(x, y, w, h + heightInc);
         }
         break;
+    case MSG_RADIO:
+        if (src == radio1)
+            GLMessageBox::Display("Radio button 1 clicked", "Radio button", GLDLG_OK, GLDLG_ICONINFO);
+        else if (src == radio2)
+            GLMessageBox::Display("Radio button 2 clicked", "Radio button", GLDLG_OK, GLDLG_ICONINFO);
+        else if (src == radio3)
+            GLMessageBox::Display("Radio button 3 clicked", "Radio button", GLDLG_OK, GLDLG_ICONINFO);
+        else if (src == radio4)
+            GLMessageBox::Display("Radio button 4 clicked", "Radio button", GLDLG_OK, GLDLG_ICONINFO);
+        break;
     default:
         return;
     }
@@ -228,7 +252,7 @@ void GLAppHelloWorld::PlaceComponents() {
     iconLabel->SetBounds(cursorX, cursorY, controlWidth + 10, controlHeight);
     cursorX += controlWidth + 10 + xSpacing;
 
-    iconInfoToggle->SetBounds(cursorX, cursorY, 60, controlHeight);
+    iconInfoToggle->SetBounds(cursorX, cursorY, 90, controlHeight + 50);
     cursorX += 60;
 
     iconWarningToggle->SetBounds(cursorX, cursorY, controlWidth, controlHeight);
@@ -282,7 +306,17 @@ void GLAppHelloWorld::PlaceComponents() {
     panelCursorY = 30;
 
     functionPanel->SetCompBounds(formulaYLabel, panelCursorX, panelCursorY, controlWidth, controlHeight);
-    cursorY += controlWidth + ySpacing;
+    cursorY += controlHeight + 70 + ySpacing;
+
+    radio1->SetBounds(cursorX, cursorY, 90, 15);
+    cursorX += 90;
+    radio2->SetBounds(cursorX, cursorY, 90, 15);    
+    cursorX += 90;
+    radio3->SetBounds(cursorX, cursorY, 90, 15);
+    cursorX += 90;
+    radio4->SetBounds(cursorX, cursorY, 90, 15);
+    cursorX += 120;
+    showSelectedRadioButton->SetBounds(cursorX, cursorY, controlWidth, controlHeight);
 }
 
 int GLAppHelloWorld::FrameMove() {
@@ -402,6 +436,20 @@ int GLAppHelloWorld::OneTimeSceneInit() {
     formulaSetXButton = new GLButton(0, "Set x");
     formulaXCloseablePanel->Add(formulaSetXButton);
 
+    parentRadioGroup = std::make_shared<GLRadioGroup>();
+    radio1 = new GLRadioButton(0, "Test button 1", parentRadioGroup);
+    parentRadioGroup->Select(radio1);
+    Add(radio1);
+    radio2 = new GLRadioButton(1, "Test button 2", parentRadioGroup);
+    Add(radio2);
+    radio3 = new GLRadioButton(2, "Test button 3", parentRadioGroup);
+    Add(radio3);
+    radio4 = new GLRadioButton(3, "Test button 4", parentRadioGroup);
+    Add(radio4);
+
+    showSelectedRadioButton = new GLButton(0, "Show selected radio message");
+    Add(showSelectedRadioButton);
+
     gradientWindow = new GradientWindow();
     colorPickerTabWindow = new ColorPicker();
 
diff --git a/Example/GLAppHelloWorld.h b/Example/GLAppHelloWorld.h
index 6b4a54b0855a829880b4712115d8eab7b5f8d286..8731204274699b3452c7f7198ecb6f2ba9680e31 100644
--- a/Example/GLAppHelloWorld.h
+++ b/Example/GLAppHelloWorld.h
@@ -3,6 +3,7 @@
 #include <list> // for recents
 #include <string>
 #include <vector>
+#include <memory>
 
 #include <GLApp/GLApp.h>
 #include "GLApp/GLChart/GLChartConst.h"
@@ -21,6 +22,8 @@ class GLChart;
 class GLDataView;
 class GLTitledPanel;
 class GLSpinner;
+class GLRadioButton;
+class GLRadioGroup;
 
 class GradientWindow;
 class ColorPicker;
@@ -64,6 +67,12 @@ private:
 	GLButton* formulaSetXButton;
 	GLTitledPanel* formulaXCloseablePanel;
 	GLTitledPanel* functionPanel;
+	std::shared_ptr<GLRadioGroup> parentRadioGroup;
+	GLRadioButton* radio1;
+	GLRadioButton* radio2;
+	GLRadioButton* radio3;
+	GLRadioButton* radio4;
+	GLButton* showSelectedRadioButton;
 
 	GradientWindow* gradientWindow;
 	ColorPicker* colorPickerTabWindow;
diff --git a/copy_to_build/images/fnt_sansserif_8.png b/copy_to_build/images/fnt_sansserif_8.png
index 152e96186c3ca30dd09493f0e55bf181f64d16ec..30b0c5adae8ba92bbd41d125d9d3390d62a3e090 100644
Binary files a/copy_to_build/images/fnt_sansserif_8.png and b/copy_to_build/images/fnt_sansserif_8.png differ
diff --git a/copy_to_build/images/gui_background.png b/copy_to_build/images/gui_background.png
index d85456723d4990ec743d5fc3bd2578727c2a0a08..44f70f62caee38ba18338f3163507304096cd59c 100644
Binary files a/copy_to_build/images/gui_background.png and b/copy_to_build/images/gui_background.png differ
diff --git a/copy_to_build/images/gui_backgrounda.png b/copy_to_build/images/gui_backgrounda.png
index f584893947e81b00c900d071f835dade10cc41bc..b4f8f69d4db80fb326a3c027253b0aa0431a9f81 100644
Binary files a/copy_to_build/images/gui_backgrounda.png and b/copy_to_build/images/gui_backgrounda.png differ
diff --git a/include/GLApp/GLRadioButton.h b/include/GLApp/GLRadioButton.h
new file mode 100644
index 0000000000000000000000000000000000000000..697c5cd5259c82fc1c46d234b4df4d174f8dcf04
--- /dev/null
+++ b/include/GLApp/GLRadioButton.h
@@ -0,0 +1,36 @@
+
+#ifndef _GLRADIOBUTTONH_
+#define _GLRADIOBUTTONH_
+
+#include "GLComponent.h"
+#include <string>
+#include <memory>
+#include <iostream>
+//#include "GLSprite.h"
+class Sprite2D;
+class GLFont2D;
+class GLRadioGroup;
+
+class GLRadioButton : public GLComponent {
+public:
+	GLRadioButton(int compId, const std::string& text, std::shared_ptr<GLRadioGroup> parentRadioGroup);
+
+	void SetText(const std::string& text);
+	bool GetSelected();
+	void SetSelected(bool setSelected);
+	void SelectInParent();
+	std::shared_ptr<GLRadioGroup> GetParentRadioGroup();
+
+	void Paint();
+	void ManageEvent(SDL_Event* evt);
+	void SetFontColor(float red, float green, float blue);
+	void SetFontColor(int red, int green, int blue);
+private:
+
+	std::string text;
+	bool selected;
+	float r, g, b;
+	std::shared_ptr<GLRadioGroup> parentRadioGroup;
+};
+
+#endif /* _GLRADIOBUTTONH_ */
\ No newline at end of file
diff --git a/include/GLApp/GLRadioGroup.h b/include/GLApp/GLRadioGroup.h
new file mode 100644
index 0000000000000000000000000000000000000000..4d5d8c5c745a7c2d2b343b3e7124e56a00767068
--- /dev/null
+++ b/include/GLApp/GLRadioGroup.h
@@ -0,0 +1,22 @@
+#ifndef _GLRADIOGROUP_
+#define _GLRADIOGROUP_
+
+#include <vector>
+#include <iostream>
+
+class GLRadioButton;
+
+class GLRadioGroup {
+public:
+	void Select(GLRadioButton* button);
+	void Register(GLRadioButton* button);
+	void Unregister(GLRadioButton* button);
+	int GetSelectedIndex();
+	GLRadioButton* GetSelected();
+
+private:
+	std::vector<GLRadioButton*> buttons;
+	GLRadioButton* selectedButton = nullptr;
+};
+
+#endif /* _GLRADIOGROUP_ */
\ No newline at end of file
diff --git a/include/GLApp/GLToolkit.h b/include/GLApp/GLToolkit.h
index 5be53a5a81b8e204bf62198f7d52f2ab55061013..a8bea8c4b9e71300d1354454dcbb9fc045b431c8 100644
--- a/include/GLApp/GLToolkit.h
+++ b/include/GLApp/GLToolkit.h
@@ -90,6 +90,7 @@ public:
 	  const int height,const int state);
   static void DrawSmallButton(int x,int y,int state);
   static void DrawTinyButton(int x,int y,int state);
+  static void DrawRoundButton(const int x, const int y);
   static void DrawToggle(int x,int y);
   static void DrawBar(int x,int y,int width,int height);
   static void DrawTextBack(const int x,const int y,const int width,
diff --git a/include/GLApp/GLTypes.h b/include/GLApp/GLTypes.h
index 7b786f76843b162219d6404a82e0619b45958e2a..de348df9763b9fa9549b99025c7553bd4b3ab1be 100644
--- a/include/GLApp/GLTypes.h
+++ b/include/GLApp/GLTypes.h
@@ -24,6 +24,7 @@
 #define MSG_TAB      14   // Tab window change
 #define MSG_SPINNER  15   // Spinner change
 #define MSG_PANELR   16   // Panel open/close
+#define MSG_RADIO    17   // Radio select
 
 #define MSG_USER     256
 
diff --git a/src/GLApp/GLRadioButton.cpp b/src/GLApp/GLRadioButton.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..63dc6112b26f74a25712699a17591eebd823caa0
--- /dev/null
+++ b/src/GLApp/GLRadioButton.cpp
@@ -0,0 +1,90 @@
+
+#include "GLApp/GLWindow.h"
+#include "GLApp/GLRadioButton.h"
+#include "GLApp/GLRadioGroup.h"
+#include "GLApp/GLToolkit.h"
+#include "GLApp/GLSprite.h"
+#include "GLApp/GLFont.h"
+#include "GLHelper/MathTools.h"
+#include <cstring> //strcpy, etc.
+#include <vector>
+
+/**
+ * Create a new radio button, set its parent radio group and register it inside it.
+ * @param compId The id of this radio button.
+ * @param text The text on the button.
+ * @param parentRadioGroup The parent radio group to register the radio button under.
+ */
+GLRadioButton::GLRadioButton(int compId, const std::string& text, std::shared_ptr<GLRadioGroup> parentRadioGroup) : GLComponent(compId) {
+	this->text = text;
+	selected = false;
+	r = g = b = 0.0f; //default color: black
+	this->parentRadioGroup = parentRadioGroup;
+	this->parentRadioGroup->Register(this);
+}
+
+bool GLRadioButton::GetSelected() {
+	return selected;
+}
+
+void GLRadioButton::SetSelected(bool setSelected) {
+	selected = setSelected;
+}
+
+/**
+ * Set the state of this radio button to `selected` and select it in its radio group.
+ */
+void GLRadioButton::SelectInParent() {
+	if (parentRadioGroup)
+		parentRadioGroup->Select(this);
+}
+
+std::shared_ptr<GLRadioGroup> GLRadioButton::GetParentRadioGroup() {
+	return parentRadioGroup;
+}
+
+void GLRadioButton::SetText(const std::string& text) {
+	this->text = text;
+}
+
+void GLRadioButton::SetFontColor(int red, int green, int blue) {
+	SetFontColor((float)red / 255.0f, (float)green / 255.0f, (float)blue / 255.0f);
+}
+
+void GLRadioButton::SetFontColor(float red, float green, float blue) {
+	r = red;
+	g = green;
+	b = blue;
+}
+
+void GLRadioButton::Paint() {
+	if (!parent) return;
+	GLFont2D* font = GLToolkit::GetDialogFont();
+
+	GLComponent::Paint();
+
+	font->SetTextColor(r, g, b);
+	font->GLDrawText(posX + 16, posY + 2, text.c_str(), false);
+
+	GLToolkit::DrawRoundButton(posX + 2, posY + 3);
+	if (selected) {
+		font->SetTextColor(0.0f, 0.0f, 0.0f);
+		font->GLDrawText(posX + 4, posY + 1, "\216", false);
+	}
+	GLToolkit::CheckGLErrors("GLRadioButton::Paint()");
+}
+
+void GLRadioButton::ManageEvent(SDL_Event* evt) {
+
+	if (!parent) return;
+
+	if (evt->type == SDL_MOUSEBUTTONDOWN) {
+		if (evt->button.button == SDL_BUTTON_LEFT) {
+			selected = true;
+			if (parentRadioGroup) {
+				parentRadioGroup->Select(this);
+			}
+			parent->ProcessMessage(this, MSG_RADIO);
+		}
+	}
+}
diff --git a/src/GLApp/GLRadioGroup.cpp b/src/GLApp/GLRadioGroup.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e0c25666214ad13064d6e9a581354573a914763f
--- /dev/null
+++ b/src/GLApp/GLRadioGroup.cpp
@@ -0,0 +1,58 @@
+#include "GLApp/GLRadioGroup.h"
+#include "GLApp/GLRadioButton.h"
+#include "GLApp/GLTypes.h"
+#include <algorithm>
+
+/**
+ * Select a radio button in this group, deselecting the current one.
+ * @param button The radio button to select.
+ */
+void GLRadioGroup::Select(GLRadioButton* button) {
+    if (selectedButton) {
+		for (GLRadioButton* button : buttons) 
+			button->SetSelected(false);
+	}
+	selectedButton = button;
+	selectedButton->SetSelected(true);
+}
+
+/**
+ * Register a radio button in this group.
+ * A radio button can only be registered if this group
+ * is set as its parent radio group during construction.
+ * @param button The radio button to register.
+ */
+void GLRadioGroup::Register(GLRadioButton *button) {
+	// Group can accept a button only if it is already the button's parent.
+	// Prevents buttons from belonging to multiple groups.
+	if (button->GetParentRadioGroup().get() == this) {
+		std::vector<GLRadioButton*>::iterator it = std::find(buttons.begin(), buttons.end(), button);
+		if (it == buttons.end()) { // Register the button only if it's not yet registered
+			buttons.push_back(button);
+		}
+	}
+}
+
+void GLRadioGroup::Unregister(GLRadioButton *button) {
+	std::vector<GLRadioButton*>::iterator it = std::find(buttons.begin(), buttons.end(), button);
+	if (it != buttons.end())
+		buttons.erase(it);
+}
+
+/**
+ * Get the index of the sleceted radio button.
+ * @return The index of the selected button, -1 if no button is selected.
+ */
+int GLRadioGroup::GetSelectedIndex() {
+	std::vector<GLRadioButton*>::iterator it = std::find(buttons.begin(), buttons.end(), selectedButton);
+	if (it != buttons.end()) 
+		return it - buttons.begin();
+	return -1;
+}
+
+/**
+ * Get the selected radio button.
+ */
+GLRadioButton* GLRadioGroup::GetSelected() {
+    return selectedButton;
+}
diff --git a/src/GLApp/GLToolkit.cpp b/src/GLApp/GLToolkit.cpp
index 8f46c7962e5ba6f0e54f96a2520647787e8a1bbb..bfbb41fbfb4be01068d35220845a179bed4dd85d 100644
--- a/src/GLApp/GLToolkit.cpp
+++ b/src/GLApp/GLToolkit.cpp
@@ -450,6 +450,13 @@ void GLToolkit::DrawSmallButton(int x,int y,int state) {
 
 }
 
+void GLToolkit::DrawRoundButton(const int x, const int y) {
+  compTex->SetColor(1.0f, 1.0f, 1.0f);
+  compTex->UpdateSprite(x, y, x + 12, y + 12);
+  compTex->SetSpriteMapping(17.0f / TW, 95.0f / TW, 29.0f / TW, 107.0f / TW);
+  compTex->Render(false);
+}
+
 void GLToolkit::DrawToggle(int x,int y) {
 
   compTex->SetColor(1.0f,1.0f,1.0f);