summaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/gui.cpp1
-rw-r--r--src/gui/skin.cpp174
-rw-r--r--src/gui/skin.h67
-rw-r--r--src/gui/window.cpp156
-rw-r--r--src/gui/window.h33
5 files changed, 252 insertions, 179 deletions
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 85a33218..2c0ddee9 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -27,6 +27,7 @@
#include "focushandler.h"
#include "gui.h"
#include "sdlinput.h"
+#include "skin.h"
#include "truetypefont.h"
#include "viewport.h"
#include "window.h"
diff --git a/src/gui/skin.cpp b/src/gui/skin.cpp
new file mode 100644
index 00000000..e9d081e9
--- /dev/null
+++ b/src/gui/skin.cpp
@@ -0,0 +1,174 @@
+/*
+ * Aethyra
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of Aethyra.
+ *
+ * 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
+ * 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
+ */
+
+#include "skin.h"
+
+#include "../log.h"
+
+#include "../resources/image.h"
+#include "../resources/resourcemanager.h"
+
+#include "../utils/dtor.h"
+#include "../utils/xml.h"
+
+SkinLoader* skinLoader = NULL;
+
+Skin::Skin():
+ closeImage(NULL),
+ instances(0)
+{
+}
+
+Skin::~Skin()
+{
+ // Clean up static resources
+ for (int i = 0; i < 9; i++)
+ {
+ delete border.grid[i];
+ border.grid[i] = NULL;
+ }
+
+ closeImage->decRef();
+}
+
+Skin* SkinLoader::load(const std::string &filename)
+{
+ SkinIterator skinIterator = mSkins.find(filename);
+
+ if (mSkins.end() != skinIterator)
+ {
+ skinIterator->second->instances++;
+ return skinIterator->second;
+ }
+
+ Skin* skin = new Skin();
+
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ logger->log("Loading Skin '%s'.", filename.c_str());
+
+ if (filename.empty())
+ logger->error("SkinLoader::load(): Invalid File Name.");
+
+ // TODO:
+ // If there is an error loading the specified file, we should try to revert
+ // to a 'default' skin file. Only if the 'default' skin file can't be loaded
+ // should we have a terminating error.
+ XML::Document doc(filename);
+ xmlNodePtr rootNode = doc.rootNode();
+
+ if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "skinset"))
+ logger->error("Widget Skinning error");
+
+ std::string skinSetImage;
+ skinSetImage = XML::getProperty(rootNode, "image", "");
+ Image *dBorders = NULL;
+ if (!skinSetImage.empty())
+ {
+ logger->log("SkinLoader::load(): <skinset> defines "
+ "'%s' as a skin image.", skinSetImage.c_str());
+ dBorders = resman->getImage("graphics/gui/" + skinSetImage);
+ }
+ else
+ {
+ logger->error("SkinLoader::load(): Skinset does not define an image!");
+ }
+
+ //iterate <widget>'s
+ for_each_xml_child_node(widgetNode, rootNode)
+ {
+ if (!xmlStrEqual(widgetNode->name, BAD_CAST "widget"))
+ continue;
+
+ std::string widgetType;
+ widgetType = XML::getProperty(widgetNode, "type", "unknown");
+ if (widgetType == "Window")
+ {
+ // Iterate through <part>'s
+ // LEEOR / TODO:
+ // We need to make provisions to load in a CloseButton image. For
+ // now it can just be hard-coded.
+ for_each_xml_child_node(partNode, widgetNode)
+ {
+ if (!xmlStrEqual(partNode->name, BAD_CAST "part"))
+ continue;
+
+ std::string partType;
+ partType = XML::getProperty(partNode, "type", "unknown");
+ // TOP ROW
+ const int xPos = XML::getProperty(partNode, "xpos", 0);
+ const int yPos = XML::getProperty(partNode, "ypos", 0);
+ const int width = XML::getProperty(partNode, "width", 1);
+ const int height = XML::getProperty(partNode, "height", 1);
+
+ if (partType == "top-left-corner")
+ skin->border.grid[0] = dBorders->getSubImage(xPos, yPos, width, height);
+ else if (partType == "top-edge")
+ skin->border.grid[1] = dBorders->getSubImage(xPos, yPos, width, height);
+ else if (partType == "top-right-corner")
+ skin->border.grid[2] = dBorders->getSubImage(xPos, yPos, width, height);
+
+ // MIDDLE ROW
+ else if (partType == "left-edge")
+ skin->border.grid[3] = dBorders->getSubImage(xPos, yPos, width, height);
+ else if (partType == "bg-quad")
+ skin->border.grid[4] = dBorders->getSubImage(xPos, yPos, width, height);
+ else if (partType == "right-edge")
+ skin->border.grid[5] = dBorders->getSubImage(xPos, yPos, width, height);
+
+ // BOTTOM ROW
+ else if (partType == "bottom-left-corner")
+ skin->border.grid[6] = dBorders->getSubImage(xPos, yPos, width, height);
+ else if (partType == "bottom-edge")
+ skin->border.grid[7] = dBorders->getSubImage(xPos, yPos, width, height);
+ else if (partType == "bottom-right-corner")
+ skin->border.grid[8] = dBorders->getSubImage(xPos, yPos, width, height);
+
+ // Part is of an uknown type.
+ else
+ logger->log("SkinLoader::load(): Unknown Part Type '%s'", partType.c_str());
+ }
+ }
+ // Widget is of an uknown type.
+ else
+ {
+ logger->log("SkinLoader::load(): Unknown Widget Type '%s'", widgetType.c_str());
+ }
+ }
+ dBorders->decRef();
+
+ logger->log("Finished loading Skin.");
+
+ // Hard-coded for now until we update the above code to look for window buttons.
+ skin->closeImage = resman->getImage("graphics/gui/close_button.png");
+ mSkins[filename] = skin;
+ return skin;
+}
+
+SkinLoader::SkinLoader()
+{
+}
+
+SkinLoader::~SkinLoader()
+{
+ delete_all(mSkins);
+}
+
diff --git a/src/gui/skin.h b/src/gui/skin.h
new file mode 100644
index 00000000..6dddb4a8
--- /dev/null
+++ b/src/gui/skin.h
@@ -0,0 +1,67 @@
+/*
+ * Aethyra
+ * Copyright (C) 2009 Aethyra Development Team
+ *
+ * This file is part of Aethyra.
+ *
+ * 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
+ * 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
+ */
+
+#ifndef SKIN_H
+#define SKIN_H
+
+#include <map>
+#include <string>
+
+#include "../graphics.h"
+
+class Image;
+
+class Skin
+{
+ public:
+ Skin();
+ ~Skin();
+
+ std::string mName; /**< Name of the skin to use */
+ ImageRect border; /**< The window border and background */
+ Image *closeImage; /**< Close Button Image */
+ int instances;
+};
+
+// Map containing all window skins
+typedef std::map<std::string, Skin*> Skins;
+
+// Iterator for window skins
+typedef Skins::iterator SkinIterator;
+
+class SkinLoader
+{
+ public:
+ SkinLoader();
+ ~SkinLoader();
+
+ /**
+ * Loads a skin
+ */
+ Skin* load(const std::string &filename);
+
+ private:
+ Skins mSkins;
+};
+
+extern SkinLoader* skinLoader;
+
+#endif
diff --git a/src/gui/window.cpp b/src/gui/window.cpp
index 0e91b68d..def81c53 100644
--- a/src/gui/window.cpp
+++ b/src/gui/window.cpp
@@ -27,6 +27,7 @@
#include <guichan/exception.hpp>
#include "gui.h"
+#include "skin.h"
#include "window.h"
#include "windowcontainer.h"
@@ -38,17 +39,12 @@
#include "../log.h"
#include "../resources/image.h"
-#include "../resources/resourcemanager.h"
-
-#include "../utils/dtor.h"
-#include "../utils/xml.h"
ConfigListener *Window::windowConfigListener = 0;
WindowContainer *Window::windowContainer = 0;
int Window::instances = 0;
int Window::mouseResize = 0;
bool Window::mAlphaChanged = false;
-Window::Skins mSkins;
class WindowConfigListener : public ConfigListener
{
@@ -58,24 +54,6 @@ class WindowConfigListener : public ConfigListener
}
};
-Skin::Skin():
- closeImage(NULL),
- instances(0)
-{
-}
-
-Skin::~Skin()
-{
- // Clean up static resources
- for (int i = 0; i < 9; i++)
- {
- delete border.grid[i];
- border.grid[i] = NULL;
- }
-
- closeImage->decRef();
-}
-
Window::Window(const std::string& caption, bool modal, Window *parent, const std::string& skin):
gcn::Window(caption),
mGrip(0),
@@ -94,17 +72,11 @@ Window::Window(const std::string& caption, bool modal, Window *parent, const std
logger->log("Window::Window(\"%s\")", caption.c_str());
if (!windowContainer)
- {
throw GCN_EXCEPTION("Window::Window(): no windowContainer set");
- }
-
- // Loads the skin
- loadSkin(skin);
-
- setGuiAlpha();
if (instances == 0)
{
+ skinLoader = new SkinLoader();
windowConfigListener = new WindowConfigListener();
// Send GUI alpha changed for initialization
windowConfigListener->optionChanged("guialpha");
@@ -117,6 +89,11 @@ Window::Window(const std::string& caption, bool modal, Window *parent, const std
setPadding(3);
setTitleBarHeight(20);
+ // Loads the skin
+ mSkin = skinLoader->load(skin);
+
+ setGuiAlpha();
+
// Add this window to the window container
windowContainer->add(this);
@@ -153,10 +130,10 @@ Window::~Window()
if (instances == 0)
{
+ delete skinLoader;
config.removeListener("guialpha", windowConfigListener);
delete windowConfigListener;
windowConfigListener = NULL;
- delete_all(mSkins);
}
}
@@ -696,123 +673,6 @@ void Window::setGuiAlpha()
mAlphaChanged = false;
}
-void Window::loadSkin(const std::string &filename)
-{
- SkinIterator skinIterator = mSkins.find(filename);
-
- if (mSkins.end() != skinIterator)
- {
- skinIterator->second->instances++;
- mSkin = skinIterator->second;
- return;
- }
-
- const std::string windowId = Window::getId();
-
- mSkin = new Skin();
-
- ResourceManager *resman = ResourceManager::getInstance();
-
- logger->log("Loading Window Skin '%s'.", filename.c_str());
- logger->log("Loading Window ID '%s'.", windowId.c_str());
-
- if (filename.empty())
- logger->error("Window::loadSkin(): Invalid File Name.");
-
- // TODO:
- // If there is an error loading the specified file, we should try to revert
- // to a 'default' skin file. Only if the 'default' skin file can't be loaded
- // should we have a terminating error.
- XML::Document doc(filename);
- xmlNodePtr rootNode = doc.rootNode();
-
- if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "skinset"))
- logger->error("Widget Skinning error");
-
- std::string skinSetImage;
- skinSetImage = XML::getProperty(rootNode, "image", "");
- Image *dBorders = NULL;
- if (!skinSetImage.empty())
- {
- logger->log("Window::loadSkin(): <skinset> defines "
- "'%s' as a skin image.", skinSetImage.c_str());
- dBorders = resman->getImage("graphics/gui/" + skinSetImage);
- }
- else
- {
- logger->error("Window::loadSkin(): Skinset does not define an image!");
- }
-
- //iterate <widget>'s
- for_each_xml_child_node(widgetNode, rootNode)
- {
- if (!xmlStrEqual(widgetNode->name, BAD_CAST "widget"))
- continue;
-
- std::string widgetType;
- widgetType = XML::getProperty(widgetNode, "type", "unknown");
- if (widgetType == "Window")
- {
- // Iterate through <part>'s
- // LEEOR / TODO:
- // We need to make provisions to load in a CloseButton image. For
- // now it can just be hard-coded.
- for_each_xml_child_node(partNode, widgetNode)
- {
- if (!xmlStrEqual(partNode->name, BAD_CAST "part"))
- continue;
-
- std::string partType;
- partType = XML::getProperty(partNode, "type", "unknown");
- // TOP ROW
- const int xPos = XML::getProperty(partNode, "xpos", 0);
- const int yPos = XML::getProperty(partNode, "ypos", 0);
- const int width = XML::getProperty(partNode, "width", 1);
- const int height = XML::getProperty(partNode, "height", 1);
-
- if (partType == "top-left-corner")
- mSkin->border.grid[0] = dBorders->getSubImage(xPos, yPos, width, height);
- else if (partType == "top-edge")
- mSkin->border.grid[1] = dBorders->getSubImage(xPos, yPos, width, height);
- else if (partType == "top-right-corner")
- mSkin->border.grid[2] = dBorders->getSubImage(xPos, yPos, width, height);
-
- // MIDDLE ROW
- else if (partType == "left-edge")
- mSkin->border.grid[3] = dBorders->getSubImage(xPos, yPos, width, height);
- else if (partType == "bg-quad")
- mSkin->border.grid[4] = dBorders->getSubImage(xPos, yPos, width, height);
- else if (partType == "right-edge")
- mSkin->border.grid[5] = dBorders->getSubImage(xPos, yPos, width, height);
-
- // BOTTOM ROW
- else if (partType == "bottom-left-corner")
- mSkin->border.grid[6] = dBorders->getSubImage(xPos, yPos, width, height);
- else if (partType == "bottom-edge")
- mSkin->border.grid[7] = dBorders->getSubImage(xPos, yPos, width, height);
- else if (partType == "bottom-right-corner")
- mSkin->border.grid[8] = dBorders->getSubImage(xPos, yPos, width, height);
-
- // Part is of an uknown type.
- else
- logger->log("Window::loadSkin(): Unknown Part Type '%s'", partType.c_str());
- }
- }
- // Widget is of an uknown type.
- else
- {
- logger->log("Window::loadSkin(): Unknown Widget Type '%s'", widgetType.c_str());
- }
- }
- dBorders->decRef();
-
- logger->log("Finished loading Window Skin.");
-
- // Hard-coded for now until we update the above code to look for window buttons.
- mSkin->closeImage = resman->getImage("graphics/gui/close_button.png");
- mSkins[filename] = mSkin;
-}
-
Layout &Window::getLayout()
{
if (!mLayout) mLayout = new Layout;
diff --git a/src/gui/window.h b/src/gui/window.h
index c5660c58..7ae7ebba 100644
--- a/src/gui/window.h
+++ b/src/gui/window.h
@@ -23,8 +23,6 @@
#ifndef WINDOW_H
#define WINDOW_H
-#include <map>
-
#include <guichan/widgetlistener.hpp>
#include <guichan/widgets/window.hpp>
@@ -35,24 +33,13 @@
class ConfigListener;
class GCContainer;
class ContainerPlacer;
-class Image;
class Layout;
class LayoutCell;
class ResizeGrip;
+class Skin;
+class SkinLoader;
class WindowContainer;
-class Skin
-{
- public:
- Skin();
- ~Skin();
-
- std::string mName; /**< Name of the skin to use */
- ImageRect border; /**< The window border and background */
- Image *closeImage; /**< Close Button Image */
- int instances;
-};
-
/**
* A window. This window can be dragged around and has a title bar. Windows are
* invisible by default.
@@ -297,11 +284,6 @@ class Window : public gcn::Window, gcn::WidgetListener
void reflowLayout(int w = 0, int h = 0);
/**
- * Loads a window skin
- */
- void loadSkin(const std::string &filename);
-
- /**
* Adds a widget to the window and sets it at given cell.
*/
LayoutCell &place(int x, int y, gcn::Widget *, int w = 1, int h = 1);
@@ -317,17 +299,6 @@ class Window : public gcn::Window, gcn::WidgetListener
* on window close they couldn't do otherwise.
*/
virtual void close();
-
- /**
- * Map containing all window skins
- */
- typedef std::map<std::string, Skin*> Skins;
-
- /**
- * Iterator for window skins
- */
- typedef Skins::iterator SkinIterator;
-
protected:
/** The window container windows add themselves to. */