Maelstrom: Added the concept of an expanding dialog panel

https://github.com/libsdl-org/Maelstrom/commit/752b4e93dc509d66c85e442545c51a51274097e9

From 752b4e93dc509d66c85e442545c51a51274097e9 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 28 Oct 2011 00:53:04 -0400
Subject: [PATCH] Added the concept of an expanding dialog panel

---
 Maelstrom_Globals.h |   3 +-
 Makefile.am         |   2 +
 UI/UITemplates.xml  |   3 ++
 UI/dawn.xml         |  27 +++++++++++
 UIDialog.cpp        | 110 ++++++++++++++++++++++++++++++++++++++++++++
 UIDialog.h          |  34 ++++++++++++++
 UIPanels.cpp        |   3 ++
 main.cpp            |   6 ++-
 screenlib/UIPanel.h |   4 +-
 9 files changed, 188 insertions(+), 4 deletions(-)
 create mode 100644 UI/dawn.xml
 create mode 100644 UIDialog.cpp
 create mode 100644 UIDialog.h

diff --git a/Maelstrom_Globals.h b/Maelstrom_Globals.h
index 61102f92..1fde751e 100644
--- a/Maelstrom_Globals.h
+++ b/Maelstrom_Globals.h
@@ -107,7 +107,8 @@ extern Bool	gNetScores;
 #define PANEL_BONUS	"bonus"
 #define PANEL_GAMEOVER	"gameover"
 #define PANEL_ABOUT	"about_story"
-#define PANEL_CONTROLS	"controls"
+#define DIALOG_CONTROLS	"controls"
+#define DIALOG_DAWN	"dawn"
 
 // Sound resource definitions...
 #define gShotSound	100
diff --git a/Makefile.am b/Makefile.am
index 45d72c40..4a15fd3e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -30,6 +30,8 @@ Maelstrom_SOURCES =		\
 	rect.h			\
 	scores.cpp		\
 	scores.h		\
+	UIDialog.cpp		\
+	UIDialog.h		\
 	UIElementIcon.cpp	\
 	UIElementIcon.h		\
 	UIElementKeyButton.cpp	\
diff --git a/UI/UITemplates.xml b/UI/UITemplates.xml
index 53b0c192..6cd414a0 100644
--- a/UI/UITemplates.xml
+++ b/UI/UITemplates.xml
@@ -75,4 +75,7 @@
 		<Color r="0xFF" g="0xFF" b="0x00"/>
 	</Label>
 
+	<Label templateName="Dialog" fontName="Chicago" fontSize="12">
+		<Color r="0x00" g="0x00" b="0x00"/>
+	</Label>
 </UITemplates>
diff --git a/UI/dawn.xml b/UI/dawn.xml
new file mode 100644
index 00000000..ad4891d3
--- /dev/null
+++ b/UI/dawn.xml
@@ -0,0 +1,27 @@
+<Dialog>
+	<Size w="318" h="194"/>
+	<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" x="160" y="73"/>
+	<Elements>
+		<Icon name="icon" id="103">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPLEFT" x="23" y="23"/>
+		</Icon>
+		<Label name="line1" template="Dialog" text="No eternal reward will forgive us">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="TOPRIGHT" anchor="icon" x="25"/>
+		</Label>
+		<Label name="line2" template="Dialog" text="now">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMLEFT" anchor="line1" y="2"/>
+		</Label>
+		<Label name="line3" template="Dialog" text="for">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMRIGHT" anchor="line2" x="2" y="2"/>
+		</Label>
+		<Label name="line4" template="Dialog" text="wasting">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMRIGHT" anchor="line3" x="2" y="2"/>
+		</Label>
+		<Label name="line5" template="Dialog" text="the">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMRIGHT" anchor="line4" x="2" y="2"/>
+		</Label>
+		<Label name="line6" template="Dialog" text="dawn.">
+			<Anchor anchorFrom="TOPLEFT" anchorTo="BOTTOMRIGHT" anchor="line5" x="2" y="2"/>
+		</Label>
+	</Elements>
+</Dialog>
diff --git a/UIDialog.cpp b/UIDialog.cpp
new file mode 100644
index 00000000..16ef73a1
--- /dev/null
+++ b/UIDialog.cpp
@@ -0,0 +1,110 @@
+
+#include "screenlib/SDL_FrameBuf.h"
+
+#include "UIDialog.h"
+
+#define EXPAND_STEPS 30
+
+
+UIDialog::UIDialog(UIManager *ui, const char *name) :
+	UIPanel(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);
+	m_colors[COLOR_LIGHT] = m_screen->MapRGB(0xCC, 0xCC, 0xFF);
+	m_colors[COLOR_WHITE] = m_screen->MapRGB(0xFF, 0xFF, 0xFF);
+	m_expand = true;
+	m_step = 0;
+}
+
+UIDialog::~UIDialog()
+{
+}
+
+bool
+UIDialog::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
+{
+	rapidxml::xml_attribute<> *attr;
+
+	if (!UIPanel::Load(node, templates)) {
+		return false;
+	}
+
+	attr = node->first_attribute("expand", 0, false);
+	if (attr) {
+		const char *value = attr->value();
+		if (*value == '0' || *value == 'f' || *value == 'F') {
+			m_expand = false;
+		} else {
+			m_expand = true;
+		}
+	}
+
+	return true;
+}
+
+void
+UIDialog::Show()
+{
+	if (m_expand) {
+		m_step = 0;
+	} else {
+		m_step = EXPAND_STEPS;
+	}
+}
+
+void
+UIDialog::Draw()
+{
+	int x, y, w, h;
+	int maxx, maxy;
+
+	if (m_step < EXPAND_STEPS) {
+		w = 8+((m_rect.w-8)*m_step)/EXPAND_STEPS;
+		h = 8+((m_rect.h-8)*m_step)/EXPAND_STEPS;
+		x = m_rect.x + m_rect.w/2 - (w/2);
+		y = m_rect.y + m_rect.h/2 - (h/2);
+	} else {
+		w = m_rect.w;
+		h = m_rect.h;
+		x = m_rect.x;
+		y = m_rect.y;
+	}
+	maxx = x+w-1;
+	maxy = y+h-1;
+
+	/* Draw the dialog border and background color */
+	m_screen->DrawLine(x, y, maxx, y, m_colors[COLOR_LIGHT]);
+	m_screen->DrawLine(x, y, x, maxy, m_colors[COLOR_LIGHT]);
+	m_screen->DrawLine(x, maxy, maxx, maxy, m_colors[COLOR_DARK]);
+	m_screen->DrawLine(maxx, y, maxx, maxy, m_colors[COLOR_DARK]);
+	m_screen->DrawRect(x+1, y+1, w-2, h-2, m_colors[COLOR_MEDIUM]);
+	m_screen->DrawLine(x+2, y+2, maxx-2, y+2, m_colors[COLOR_DARK]);
+	m_screen->DrawLine(x+2, y+2, x+2, maxy-2, m_colors[COLOR_DARK]);
+	m_screen->DrawLine(x+3, maxy-2, maxx-2, maxy-2, m_colors[COLOR_LIGHT]);
+	m_screen->DrawLine(maxx-2, y+3, maxx-2, maxy-2, m_colors[COLOR_LIGHT]);
+	m_screen->DrawRect(x+3, y+3, w-6, h-6, m_colors[COLOR_BLACK]);
+	m_screen->FillRect(x+4, y+4, w-8, h-8, m_colors[COLOR_WHITE]);
+
+	/* Don't draw the controls until we've finished expanding */
+	if (m_step < EXPAND_STEPS) {
+		++m_step;
+		return;
+	}
+
+	UIPanel::Draw();
+}
+
+bool
+UIDialog::HandleEvent(const SDL_Event &event)
+{
+	UIPanel::HandleEvent(event);
+
+	if (event.type != SDL_QUIT) {
+		return true;
+	}
+	return false;
+}
diff --git a/UIDialog.h b/UIDialog.h
new file mode 100644
index 00000000..3c2a6c8d
--- /dev/null
+++ b/UIDialog.h
@@ -0,0 +1,34 @@
+
+#ifndef _UIDialog_h
+#define _UIDialog_h
+
+#include "screenlib/UIPanel.h"
+
+
+class UIDialog : public UIPanel
+{
+public:
+	UIDialog(UIManager *ui, const char *name);
+	virtual ~UIDialog();
+
+	virtual bool Load(rapidxml::xml_node<> *node, const UITemplates *templates);
+
+	virtual void Show();
+	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;
+};
+
+#endif // _UIDialog_h
diff --git a/UIPanels.cpp b/UIPanels.cpp
index 986d6277..ff0a1c1d 100644
--- a/UIPanels.cpp
+++ b/UIPanels.cpp
@@ -1,6 +1,7 @@
 
 #include "screenlib/UIPanel.h"
 #include "UIPanels.h"
+#include "UIDialog.h"
 #include "main.h"
 #include "netlogic/about.h"
 #include "netlogic/game.h"
@@ -28,6 +29,8 @@ CreateMaelstromUIPanel(UIManager *ui, const char *type, const char *name, const
 
 	if (strcasecmp(type, "UIPanel") == 0) {
 		panel = new UIPanel(ui, name);
+	} else if (strcasecmp(type, "Dialog") == 0) {
+		panel = new UIDialog(ui, name);
 	} else {
 		panel = NULL;
 	}
diff --git a/main.cpp b/main.cpp
index 2603ee01..a32a2040 100644
--- a/main.cpp
+++ b/main.cpp
@@ -113,6 +113,10 @@ static void RunCheat(void)
 		NewGame();
 	}
 }
+static void RunShowDawn(void)
+{
+	ui->ShowPanel(DIALOG_DAWN);
+}
 static void RunScreenshot(void)
 {
 	screen->ScreenDump("ScoreDump", 64, 48, 298, 384);
@@ -396,7 +400,7 @@ MainPanelDelegate::OnLoad()
 	}
 	button = m_panel->GetElement<UIElementButton>("Special");
 	if (button) {
-		button->SetClickCallback(ShowDawn);
+		button->SetClickCallback(RunShowDawn);
 	}
 	button = m_panel->GetElement<UIElementButton>("Screenshot");
 	if (button) {
diff --git a/screenlib/UIPanel.h b/screenlib/UIPanel.h
index 9ba9dd9b..8fedeb6f 100644
--- a/screenlib/UIPanel.h
+++ b/screenlib/UIPanel.h
@@ -97,8 +97,8 @@ class UIPanel : public UIArea
 
 	void HideAll();
 
-	void Draw();
-	bool HandleEvent(const SDL_Event &event);
+	virtual void Draw();
+	virtual bool HandleEvent(const SDL_Event &event);
 
 protected:
 	UIManager *m_ui;