https://github.com/libsdl-org/Maelstrom/commit/9306d2609cefd0373620cc1306d531dfefb06aaa
From 9306d2609cefd0373620cc1306d531dfefb06aaa Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 28 Oct 2011 18:33:23 -0400
Subject: [PATCH] Made the UI manager an interface which games can implement to
extend the base functionality.
---
MaelstromUI.cpp | 84 ++++++++++++++++++++++++++++++++++++
MaelstromUI.h | 32 ++++++++++++++
Makefile.am | 8 ++--
UIElements.cpp | 37 ----------------
UIElements.h | 9 ----
UIPanels.cpp | 43 ------------------
UIPanels.h | 9 ----
init.cpp | 18 ++------
screenlib/Makefile.am | 2 +
screenlib/UIFontInterface.h | 42 ++++++++++++++++++
screenlib/UIManager.cpp | 77 ++++++++++++++++++++++++---------
screenlib/UIManager.h | 39 +++++------------
screenlib/UIPanel.cpp | 2 +-
screenlib/UISoundInterface.h | 32 ++++++++++++++
14 files changed, 268 insertions(+), 166 deletions(-)
create mode 100644 MaelstromUI.cpp
create mode 100644 MaelstromUI.h
delete mode 100644 UIElements.cpp
delete mode 100644 UIElements.h
delete mode 100644 UIPanels.cpp
delete mode 100644 UIPanels.h
create mode 100644 screenlib/UIFontInterface.h
create mode 100644 screenlib/UISoundInterface.h
diff --git a/MaelstromUI.cpp b/MaelstromUI.cpp
new file mode 100644
index 00000000..c160fafb
--- /dev/null
+++ b/MaelstromUI.cpp
@@ -0,0 +1,84 @@
+
+#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 "UIDialogLabel.h"
+#include "UIElementIcon.h"
+#include "UIElementKeyButton.h"
+#include "UIElementLabel.h"
+#include "UIElementSprite.h"
+#include "UIElementTitle.h"
+
+
+MaelstromUI::MaelstromUI(FrameBuf *screen) : UIManager(screen)
+{
+ /* Load up our UI templates */
+ SetLoadPath("UI");
+ LoadTemplates("UITemplates.xml");
+}
+
+MaelstromUI::~MaelstromUI()
+{
+}
+
+SDL_Texture *
+MaelstromUI::CreateText(const char *text, const char *fontName, int fontSize, UIFontStyle fontStyle)
+{
+}
+
+void
+MaelstromUI::FreeText(SDL_Texture *texture)
+{
+ fontserv->FreeText(texture);
+}
+
+void
+MaelstromUI::PlaySound(int soundID)
+{
+ sound->PlaySound(soundID, 5);
+}
+
+UIPanel *
+MaelstromUI::CreatePanel(const char *type, const char *name)
+{
+ if (strcasecmp(type, "Dialog") == 0) {
+ return new UIDialog(ui, name);
+ }
+ return UIManager::CreatePanel(type, name);
+}
+
+UIPanelDelegate *
+MaelstromUI::CreatePanelDelegate(UIPanel *panel, const char *delegate)
+{
+ if (strcasecmp(delegate, "MainPanel") == 0) {
+ return new MainPanelDelegate(panel);
+ } else if (strcasecmp(delegate, "AboutPanel") == 0) {
+ return new AboutPanelDelegate(panel);
+ } else if (strcasecmp(delegate, "GamePanel") == 0) {
+ return new GamePanelDelegate(panel);
+ }
+ return UIManager::CreatePanelDelegate(panel, delegate);
+}
+
+UIElement *
+MaelstromUI::CreateElement(UIPanel *panel, const char *type)
+{
+ if (strcasecmp(type, "Label") == 0) {
+ return new UIElementLabel(panel);
+ } else if (strcasecmp(type, "DialogLabel") == 0) {
+ return new UIDialogLabel(panel);
+ } else if (strcasecmp(type, "KeyButton") == 0) {
+ return new UIElementKeyButton(panel);
+ } else if (strcasecmp(type, "Icon") == 0) {
+ return new UIElementIcon(panel);
+ } else if (strcasecmp(type, "Sprite") == 0) {
+ return new UIElementSprite(panel);
+ } else if (strcasecmp(type, "Title") == 0) {
+ return new UIElementTitle(panel);
+ }
+ return UIManager::CreateElement(panel, type);;
+}
diff --git a/MaelstromUI.h b/MaelstromUI.h
new file mode 100644
index 00000000..b1590fa6
--- /dev/null
+++ b/MaelstromUI.h
@@ -0,0 +1,32 @@
+
+#include "screenlib/UIManager.h"
+
+class HashTable;
+
+class MaelstromUI : public UIManager
+{
+public:
+ MaelstromUI(FrameBuf *screen);
+ virtual ~MaelstromUI();
+
+ //
+ // UIFontInterface
+ //
+ virtual SDL_Texture *CreateText(const char *text, const char *fontName, int fontSize, UIFontStyle fontStyle);
+ virtual void FreeText(SDL_Texture *texture);
+
+ //
+ // UISoundInterface
+ //
+ virtual void PlaySound(int soundID);
+
+ //
+ // UIManager functions
+ //
+ virtual UIPanel *CreatePanel(const char *type, const char *name);
+ virtual UIPanelDelegate *CreatePanelDelegate(UIPanel *panel, const char *delegate);
+ virtual UIElement *CreateElement(UIPanel *panel, const char *type);
+
+protected:
+ HashTable *m_fonts;
+};
diff --git a/Makefile.am b/Makefile.am
index 1e975918..e685d417 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,6 +5,8 @@ bin_PROGRAMS = Maelstrom Maelstrom-netd
Maelstrom_SOURCES = \
Maelstrom.h \
Maelstrom_Globals.h \
+ MaelstromUI.cpp \
+ MaelstromUI.h \
buttonlist.h \
checksum.cpp \
checksum.h \
@@ -43,11 +45,7 @@ Maelstrom_SOURCES = \
UIElementSprite.cpp \
UIElementSprite.h \
UIElementTitle.cpp \
- UIElementTitle.h \
- UIElements.cpp \
- UIElements.h \
- UIPanels.cpp \
- UIPanels.h
+ UIElementTitle.h
LOGIC = netlogic
diff --git a/UIElements.cpp b/UIElements.cpp
deleted file mode 100644
index 95bd0b6e..00000000
--- a/UIElements.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-
-#include "UIElements.h"
-#include "screenlib/UIElementButton.h"
-#include "screenlib/UIElementLine.h"
-#include "screenlib/UIElementRect.h"
-#include "UIDialogLabel.h"
-#include "UIElementIcon.h"
-#include "UIElementKeyButton.h"
-#include "UIElementLabel.h"
-#include "UIElementSprite.h"
-#include "UIElementTitle.h"
-
-
-UIElement *
-CreateMaelstromUIElement(UIPanel *panel, const char *type)
-{
- if (strcasecmp(type, "Line") == 0) {
- return new UIElementLine(panel);
- } else if (strcasecmp(type, "Rectangle") == 0) {
- return new UIElementRect(panel);
- } else if (strcasecmp(type, "Label") == 0) {
- return new UIElementLabel(panel);
- } else if (strcasecmp(type, "DialogLabel") == 0) {
- return new UIDialogLabel(panel);
- } else if (strcasecmp(type, "Button") == 0) {
- return new UIElementButton(panel);
- } else if (strcasecmp(type, "KeyButton") == 0) {
- return new UIElementKeyButton(panel);
- } else if (strcasecmp(type, "Icon") == 0) {
- return new UIElementIcon(panel);
- } else if (strcasecmp(type, "Sprite") == 0) {
- return new UIElementSprite(panel);
- } else if (strcasecmp(type, "Title") == 0) {
- return new UIElementTitle(panel);
- }
- return NULL;
-}
diff --git a/UIElements.h b/UIElements.h
deleted file mode 100644
index 82d56435..00000000
--- a/UIElements.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _UIElements_h
-#define _UIElements_h
-
-class UIPanel;
-class UIElement;
-
-UIElement *CreateMaelstromUIElement(UIPanel *panel, const char *type);
-
-#endif // _UIElements_h
diff --git a/UIPanels.cpp b/UIPanels.cpp
deleted file mode 100644
index ff0a1c1d..00000000
--- a/UIPanels.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-
-#include "screenlib/UIPanel.h"
-#include "UIPanels.h"
-#include "UIDialog.h"
-#include "main.h"
-#include "netlogic/about.h"
-#include "netlogic/game.h"
-
-
-static UIPanelDelegate *
-CreateMaelstromUIDelegate(UIPanel *panel, const char *delegate)
-{
- if (strcasecmp(delegate, "MainPanel") == 0) {
- return new MainPanelDelegate(panel);
- } else if (strcasecmp(delegate, "AboutPanel") == 0) {
- return new AboutPanelDelegate(panel);
- } else if (strcasecmp(delegate, "GamePanel") == 0) {
- return new GamePanelDelegate(panel);
- } else {
- fprintf(stderr, "Warning: Couldn't find delegate '%s'\n", delegate);
- return NULL;
- }
-}
-
-UIPanel *
-CreateMaelstromUIPanel(UIManager *ui, const char *type, const char *name, const char *delegate)
-{
- UIPanel *panel;
-
- if (strcasecmp(type, "UIPanel") == 0) {
- panel = new UIPanel(ui, name);
- } else if (strcasecmp(type, "Dialog") == 0) {
- panel = new UIDialog(ui, name);
- } else {
- panel = NULL;
- }
-
- if (panel && delegate && *delegate) {
- panel->SetPanelDelegate(CreateMaelstromUIDelegate(panel, delegate));
- }
-
- return panel;
-}
diff --git a/UIPanels.h b/UIPanels.h
deleted file mode 100644
index d8674d80..00000000
--- a/UIPanels.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _UIPanels_h
-#define _UIPanels_h
-
-class UIManager;
-class UIPanel;
-
-UIPanel *CreateMaelstromUIPanel(UIManager *ui, const char *type, const char *name, const char *delegate);
-
-#endif // _UIPanels_h
diff --git a/init.cpp b/init.cpp
index cc70ce2a..1e5b5189 100644
--- a/init.cpp
+++ b/init.cpp
@@ -8,8 +8,7 @@
#include "load.h"
#include "colortable.h"
#include "fastrand.h"
-#include "UIPanels.h"
-#include "UIElements.h"
+#include "MaelstromUI.h"
#include "screenlib/UIElement.h"
@@ -647,12 +646,6 @@ void CleanUp(void)
SDL_Quit();
}
-/* This function is called by the UI to play menu sounds */
-static void PlayUISound(void*, int soundID)
-{
- sound->PlaySound(soundID, 5);
-}
-
/* ----------------------------------------------------------------- */
/* -- Perform some initializations and report failure if we choke */
int DoInitializations(Uint32 window_flags, Uint32 render_flags)
@@ -726,12 +719,6 @@ int DoInitializations(Uint32 window_flags, Uint32 render_flags)
}
}
- /* Create the UI manager */
- ui = new UIManager(screen, CreateMaelstromUIPanel, CreateMaelstromUIElement);
- ui->SetSoundCallback(PlayUISound, NULL);
- ui->SetLoadPath("UI");
- ui->LoadTemplates("UITemplates.xml");
-
/* Load the Sound Server and initialize sound */
sound = new Sound("Maelstrom Sounds", gSoundLevel);
if ( sound->Error() ) {
@@ -739,6 +726,9 @@ int DoInitializations(Uint32 window_flags, Uint32 render_flags)
return(-1);
}
+ /* Create the UI manager */
+ ui = new MaelstromUI(screen);
+
/* -- We want to access the FULL screen! */
SetRect(&gScrnRect, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
gStatusLine = (gScrnRect.bottom - gScrnRect.top - STATUS_HEIGHT);
diff --git a/screenlib/Makefile.am b/screenlib/Makefile.am
index 3eb44741..b2c4b0e2 100644
--- a/screenlib/Makefile.am
+++ b/screenlib/Makefile.am
@@ -17,9 +17,11 @@ libSDLscreen_a_SOURCES = \
UIElementRect.h \
UIElementTexture.cpp \
UIElementTexture.h \
+ UIFontInterface.h \
UIManager.cpp \
UIManager.h \
UIPanel.cpp \
UIPanel.h \
+ UISoundInterface.h \
UITemplates.cpp \
UITemplates.h
diff --git a/screenlib/UIFontInterface.h b/screenlib/UIFontInterface.h
new file mode 100644
index 00000000..06e0e91e
--- /dev/null
+++ b/screenlib/UIFontInterface.h
@@ -0,0 +1,42 @@
+/*
+ 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 _UIFontInterface_h
+#define _UIFontInterface_h
+
+enum UIFontStyle {
+ UIFONT_STYLE_NORMAL = 0x00,
+ UIFONT_STYLE_BOLD = 0x01,
+ UIFONT_STYLE_UNDERLINE = 0x02,
+ UIFONT_STYLE_ITALIC = 0x04,
+};
+
+struct SDL_Texture;
+
+class UIFontInterface
+{
+public:
+ virtual SDL_Texture *CreateText(const char *text, const char *fontName, int fontSize, UIFontStyle fontStyle) = 0;
+ virtual void FreeText(SDL_Texture *texture) = 0;
+};
+
+#endif // _UIFontInterface_h
diff --git a/screenlib/UIManager.cpp b/screenlib/UIManager.cpp
index 15ed1254..ae573f0f 100644
--- a/screenlib/UIManager.cpp
+++ b/screenlib/UIManager.cpp
@@ -25,14 +25,13 @@
#include "SDL_FrameBuf.h"
#include "UIManager.h"
#include "UIPanel.h"
+#include "UIElementButton.h"
+#include "UIElementLine.h"
+#include "UIElementRect.h"
-UIManager::UIManager(FrameBuf *screen, UIPanelFactory panelFactory, UIElementFactory elementFactory) : UIArea(screen)
+UIManager::UIManager(FrameBuf *screen) : UIArea(screen)
{
- m_panelFactory = panelFactory;
- m_elementFactory = elementFactory;
- m_soundCallback = NULL;
- m_soundCallbackParam = NULL;
m_loadPath = new char[2];
strcpy(m_loadPath, ".");
}
@@ -94,15 +93,6 @@ UIManager::LoadPanel(const char *name)
PHYSFS_sint64 size;
char *buffer;
- if (!GetPanelFactory()) {
- fprintf(stderr, "Error: No panel factory set\n");
- return NULL;
- }
- if (!GetElementFactory()) {
- fprintf(stderr, "Error: No element factory set\n");
- return NULL;
- }
-
sprintf(file, "%s/%s.xml", m_loadPath, name);
fp = PHYSFS_openRead(file);
if (!fp) {
@@ -135,17 +125,36 @@ UIManager::LoadPanel(const char *name)
rapidxml::xml_node<> *node = doc.first_node();
rapidxml::xml_attribute<> *attr;
+
+ panel = CreatePanel(node->name(), name);
+ if (!panel) {
+ fprintf(stderr, "Warning: Couldn't create panel %s in %s\n",
+ node->name(), file);
+ delete[] buffer;
+ return NULL;
+ }
+
attr = node->first_attribute("delegate", 0, false);
- panel = (GetPanelFactory())(this, node->name(), name, attr ? attr->value() : NULL);
- if (panel) {
- if (!panel->Load(node, GetTemplates()) ||
- !panel->FinishLoading()) {
- fprintf(stderr, "Warning: Couldn't load %s: %s\n",
- file, panel->Error());
+ if (attr) {
+ UIPanelDelegate *delegate;
+
+ delegate = CreatePanelDelegate(panel, attr->value());
+ if (!delegate) {
+ fprintf(stderr, "Warning: Couldn't find delegate '%s'\n", attr->value());
delete[] buffer;
delete panel;
return NULL;
}
+ panel->SetPanelDelegate(delegate);
+ }
+
+ if (!panel->Load(node, GetTemplates()) ||
+ !panel->FinishLoading()) {
+ fprintf(stderr, "Warning: Couldn't load %s: %s\n",
+ file, panel->Error());
+ delete[] buffer;
+ delete panel;
+ return NULL;
}
delete[] buffer;
}
@@ -256,3 +265,31 @@ UIManager::HandleEvent(const SDL_Event &event)
}
return false;
}
+
+UIPanel *
+UIManager::CreatePanel(const char *type, const char *name)
+{
+ if (strcasecmp(type, "UIPanel") == 0) {
+ return new UIPanel(this, name);
+ }
+ return NULL;
+}
+
+UIPanelDelegate *
+UIManager::CreatePanelDelegate(UIPanel *panel, const char *delegate)
+{
+ return NULL;
+}
+
+UIElement *
+UIManager::CreateElement(UIPanel *panel, const char *type)
+{
+ if (strcasecmp(type, "Line") == 0) {
+ return new UIElementLine(panel);
+ } else if (strcasecmp(type, "Rectangle") == 0) {
+ return new UIElementRect(panel);
+ } else if (strcasecmp(type, "Button") == 0) {
+ return new UIElementButton(panel);
+ }
+ return NULL;
+}
diff --git a/screenlib/UIManager.h b/screenlib/UIManager.h
index 6f97016e..fe38d54a 100644
--- a/screenlib/UIManager.h
+++ b/screenlib/UIManager.h
@@ -26,32 +26,24 @@
#include "SDL.h"
#include "../utils/array.h"
#include "UIArea.h"
+#include "UIFontInterface.h"
+#include "UISoundInterface.h"
#include "UITemplates.h"
class FrameBuf;
-class UIManager;
class UIPanel;
+class UIPanelDelegate;
class UIElement;
-typedef UIPanel *(*UIPanelFactory)(UIManager *ui, const char *type, const char *name, const char *delegate);
-typedef UIElement *(*UIElementFactory)(UIPanel *panel, const char *name);
-typedef void (*UISoundCallback)(void *, int soundID);
-
-class UIManager : public UIArea
+class UIManager : public UIArea, public UIFontInterface, public UISoundInterface
{
public:
- UIManager(FrameBuf *screen, UIPanelFactory panelFactory, UIElementFactory elementFactory);
- ~UIManager();
+ UIManager(FrameBuf *screen);
+ virtual ~UIManager();
FrameBuf *GetScreen() const {
return m_screen;
}
- UIPanelFactory GetPanelFactory() const {
- return m_panelFactory;
- }
- UIElementFactory GetElementFactory() const {
- return m_elementFactory;
- }
const UITemplates *GetTemplates() const {
return &m_templates;
}
@@ -86,24 +78,15 @@ class UIManager : public UIArea
DeletePanel(GetPanel(name));
}
- void SetSoundCallback(UISoundCallback callback, void *param) {
- m_soundCallback = callback;
- m_soundCallbackParam = param;
- }
- void PlaySound(int soundID) {
- if (m_soundCallback) {
- m_soundCallback(m_soundCallbackParam, soundID);
- }
- }
-
void Draw(bool fullUpdate = true);
bool HandleEvent(const SDL_Event &event);
+public:
+ virtual UIPanel *CreatePanel(const char *type, const char *name);
+ virtual UIPanelDelegate *CreatePanelDelegate(UIPanel *panel, const char *delegate);
+ virtual UIElement *CreateElement(UIPanel *panel, const char *type);
+
protected:
- UIPanelFactory m_panelFactory;
- UIElementFactory m_elementFactory;
- UISoundCallback m_soundCallback;
- void *m_soundCallbackParam;
char *m_loadPath;
UITemplates m_templates;
array<UIPanel *> m_panels;
diff --git a/screenlib/UIPanel.cpp b/screenlib/UIPanel.cpp
index 791ea7b0..074f3127 100644
--- a/screenlib/UIPanel.cpp
+++ b/screenlib/UIPanel.cpp
@@ -125,7 +125,7 @@ bool
UIPanel::LoadElements(rapidxml::xml_node<> *node, const UITemplates *templates)
{
for (node = node->first_node(); node; node = node->next_sibling()) {
- UIElement *element = (m_ui->GetElementFactory())(this, node->name());
+ UIElement *element = m_ui->CreateElement(this, node->name());
if (!element) {
fprintf(stderr, "Warning: Couldn't find handler for element %s\n", node->name());
continue;
diff --git a/screenlib/UISoundInterface.h b/screenlib/UISoundInterface.h
new file mode 100644
index 00000000..bd125db6
--- /dev/null
+++ b/screenlib/UISoundInterface.h
@@ -0,0 +1,32 @@
+/*
+ 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 _UISoundInterface_h
+#define _UISoundInterface_h
+
+class UISoundInterface
+{
+public:
+ virtual void PlaySound(int soundID) = 0;
+};
+
+#endif // _UISoundInterface_h