Maelstrom: Added UI text changed callback

From ca25f4c782a2055ef6fa2e70681160064f952b98 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 28 Nov 2025 15:23:46 -0800
Subject: [PATCH] Added UI text changed callback

---
 screenlib/UIElement.cpp | 15 +++++++++++
 screenlib/UIElement.h   | 57 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 72 insertions(+)

diff --git a/screenlib/UIElement.cpp b/screenlib/UIElement.cpp
index 176119ff..c84124dd 100644
--- a/screenlib/UIElement.cpp
+++ b/screenlib/UIElement.cpp
@@ -53,6 +53,7 @@ UIElement::UIElement(UIBaseElement *parent, const char *name, UIDrawEngine *draw
 	m_mouseInside = false;
 	m_mousePressed = false;
 	m_clickCallback = NULL;
+	m_textCallback = NULL;
 	m_action = NULL;
 	m_actionPressed = NULL;
 	m_actionReleased = NULL;
@@ -458,6 +459,10 @@ UIElement::SetText(const char *text)
 	if (m_drawEngine) {
 		m_drawEngine->OnTextChanged();
 	}
+
+	if (m_textCallback) {
+		(*m_textCallback)(m_text);
+	}
 }
 
 void
@@ -626,6 +631,16 @@ UIElement::SetClickCallback(UIClickCallback *callback)
 	}
 }
 
+void
+UIElement::SetTextCallback(UITextCallback *callback)
+{
+	if (m_textCallback) {
+		delete m_textCallback;
+	}
+
+	m_textCallback = callback;
+}
+
 void
 UIElement::SetAction(const char *action)
 {
diff --git a/screenlib/UIElement.h b/screenlib/UIElement.h
index 5791097b..c8597340 100644
--- a/screenlib/UIElement.h
+++ b/screenlib/UIElement.h
@@ -73,6 +73,51 @@ class UIFunctionClickCallback : public UIClickCallback
 	void *m_param;
 };
 
+class UITextCallback
+{
+public:
+	virtual ~UITextCallback() { }
+
+	virtual void operator()(const char *text) = 0;
+};
+
+template <class C>
+class UIObjectTextCallback : public UITextCallback
+{
+public:
+	UIObjectTextCallback(C *obj, void (C::*callback)(void*, const char*), void *param) : UITextCallback() {
+		m_obj = obj;
+		m_callback = callback;
+		m_param = param;
+	}
+
+	virtual void operator()(const char *text) {
+		(m_obj->*m_callback)(m_param, text);
+	}
+
+protected:
+	C *m_obj;
+	void (C::*m_callback)(void*, const char*);
+	void *m_param;
+};
+
+class UIFunctionTextCallback : public UITextCallback
+{
+public:
+	UIFunctionTextCallback(void (*callback)(void*, const char*), void *param) : UITextCallback() {
+		m_callback = callback;
+		m_param = param;
+	}
+
+	virtual void operator()(const char *text) {
+		(*m_callback)(m_param, text);
+	}
+
+protected:
+	void (*m_callback)(void*, const char*);
+	void *m_param;
+};
+
 // This is the basic thing you see on the screen.
 // It consists of an area, a parent, children, text, an image, and a
 // drawing engine which is notified of state changes.
@@ -199,6 +244,17 @@ DECLARE_TYPESAFE_CLASS(UIBaseElement)
 		SetClickCallback(new UIFunctionClickCallback(callback, param));
 	}
 	void SetClickCallback(UIClickCallback *callback);
+
+	// Once set, the element owns the text callback and will free it.
+	template <class C>
+	void SetTextCallback(C *obj, void (C::*callback)(void*, const char*), void *param = 0) {
+		SetTextCallback(new UIObjectTextCallback<C>(obj, callback, param));
+	}
+	void SetTextCallback(void (*callback)(void*, const char*), void *param = 0) {
+		SetTextCallback(new UIFunctionTextCallback(callback, param));
+	}
+	void SetTextCallback(UITextCallback *callback);
+
 	void SetAction(const char *action);
 
 	// These can be overridden by inheriting classes
@@ -231,6 +287,7 @@ DECLARE_TYPESAFE_CLASS(UIBaseElement)
 	bool m_mouseInside;
 	bool m_mousePressed;
 	UIClickCallback *m_clickCallback;
+	UITextCallback *m_textCallback;
 	char *m_action;
 	char *m_actionPressed;
 	char *m_actionReleased;