Maelstrom: Added the concept of a panel delegate which can be used to easily extend panels.

https://github.com/libsdl-org/Maelstrom/commit/d205268d39d894228fdebb1d79193aeb25733d08

From d205268d39d894228fdebb1d79193aeb25733d08 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Tue, 25 Oct 2011 01:05:10 -0400
Subject: [PATCH] Added the concept of a panel delegate which can be used to
 easily extend panels.

---
 screenlib/UIElementButton.cpp |  3 ++-
 screenlib/UIPanel.cpp         | 25 +++++++++++++++++++++++++
 screenlib/UIPanel.h           | 13 +++++++++++++
 3 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/screenlib/UIElementButton.cpp b/screenlib/UIElementButton.cpp
index fd313818..91c34284 100644
--- a/screenlib/UIElementButton.cpp
+++ b/screenlib/UIElementButton.cpp
@@ -58,10 +58,11 @@ UIElementButton::UIElementButton(UIPanel *panel, const char *name) :
 
 UIElementButton::~UIElementButton()
 {
+	SetButtonDelegate(NULL);
+
 	if (m_clickPanel) {
 		delete[] m_clickPanel;
 	}
-	SetButtonDelegate(NULL);
 }
 
 bool
diff --git a/screenlib/UIPanel.cpp b/screenlib/UIPanel.cpp
index 36d24c82..5c584974 100644
--- a/screenlib/UIPanel.cpp
+++ b/screenlib/UIPanel.cpp
@@ -40,6 +40,8 @@ UIPanel::UIPanel(UIManager *ui, const char *name) : UIArea(ui->GetScreen())
 	m_fullscreen = true;
 	m_enterSound = 0;
 	m_leaveSound = 0;
+	m_delegate = NULL;
+	m_deleteDelegate = false;
 
 	m_ui->AddPanel(this);
 }
@@ -48,6 +50,8 @@ UIPanel::~UIPanel()
 {
 	m_ui->RemovePanel(this);
 
+	SetPanelDelegate(NULL);
+
 	delete[] m_name;
 
 	for (unsigned i = 0; i < m_elements.length(); ++i) {
@@ -172,6 +176,16 @@ UIPanel::GetElement(const char *name)
 	return NULL;
 }
 
+void
+UIPanel::SetPanelDelegate(UIPanelDelegate *delegate, bool autodelete)
+{
+	if (m_delegate && m_deleteDelegate) {
+		delete m_delegate;
+	}
+	m_delegate = delegate;
+	m_deleteDelegate = autodelete;
+}
+
 void
 UIPanel::Show()
 {
@@ -179,6 +193,10 @@ UIPanel::Show()
 		m_ui->PlaySound(m_enterSound);
 	}
 	UIArea::Show();
+
+	if (m_delegate) {
+		m_delegate->OnShow();
+	}
 }
 
 void
@@ -188,6 +206,10 @@ UIPanel::Hide()
 		m_ui->PlaySound(m_leaveSound);
 	}
 	UIArea::Hide();
+
+	if (m_delegate) {
+		m_delegate->OnHide();
+	}
 }
 
 void
@@ -198,6 +220,9 @@ UIPanel::Draw()
 			m_elements[i]->Draw();
 		}
 	}
+	if (m_delegate) {
+		m_delegate->OnDraw();
+	}
 }
 
 bool
diff --git a/screenlib/UIPanel.h b/screenlib/UIPanel.h
index 26ff81a2..a7c4abe1 100644
--- a/screenlib/UIPanel.h
+++ b/screenlib/UIPanel.h
@@ -35,6 +35,14 @@ class FrameBuf;
 class UIManager;
 
 
+class UIPanelDelegate
+{
+public:
+	virtual void OnShow() { }
+	virtual void OnHide() { }
+	virtual void OnDraw() { }
+};
+
 class UIPanel : public UIArea
 {
 public:
@@ -70,6 +78,8 @@ class UIPanel : public UIArea
 		m_elements.remove(element);
 	}
 
+	void SetPanelDelegate(UIPanelDelegate *delegate, bool autodelete = true);
+
 	virtual void Show();
 	virtual void Hide();
 
@@ -82,8 +92,11 @@ class UIPanel : public UIArea
 	bool m_fullscreen;
 	int m_enterSound;
 	int m_leaveSound;
+	UIPanelDelegate *m_delegate;
+	bool m_deleteDelegate;
 	array<UIElement *> m_elements;
 
+protected:
 	UIElement *GetElement(const char *name);
 
 	bool LoadElements(rapidxml::xml_node<> *node);