Maelstrom: Separated dialog functionality from the look and feel.

https://github.com/libsdl-org/Maelstrom/commit/476ccbddc23cf77d57ca8028365ab9b1f92868c2

From 476ccbddc23cf77d57ca8028365ab9b1f92868c2 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 29 Oct 2011 12:58:40 -0400
Subject: [PATCH] Separated dialog functionality from the look and feel.
 Functionality goes in screenlib, the look and feel is implemented in the
 MacDialog* classes.

---
 UIDialog.cpp => MacDialog.cpp                 | 84 ++--------------
 MacDialog.h                                   | 46 +++++++++
 UIDialogButton.cpp => MacDialogButton.cpp     | 81 +++------------
 MacDialogButton.h                             | 39 ++++++++
 UIDialogCheckbox.cpp => MacDialogCheckbox.cpp | 18 ++--
 UIDialogCheckbox.h => MacDialogCheckbox.h     | 12 +--
 UIDialogLabel.cpp => MacDialogLabel.cpp       |  6 +-
 UIDialogLabel.h => MacDialogLabel.h           | 10 +-
 MaelstromUI.cpp                               | 53 ++++++----
 MaelstromUI.h                                 |  2 +-
 Makefile.am                                   | 16 +--
 UI/UITemplates.xml                            |  4 +-
 UI/about_credits.xml                          |  4 +-
 UI/about_game.xml                             |  4 +-
 UI/about_story.xml                            |  4 +-
 UI/bonus.xml                                  |  4 +-
 UI/game.xml                                   |  4 +-
 UI/gameover.xml                               |  4 +-
 UI/loading.xml                                |  4 +-
 UI/main.xml                                   |  4 +-
 UI/splash.xml                                 |  4 +-
 UIDialogButton.h                              | 46 ---------
 main.cpp                                      |  2 +-
 screenlib/Makefile.am                         |  4 +
 screenlib/UIDialog.cpp                        | 98 +++++++++++++++++++
 UIDialog.h => screenlib/UIDialog.h            | 40 ++++----
 screenlib/UIDialogButton.cpp                  | 89 +++++++++++++++++
 screenlib/UIDialogButton.h                    | 59 +++++++++++
 screenlib/UIManager.cpp                       | 34 -------
 screenlib/UIManager.h                         | 13 ++-
 30 files changed, 478 insertions(+), 314 deletions(-)
 rename UIDialog.cpp => MacDialog.cpp (57%)
 create mode 100644 MacDialog.h
 rename UIDialogButton.cpp => MacDialogButton.cpp (67%)
 create mode 100644 MacDialogButton.h
 rename UIDialogCheckbox.cpp => MacDialogCheckbox.cpp (67%)
 rename UIDialogCheckbox.h => MacDialogCheckbox.h (66%)
 rename UIDialogLabel.cpp => MacDialogLabel.cpp (53%)
 rename UIDialogLabel.h => MacDialogLabel.h (64%)
 delete mode 100644 UIDialogButton.h
 create mode 100644 screenlib/UIDialog.cpp
 rename UIDialog.h => screenlib/UIDialog.h (63%)
 create mode 100644 screenlib/UIDialogButton.cpp
 create mode 100644 screenlib/UIDialogButton.h

diff --git a/UIDialog.cpp b/MacDialog.cpp
similarity index 57%
rename from UIDialog.cpp
rename to MacDialog.cpp
index da106dc2..43998a67 100644
--- a/UIDialog.cpp
+++ b/MacDialog.cpp
@@ -1,20 +1,17 @@
 
 #include "screenlib/SDL_FrameBuf.h"
-#include "screenlib/UIManager.h"
 
-#include "UIDialog.h"
+#include "MacDialog.h"
 
 #define EXPAND_STEPS 30
 
 
-UIElementType UIDialog::s_elementType;
+UIElementType MacDialog::s_elementType;
 
 
-UIDialog::UIDialog(UIManager *ui, const char *name) :
-	UIPanel(ui, name)
+MacDialog::MacDialog(UIManager *ui, const char *name) :
+	UIDialog(ui, name)
 {
-	m_fullscreen = false;
-
 	m_colors[COLOR_BLACK] = m_screen->MapRGB(0x00, 0x00, 0x00);
 	m_colors[COLOR_DARK] = m_screen->MapRGB(0x66, 0x66, 0x99);
 	m_colors[COLOR_MEDIUM] = m_screen->MapRGB(0xBB, 0xBB, 0xBB);
@@ -22,19 +19,12 @@ UIDialog::UIDialog(UIManager *ui, const char *name) :
 	m_colors[COLOR_WHITE] = m_screen->MapRGB(0xFF, 0xFF, 0xFF);
 	m_expand = true;
 	m_step = 0;
-	m_status = 0;
-	m_handleInit = NULL;
-	m_handleDone = NULL;
-}
-
-UIDialog::~UIDialog()
-{
 }
 
 bool
-UIDialog::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
+MacDialog::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
 {
-	if (!UIPanel::Load(node, templates)) {
+	if (!UIDialog::Load(node, templates)) {
 		return false;
 	}
 
@@ -44,34 +34,19 @@ UIDialog::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
 }
 
 void
-UIDialog::Show()
+MacDialog::Show()
 {
 	if (m_expand) {
 		m_step = 0;
 	} else {
 		m_step = EXPAND_STEPS;
 	}
-	m_status = 0;
 
-	if (m_handleInit) {
-		m_handleInit(this);
-	}
-
-	UIPanel::Show();
+	UIDialog::Show();
 }
 
 void
-UIDialog::Hide()
-{
-	UIPanel::Hide();
-
-	if (m_handleDone) {
-		m_handleDone(this, m_status);
-	}
-}
-
-void
-UIDialog::Draw()
+MacDialog::Draw()
 {
 	int x, y, w, h;
 	int maxx, maxy;
@@ -115,44 +90,5 @@ UIDialog::Draw()
 		return;
 	}
 
-	UIPanel::Draw();
-}
-
-bool
-UIDialog::HandleEvent(const SDL_Event &event)
-{
-	if (UIPanel::HandleEvent(event)) {
-		return true;
-	}
-
-	if (event.type != SDL_QUIT) {
-		/* Press escape to cancel out of dialogs */
-		if (event.type == SDL_KEYUP &&
-		    event.key.keysym.sym == SDLK_ESCAPE) {
-			GetUI()->HidePanel(GetUI()->GetCurrentPanel());
-		}
-		return true;
-	}
-	return false;
-}
-
-UIDialogLauncher::UIDialogLauncher(UIManager *ui, const char *name, UIDialogInitHandler handleInit, UIDialogDoneHandler handleDone)
-{
-	m_ui = ui;
-	m_name = name;
-	m_handleInit = handleInit;
-	m_handleDone = handleDone;
-}
-
-void
-UIDialogLauncher::OnClick()
-{
-	UIDialog *dialog;
-
-	dialog = m_ui->GetPanel<UIDialog>(m_name);
-	if (dialog) {
-		dialog->SetDialogHandlers(m_handleInit, m_handleDone);
-
-		m_ui->ShowPanel(dialog);
-	}
+	UIDialog::Draw();
 }
diff --git a/MacDialog.h b/MacDialog.h
new file mode 100644
index 00000000..aab4ffbe
--- /dev/null
+++ b/MacDialog.h
@@ -0,0 +1,46 @@
+
+#ifndef _MacDialog_h
+#define _MacDialog_h
+
+#include "screenlib/UIDialog.h"
+
+class MacDialog : public UIDialog
+{
+public:
+	MacDialog(UIManager *ui, const char *name);
+
+	virtual bool IsA(UIElementType type) {
+		return UIDialog::IsA(type) || type == GetType();
+	}
+
+	virtual bool Load(rapidxml::xml_node<> *node, const UITemplates *templates);
+
+	virtual void Show();
+	virtual void Draw();
+
+protected:
+	enum {
+		COLOR_BLACK,
+		COLOR_DARK,
+		COLOR_MEDIUM,
+		COLOR_LIGHT,
+		COLOR_WHITE,
+		NUM_COLORS
+	};
+	Uint32 m_colors[NUM_COLORS];
+	bool m_expand;
+	int m_step;
+
+protected:
+	static UIElementType s_elementType;
+
+public:
+	static UIElementType GetType() {
+		if (!s_elementType) {
+			s_elementType = GenerateType();
+		}
+		return s_elementType;
+	}
+};
+
+#endif // _MacDialog_h
diff --git a/UIDialogButton.cpp b/MacDialogButton.cpp
similarity index 67%
rename from UIDialogButton.cpp
rename to MacDialogButton.cpp
index 1b655a3e..687dd3f1 100644
--- a/UIDialogButton.cpp
+++ b/MacDialogButton.cpp
@@ -1,68 +1,27 @@
 
 #include "screenlib/SDL_FrameBuf.h"
-#include "screenlib/UIManager.h"
-#include "UIDialog.h"
-#include "UIDialogButton.h"
-#include "UIDialogLabel.h"
+#include "screenlib/UIElementLabel.h"
+#include "MacDialogButton.h"
 
 /* Default dialog button size */
 #define BUTTON_WIDTH	75
 #define BUTTON_HEIGHT	19
 
 
-UIElementType UIDialogButton::s_elementType;
+UIElementType MacDialogButton::s_elementType;
 
 
-UIDialogButton::UIDialogButton(UIBaseElement *parent, const char *name) :
-	UIElementButton(parent, name)
+MacDialogButton::MacDialogButton(UIBaseElement *parent, const char *name) :
+	UIDialogButton(parent, name)
 {
-	m_statusID = 0;
-	m_default = false;
-	m_closeDialog = true;
-
 	m_colors[0] = m_screen->MapRGB(0xFF, 0xFF, 0xFF);
 	m_colors[1] = m_screen->MapRGB(0x00, 0x00, 0x00);
 
 	SetSize(BUTTON_WIDTH, BUTTON_HEIGHT);
 }
 
-UIDialogButton::~UIDialogButton()
-{
-}
-
-bool
-UIDialogButton::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
-{
-	rapidxml::xml_attribute<> *attr;
-
-	if (!UIElementButton::Load(node, templates)) {
-		return false;
-	}
-
-	LoadNumber(node, "id", m_statusID);
-
-	LoadBool(node, "default", m_default);
-	if (m_default) {
-		m_hotkey = SDLK_RETURN;
-	}
-
-	LoadBool(node, "closeDialog", m_closeDialog);
-
-	attr = node->first_attribute("text", 0, false);
-	if (attr) {
-		UIDialogLabel *label;
-
-		label = new UIDialogLabel(this, "label");
-		label->SetText(attr->value());
-		label->SetTextColor(m_colors[1]);
-		AddElement(label);
-	}
-
-	return true;
-}
-
 void
-UIDialogButton::Draw()
+MacDialogButton::Draw()
 {
 	Uint32 bg, fg;
 	int x, y, maxx, maxy;
@@ -136,43 +95,27 @@ UIDialogButton::Draw()
 		m_screen->DrawLine(x+5, maxy, maxx-5, maxy, fg);
 	}
 
-	UIElementButton::Draw();
+	UIDialogButton::Draw();
 }
 
 void
-UIDialogButton::OnMouseDown()
+MacDialogButton::OnMouseDown()
 {
 	SetElementColor(m_colors[0]);
 
-	UIElementButton::OnMouseDown();
+	UIDialogButton::OnMouseDown();
 }
 
 void
-UIDialogButton::OnMouseUp()
+MacDialogButton::OnMouseUp()
 {
 	SetElementColor(m_colors[1]);
 
-	UIElementButton::OnMouseUp();
-}
-
-void
-UIDialogButton::OnClick()
-{
-	UIElementButton::OnClick();
-
-	if (m_statusID) {
-		UIPanel *panel = GetUI()->GetCurrentPanel();
-		if (panel->IsA(UIDialog::GetType())) {
-			static_cast<UIDialog*>(panel)->SetDialogStatus(m_statusID);
-		}
-	}
-	if (m_closeDialog) {
-		GetUI()->HidePanel(GetUI()->GetCurrentPanel());
-	}
+	UIDialogButton::OnMouseUp();
 }
 
 void
-UIDialogButton::SetElementColor(Uint32 color)
+MacDialogButton::SetElementColor(Uint32 color)
 {
 	Uint8 R, G, B;
 
diff --git a/MacDialogButton.h b/MacDialogButton.h
new file mode 100644
index 00000000..5f235d67
--- /dev/null
+++ b/MacDialogButton.h
@@ -0,0 +1,39 @@
+#ifndef _MacDialogButton_h
+#define _MacDialogButton_h
+
+#include "screenlib/UIDialogButton.h"
+
+
+class MacDialogButton : public UIDialogButton
+{
+public:
+	MacDialogButton(UIBaseElement *parent, const char *name = "");
+
+	virtual bool IsA(UIElementType type) {
+		return UIDialogButton::IsA(type) || type == GetType();
+	}
+
+	virtual void Draw();
+
+	virtual void OnMouseDown();
+	virtual void OnMouseUp();
+
+protected:
+	Uint32 m_colors[2];
+
+protected:
+	void SetElementColor(Uint32 color);
+
+protected:
+	static UIElementType s_elementType;
+
+public:
+	static UIElementType GetType() {
+		if (!s_elementType) {
+			s_elementType = GenerateType();
+		}
+		return s_elementType;
+	}
+};
+
+#endif // _MacDialogButton_h
diff --git a/UIDialogCheckbox.cpp b/MacDialogCheckbox.cpp
similarity index 67%
rename from UIDialogCheckbox.cpp
rename to MacDialogCheckbox.cpp
index 5017ab20..46876a69 100644
--- a/UIDialogCheckbox.cpp
+++ b/MacDialogCheckbox.cpp
@@ -1,16 +1,16 @@
 
 #include "screenlib/SDL_FrameBuf.h"
-#include "UIDialogCheckbox.h"
-#include "UIDialogLabel.h"
+#include "MacDialogCheckbox.h"
+#include "MacDialogLabel.h"
 
 /* Default checkbox size */
 #define CHECKBOX_SIZE	12
 
 
-UIElementType UIDialogCheckbox::s_elementType;
+UIElementType MacDialogCheckbox::s_elementType;
 
 
-UIDialogCheckbox::UIDialogCheckbox(UIBaseElement *parent, const char *name) :
+MacDialogCheckbox::MacDialogCheckbox(UIBaseElement *parent, const char *name) :
 	UIElementCheckbox(parent, name)
 {
 	m_color = m_screen->MapRGB(0x00, 0x00, 0x00);
@@ -18,12 +18,12 @@ UIDialogCheckbox::UIDialogCheckbox(UIBaseElement *parent, const char *name) :
 	SetSize(CHECKBOX_SIZE, CHECKBOX_SIZE);
 }
 
-UIDialogCheckbox::~UIDialogCheckbox()
+MacDialogCheckbox::~MacDialogCheckbox()
 {
 }
 
 bool
-UIDialogCheckbox::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
+MacDialogCheckbox::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
 {
 	rapidxml::xml_attribute<> *attr;
 
@@ -33,9 +33,9 @@ UIDialogCheckbox::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
 
 	attr = node->first_attribute("text", 0, false);
 	if (attr) {
-		UIDialogLabel *label;
+		MacDialogLabel *label;
 
-		label = new UIDialogLabel(this, "label");
+		label = new MacDialogLabel(this, "label");
 		label->SetText(attr->value());
 		label->SetTextColor(m_color);
 		label->SetAnchor(TOPLEFT, TOPRIGHT, this, 3, -2);
@@ -46,7 +46,7 @@ UIDialogCheckbox::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
 }
 
 void
-UIDialogCheckbox::Draw()
+MacDialogCheckbox::Draw()
 {
 	m_screen->DrawRect(X(), Y(), Width(), Height(), m_color);
 
diff --git a/UIDialogCheckbox.h b/MacDialogCheckbox.h
similarity index 66%
rename from UIDialogCheckbox.h
rename to MacDialogCheckbox.h
index fb6943eb..eb6bc6ac 100644
--- a/UIDialogCheckbox.h
+++ b/MacDialogCheckbox.h
@@ -1,14 +1,14 @@
-#ifndef _UIDialogCheckbox_h
-#define _UIDialogCheckbox_h
+#ifndef _MacDialogCheckbox_h
+#define _MacDialogCheckbox_h
 
 #include "screenlib/UIElementCheckbox.h"
 
 
-class UIDialogCheckbox : public UIElementCheckbox
+class MacDialogCheckbox : public UIElementCheckbox
 {
 public:
-	UIDialogCheckbox(UIBaseElement *parent, const char *name = "");
-	virtual ~UIDialogCheckbox();
+	MacDialogCheckbox(UIBaseElement *parent, const char *name = "");
+	virtual ~MacDialogCheckbox();
 
 	virtual bool IsA(UIElementType type) {
 		return UIElementCheckbox::IsA(type) || type == GetType();
@@ -33,4 +33,4 @@ class UIDialogCheckbox : public UIElementCheckbox
 	}
 };
 
-#endif // _UIDialogCheckbox_h
+#endif // _MacDialogCheckbox_h
diff --git a/UIDialogLabel.cpp b/MacDialogLabel.cpp
similarity index 53%
rename from UIDialogLabel.cpp
rename to MacDialogLabel.cpp
index 75867aae..97f9491d 100644
--- a/UIDialogLabel.cpp
+++ b/MacDialogLabel.cpp
@@ -1,11 +1,11 @@
 
-#include "UIDialogLabel.h"
+#include "MacDialogLabel.h"
 #include "Maelstrom_Globals.h"
 
-UIElementType UIDialogLabel::s_elementType;
+UIElementType MacDialogLabel::s_elementType;
 
 
-UIDialogLabel::UIDialogLabel(UIBaseElement *parent, const char *name) :
+MacDialogLabel::MacDialogLabel(UIBaseElement *parent, const char *name) :
 	UIElementLabel(parent, name)
 {
 	m_fontName = SDL_strdup("Chicago");
diff --git a/UIDialogLabel.h b/MacDialogLabel.h
similarity index 64%
rename from UIDialogLabel.h
rename to MacDialogLabel.h
index eba42599..9c737415 100644
--- a/UIDialogLabel.h
+++ b/MacDialogLabel.h
@@ -1,12 +1,12 @@
-#ifndef _UIDialogLabel_h
-#define _UIDialogLabel_h
+#ifndef _MacDialogLabel_h
+#define _MacDialogLabel_h
 
 #include "screenlib/UIElementLabel.h"
 
-class UIDialogLabel : public UIElementLabel
+class MacDialogLabel : public UIElementLabel
 {
 public:
-	UIDialogLabel(UIBaseElement *parent, const char *name = "");
+	MacDialogLabel(UIBaseElement *parent, const char *name = "");
 
 	virtual bool IsA(UIElementType type) {
 		return UIElementLabel::IsA(type) || type == GetType();
@@ -24,4 +24,4 @@ class UIDialogLabel : public UIElementLabel
 	}
 };
 
-#endif // _UIDialogLabel_h
+#endif // _MacDialogLabel_h
diff --git a/MaelstromUI.cpp b/MaelstromUI.cpp
index c4b3c25f..1d14ba0a 100644
--- a/MaelstromUI.cpp
+++ b/MaelstromUI.cpp
@@ -1,18 +1,23 @@
 
 #include "MaelstromUI.h"
 #include "Maelstrom_Globals.h"
-#include "UIDialog.h"
 #include "main.h"
 #include "netlogic/about.h"
 #include "netlogic/game.h"
-#include "utils/hashtable.h"
-#include "UIDialogButton.h"
-#include "UIDialogCheckbox.h"
-#include "UIDialogLabel.h"
+#include "MacDialog.h"
+#include "MacDialogButton.h"
+#include "MacDialogCheckbox.h"
+#include "MacDialogLabel.h"
 #include "UIElementIcon.h"
 #include "UIElementKeyButton.h"
 #include "UIElementSprite.h"
 #include "UIElementTitle.h"
+#include "screenlib/UIElementButton.h"
+#include "screenlib/UIElementCheckbox.h"
+#include "screenlib/UIElementLine.h"
+#include "screenlib/UIElementRadio.h"
+#include "screenlib/UIElementRect.h"
+#include "utils/hashtable.h"
 
 
 static void
@@ -136,8 +141,10 @@ MaelstromUI::PlaySound(int soundID)
 UIPanel *
 MaelstromUI::CreatePanel(const char *type, const char *name)
 {
-	if (strcasecmp(type, "Dialog") == 0) {
-		return new UIDialog(ui, name);
+	if (strcasecmp(type, "Panel") == 0) {
+		return new UIPanel(this, name);
+	} else if (strcasecmp(type, "Dialog") == 0) {
+		return new MacDialog(ui, name);
 	}
 	return UIManager::CreatePanel(type, name);
 }
@@ -156,24 +163,34 @@ MaelstromUI::CreatePanelDelegate(UIPanel *panel, const char *delegate)
 }
 
 UIElement *
-MaelstromUI::CreateElement(UIBaseElement *parent, const char *type)
+MaelstromUI::CreateElement(UIBaseElement *parent, const char *type, const char *name)
 {
-	if (strcasecmp(type, "Label") == 0) {
-		return new UIElementLabel(parent);
+	if (strcasecmp(type, "Line") == 0) {
+		return new UIElementLine(parent, name);
+	} else if (strcasecmp(type, "Rectangle") == 0) {
+		return new UIElementRect(parent, name);
+	} else if (strcasecmp(type, "Label") == 0) {
+		return new UIElementLabel(parent, name);
+	} else if (strcasecmp(type, "Button") == 0) {
+		return new UIElementButton(parent, name);
 	} else if (strcasecmp(type, "DialogLabel") == 0) {
-		return new UIDialogLabel(parent);
+		return new MacDialogLabel(parent, name);
 	} else if (strcasecmp(type, "DialogButton") == 0) {
-		return new UIDialogButton(parent);
+		return new MacDialogButton(parent, name);
 	} else if (strcasecmp(type, "DialogCheckbox") == 0) {
-		return new UIDialogCheckbox(parent);
+		return new MacDialogCheckbox(parent, name);
+	} else if (strcasecmp(type, "DialogRadioGroup") == 0) {
+		return new UIElementRadioGroup(parent, name);
+	} else if (strcasecmp(type, "DialogRadioButton") == 0) {
+		return new UIElementRadioButton(parent, name);
 	} else if (strcasecmp(type, "KeyButton") == 0) {
-		return new UIElementKeyButton(parent);
+		return new UIElementKeyButton(parent, name);
 	} else if (strcasecmp(type, "Icon") == 0) {
-		return new UIElementIcon(parent);
+		return new UIElementIcon(parent, name);
 	} else if (strcasecmp(type, "Sprite") == 0) {
-		return new UIElementSprite(parent);
+		return new UIElementSprite(parent, name);
 	} else if (strcasecmp(type, "Title") == 0) {
-		return new UIElementTitle(parent);
+		return new UIElementTitle(parent, name);
 	}
-	return UIManager::CreateElement(parent, type);;
+	return UIManager::CreateElement(parent, name, type);;
 }
diff --git a/MaelstromUI.h b/MaelstromUI.h
index 68562299..bf883ae6 100644
--- a/MaelstromUI.h
+++ b/MaelstromUI.h
@@ -25,7 +25,7 @@ class MaelstromUI : public UIManager
 	//
 	virtual UIPanel *CreatePanel(const char *type, const char *name);
 	virtual UIPanelDelegate *CreatePanelDelegate(UIPanel *panel, const char *delegate);
-	virtual UIElement *CreateElement(UIBaseElement *parent, const char *type);
+	virtual UIElement *CreateElement(UIBaseElement *parent, const char *type, const char *name);
 
 protected:
 	HashTable *m_fonts;
diff --git a/Makefile.am b/Makefile.am
index 8534756b..eb1c70e3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -32,14 +32,14 @@ Maelstrom_SOURCES =		\
 	rect.h			\
 	scores.cpp		\
 	scores.h		\
-	UIDialog.cpp		\
-	UIDialog.h		\
-	UIDialogButton.cpp	\
-	UIDialogButton.h	\
-	UIDialogCheckbox.cpp	\
-	UIDialogCheckbox.h	\
-	UIDialogLabel.cpp	\
-	UIDialogLabel.h		\
+	MacDialog.cpp		\
+	MacDialog.h		\
+	MacDialogButton.cpp	\
+	MacDialogButton.h	\
+	MacDialogCheckbox.cpp	\
+	MacDialogCheckbox.h	\
+	MacDialogLabel.cpp	\
+	MacDialogLabel.h		\
 	UIElementIcon.cpp	\
 	UIElementIcon.h		\
 	UIElementKeyButton.cpp	\
diff --git a/UI/UITemplates.xml b/UI/UITemplates.xml
index ddc3801c..eb357f63 100644
--- a/UI/UITemplates.xml
+++ b/UI/UITemplates.xml
@@ -1,5 +1,5 @@
 <UITemplates>
-	<UIPanel templateName="FramedPanel">
+	<Panel templateName="FramedPanel">
 		<Elements>
 			<Rectangle>
 				<Color r="0x75" g="0x75" b="0xFF"/>
@@ -30,7 +30,7 @@
 				<Size w="526" h="398"/>
 			</Rectangle>
 		</Elements>
-	</UIPanel>
+	</Panel>
 
 	<Label templateName="Small" fontName="Geneva" fontSize="9" fontStyle="BOLD"/>
 	<Label templateName="SmallWhite" template="Small">
diff --git a/UI/about_credits.xml b/UI/about_credits.xml
index aa776c56..0b89cc08 100644
--- a/UI/about_credits.xml
+++ b/UI/about_credits.xml
@@ -1,4 +1,4 @@
-<UIPanel template="FramedPanel">
+<Panel template="FramedPanel">
 	<Elements>
 		<Title name="image" id="135"/>
 
@@ -19,4 +19,4 @@
 		<!-- Buttons -->
 		<Button hotkey="any" clickPanel="main" clickSound="131"/>
 	</Elements>
-</UIPanel>
+</Panel>
diff --git a/UI/about_game.xml b/UI/about_game.xml
index 194c7b99..0e9b2f39 100644
--- a/UI/about_game.xml
+++ b/UI/about_game.xml
@@ -1,4 +1,4 @@
-<UIPanel template="FramedPanel" delegate="AboutPanel">
+<Panel template="FramedPanel" delegate="AboutPanel">
 	<Elements>
 		<Title name="image" id="134"/>
 
@@ -31,4 +31,4 @@
 		<Button hotkey="any" clickPanel="main" clickSound="106"/>
 		<Button hotkey="Return" clickPanel="about_credits" clickSound="102"/>
 	</Elements>
-</UIPanel>
+</Panel>
diff --git a/UI/about_story.xml b/UI/about_story.xml
index a75d52c9..af85af29 100644
--- a/UI/about_story.xml
+++ b/UI/about_story.xml
@@ -1,4 +1,4 @@
-<UIPanel template="FramedPanel">
+<Panel template="FramedPanel">
 	<Elements>
 		<Title name="image" id="133"/>
 
@@ -6,4 +6,4 @@
 		<Button hotkey="any" clickPanel="main" clickSound="106"/>
 		<Button hotkey="Return" clickPanel="about_game" clickSound="102"/>
 	</Elements>
-</UIPanel>
+</Panel>
diff --git a/UI/bonus.xml b/UI/bonus.xml
index 39b595ca..b8b133ce 100644
--- a/UI/bonus.xml
+++ b/UI/bonus.xml
@@ -1,4 +1,4 @@
-<UIPanel fullscreen="false" enterSound="110">
+<Panel fullscreen="false" enterSound="110">
 	<Elements>
 		<Label name="wave" template="SmallYellow">
 			<Anchor anchorFrom="TOP" anchorTo="CENTER" y="-90"/>
@@ -35,4 +35,4 @@
 			<Anchor anchorFrom="TOP" anchorTo="TOP" anchor="wave" y="109"/>
 		</Label>
 	</Elements>
-</UIPanel>
+</Panel>
diff --git a/UI/game.xml b/UI/game.xml
index 73098346..a308a299 100644
--- a/UI/game.xml
+++ b/UI/game.xml
@@ -1,4 +1,4 @@
-<UIPanel cursor="false" delegate="GamePanel">
+<Panel cursor="false" delegate="GamePanel">
 	<Elements>
 		<!-- Status display -->
 		<Line name="status_line">
@@ -93,4 +93,4 @@
 			<Anchor anchorFrom="LEFT" anchorTo="RIGHT" anchor="frags_label" x="4"/>
 		</Label>
 	</Elements>
-</UIPanel>
+</Panel>
diff --git a/UI/gameover.xml b/UI/gameover.xml
index 40537cf6..0d789f83 100644
--- a/UI/gameover.xml
+++ b/UI/gameover.xml
@@ -1,4 +1,4 @@
-<UIPanel cursor="false" enterSound="113">
+<Panel cursor="false" enterSound="113">
 	<Elements>
 		<Title name="image" id="128">
 			<Anchor anchorFrom="CENTER" anchorTo="CENTER" y="-80"/>
@@ -22,4 +22,4 @@
 			<Anchor anchorFrom="LEFT" anchorTo="RIGHT" anchor="name_label"/>
 		</Label>
 	</Elements>
-</UIPanel>
+</Panel>
diff --git a/UI/loading.xml b/UI/loading.xml
index 5b6add2a..80c01180 100644
--- a/UI/loading.xml
+++ b/UI/loading.xml
@@ -1,4 +1,4 @@
-<UIPanel template="FramedPanel" enterSound="111" leaveSound="123">
+<Panel template="FramedPanel" enterSound="111" leaveSound="123">
 	<Elements>
 		<Title name="image" id="130"/>
 
@@ -28,4 +28,4 @@
 			<Anchor anchorFrom="LEFT" anchorTo="CENTER" x="-98" y="185"/>
 		</Rectangle>
 	</Elements>
-</UIPanel>
+</Panel>
diff --git a/UI/main.xml b/UI/main.xml
index 7032ede9..5335d8c0 100644
--- a/UI/main.xml
+++ b/UI/main.xml
@@ -1,4 +1,4 @@
-<UIPanel template="FramedPanel" delegate="MainPanel">
+<Panel template="FramedPanel" delegate="MainPanel">
 	<Elements>
 		<Title name="image" id="129">
 			<Anchor anchorFrom="TOPLEFT" anchorTo="CENTER" x="-251" y="-187"/>
@@ -209,4 +209,4 @@
 			<Anchor anchorFrom="BOTTOMLEFT" anchorTo="TOPLEFT" anchor="VolumeDownButton" x="-6" y="22"/>
 		</Label>
 	</Elements>
-</UIPanel>
+</Panel>
diff --git a/UI/splash.xml b/UI/splash.xml
index 8b8e1a3c..f845f1c7 100644
--- a/UI/splash.xml
+++ b/UI/splash.xml
@@ -1,5 +1,5 @@
-<UIPanel>
+<Panel>
 	<Elements>
 		<Title id="999"/>
 	</Elements>
-</UIPanel>
+</Panel>
diff --git a/UIDialogButton.h b/UIDialogButton.h
deleted file mode 100644
index 757617b4..00000000
--- a/UIDialogButton.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef _UIDialogButton_h
-#define _UIDialogButton_h
-
-#include "screenlib/UIElementButton.h"
-
-
-class UIDialogButton : public UIElementButton
-{
-public:
-	UIDialogButton(UIBaseElement *parent, const char *name = "");
-	virtual ~UIDialogButton();
-
-	virtual bool IsA(UIElementType type) {
-		return UIElementButton::IsA(type) || type == GetType();
-	}
-
-	virtual bool Load(rapidxml::xml_node<> *node, const UITemplates *templates);
-
-	virtual void Draw();
-
-	virtual void OnMouseDown();
-	virtual void OnMouseUp();
-	virtual void OnClick();
-
-protected:
-	Uint32 m_colors[2];
-	int m_statusID;
-	bool m_default;
-	bool m_closeDialog;
-
-protected:
-	void SetElementColor(Uint32 color);
-
-protected:
-	static UIElementType s_elementType;
-
-public:
-	static UIElementType GetType() {
-		if (!s_elementType) {
-			s_elementType = GenerateType();
-		}
-		return s_elementType;
-	}
-};
-
-#endif // _UIDialogButton_h
diff --git a/main.cpp b/main.cpp
index f45e97dc..a73ccead 100644
--- a/main.cpp
+++ b/main.cpp
@@ -18,7 +18,7 @@
 #include "main.h"
 
 #include "screenlib/UIElementLabel.h"
-#include "UIDialog.h"
+#include "screenlib/UIDialog.h"
 #include "UIElementKeyButton.h"
 
 /* External functions used in this file */
diff --git a/screenlib/Makefile.am b/screenlib/Makefile.am
index c9558dc5..cd66cabe 100644
--- a/screenlib/Makefile.am
+++ b/screenlib/Makefile.am
@@ -9,6 +9,10 @@ libSDLscreen_a_SOURCES =	\
 	UIArea.h		\
 	UIBaseElement.cpp	\
 	UIBaseElement.h		\
+	UIDialog.cpp		\
+	UIDialog.h		\
+	UIDialogButton.cpp	\
+	UIDialogButton.h	\
 	UIElement.cpp		\
 	UIElement.h		\
 	UIElementButton.cpp	\
diff --git a/screenlib/UIDialog.cpp b/screenlib/UIDialog.cpp
new file mode 100644
index 00000000..9bb08051
--- /dev/null
+++ b/screenlib/UIDialog.cpp
@@ -0,0 +1,98 @@
+/*
+    SCREENLIB:  A framebuffer library based on the SDL library
+    Copyright (C) 1997  Sam Lantinga
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+#include "SDL_FrameBuf.h"
+#include "UIManager.h"
+#include "UIDialog.h"
+
+UIElementType UIDialog::s_elementType;
+
+
+UIDialog::UIDialog(UIManager *ui, const char *name) :
+	UIPanel(ui, name)
+{
+	m_fullscreen = false;
+	m_status = 0;
+	m_handleInit = NULL;
+	m_handleDone = NULL;
+}
+
+void
+UIDialog::Show()
+{
+	m_status = 0;
+
+	if (m_handleInit) {
+		m_handleInit(this);
+	}
+
+	UIPanel::Show();
+}
+
+void
+UIDialog::Hide()
+{
+	UIPanel::Hide();
+
+	if (m_handleDone) {
+		m_handleDone(this, m_status);
+	}
+}
+
+bool
+UIDialog::HandleEvent(const SDL_Event &event)
+{
+	if (UIPanel::HandleEvent(event)) {
+		return true;
+	}
+
+	if (event.type != SDL_QUIT) {
+		/* Press escape to cancel out of dialogs */
+		if (event.type == SDL_KEYUP &&
+		    event.key.keysym.sym == SDLK_ESCAPE) {
+			GetUI()->HidePanel(GetUI()->GetCurrentPanel());
+		}
+		return true;
+	}
+	return false;
+}
+
+UIDialogLauncher::UIDialogLauncher(UIManager *ui, const char *name, UIDialogInitHandler handleInit, UIDialogDoneHandler handleDone)
+{
+	m_ui = ui;
+	m_name = name;
+	m_handleInit = handleInit;
+	m_handleDone = handleDone;
+}
+
+void
+UIDialogLauncher::OnClick()
+{
+	UIDialog *dialog;
+
+	dialog = m_ui->GetPanel<UIDialog>(m_name);
+	if (dialog) {
+		dialog->SetDialogHandlers(m_handleInit, m_handleDone);
+
+		m_ui->ShowPanel(dialog);
+	}
+}
diff --git a/UIDialog.h b/screenlib/UIDialog.h
similarity index 63%
rename from UIDialog.h
rename to screenlib/UIDialog.h
index 7b73612b..22bc79ee 100644
--- a/UIDialog.h
+++ b/screenlib/UIDialog.h
@@ -1,9 +1,30 @@
+/*
+    SCREENLIB:  A framebuffer library based on the SDL library
+    Copyright (C) 1997  Sam Lantinga
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
 
 #ifndef _UIDialog_h
 #define _UIDialog_h
 
-#include "screenlib/UIPanel.h"
-#include "screenlib/UIElementButton.h"
+#include "UIPanel.h"
+#include "UIElementButton.h"
 
 class UIDialog;
 
@@ -20,7 +41,6 @@ class UIDialog : public UIPanel
 {
 public:
 	UIDialog(UIManager *ui, const char *name);
-	virtual ~UIDialog();
 
 	virtual bool IsA(UIElementType type) {
 		return UIPanel::IsA(type) || type == GetType();
@@ -36,25 +56,11 @@ class UIDialog : public UIPanel
 		m_status = status;
 	}
 
-	virtual bool Load(rapidxml::xml_node<> *node, const UITemplates *templates);
-
 	virtual void Show();
 	virtual void Hide();
-	virtual void Draw();
 	virtual bool HandleEvent(const SDL_Event &event);
 
 protected:
-	enum {
-		COLOR_BLACK,
-		COLOR_DARK,
-		COLOR_MEDIUM,
-		COLOR_LIGHT,
-		COLOR_WHITE,
-		NUM_COLORS
-	};
-	Uint32 m_colors[NUM_COLORS];
-	bool m_expand;
-	int m_step;
 	int m_status;
 	UIDialogInitHandler m_handleInit;
 	UIDialogDoneHandler m_handleDone;
diff --git a/screenlib/UIDialogButton.cpp b/screenlib/UIDialogButton.cpp
new file mode 100644
index 00000000..67db7f65
--- /dev/null
+++ b/screenlib/UIDialogButton.cpp
@@ -0,0 +1,89 @@
+/*
+    SCREENLIB:  A framebuffer library based on the SDL library
+    Copyright (C) 1997  Sam Lantinga
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+#include "SDL_FrameBuf.h"
+#include "UIManager.h"
+#include "UIDialog.h"
+#include "UIDialogButton.h"
+#include "UIElementLabel.h"
+
+UIElementType UIDialogButton::s_elementType;
+
+
+UIDialogButton::UIDialogButton(UIBaseElement *parent, const char *name) :
+	UIElementButton(parent, name)
+{
+	m_statusID = 0;
+	m_default = false;
+	m_closeDialog = true;
+}
+
+bool
+UIDialogButton::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
+{
+	rapidxml::xml_attribute<> *attr;
+
+	if (!UIElementButton::Load(node, templates)) {
+		return false;
+	}
+
+	LoadNumber(node, "id", m_statusID);
+
+	LoadBool(node, "default", m_default);
+	if (m_default) {
+		m_hotkey = SDLK_RETURN;
+	}
+
+	LoadBool(node, "closeDialog", m_closeDialog);
+
+	attr = node->first_attribute("text", 0, false);
+	if (attr) {
+		UIElement *label;
+
+		label = GetUI()->CreateElement(this, "DialogLabel", "label");
+		if (label && label->IsA(UIElementLabel::GetType())) {
+			static_cast<UIElementLabel*>(label)->SetText(attr->value())

(Patch may be truncated, please check the link at the top of this post.)