diff options
author | Ira Rice <irarice@gmail.com> | 2009-03-11 14:38:26 -0600 |
---|---|---|
committer | Ira Rice <irarice@gmail.com> | 2009-03-11 14:38:26 -0600 |
commit | 2a6b52f6467bfb4babb2a33205752f58554b651b (patch) | |
tree | 62934e146a8cb5a9be2a786d1f45795ffea51731 | |
parent | bb45b6a8ca4ea751bceb5853060251a3eefcd4fc (diff) | |
download | mana-2a6b52f6467bfb4babb2a33205752f58554b651b.tar.gz mana-2a6b52f6467bfb4babb2a33205752f58554b651b.tar.bz2 mana-2a6b52f6467bfb4babb2a33205752f58554b651b.tar.xz mana-2a6b52f6467bfb4babb2a33205752f58554b651b.zip |
Moved the Skin class outside of the Window class, in order to allow
other widget containers to use skins as well, and to make it easier to
extend later.
Signed-off-by: Ira Rice <irarice@gmail.com>
-rw-r--r-- | aethyra.cbp | 2 | ||||
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/game.cpp | 1 | ||||
-rw-r--r-- | src/gui/gui.cpp | 1 | ||||
-rw-r--r-- | src/gui/skin.cpp | 174 | ||||
-rw-r--r-- | src/gui/skin.h | 67 | ||||
-rw-r--r-- | src/gui/window.cpp | 156 | ||||
-rw-r--r-- | src/gui/window.h | 33 | ||||
-rw-r--r-- | src/main.cpp | 54 |
10 files changed, 288 insertions, 204 deletions
diff --git a/aethyra.cbp b/aethyra.cbp index 46034040..6bae4561 100644 --- a/aethyra.cbp +++ b/aethyra.cbp @@ -236,6 +236,8 @@ <Unit filename="src\gui\shortcutwindow.h" /> <Unit filename="src\gui\skill.cpp" /> <Unit filename="src\gui\skill.h" /> + <Unit filename="src\gui\skin.cpp" /> + <Unit filename="src\gui\skin.h" /> <Unit filename="src\gui\slider.cpp" /> <Unit filename="src\gui\slider.h" /> <Unit filename="src\gui\speechbubble.cpp" /> diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c7003946..171ec7ff 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -185,6 +185,8 @@ SET(SRCS gui/shortcutcontainer.h gui/skill.cpp gui/skill.h + gui/skin.cpp + gui/skin.h gui/slider.cpp gui/slider.h gui/speechbubble.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 963e41fb..440c020e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -135,6 +135,8 @@ aethyra_SOURCES = gui/widgets/dropdown.cpp \ gui/shortcutcontainer.h \ gui/skill.cpp \ gui/skill.h \ + gui/skin.cpp \ + gui/skin.h \ gui/slider.cpp \ gui/slider.h \ gui/speechbubble.cpp \ diff --git a/src/game.cpp b/src/game.cpp index 13be3663..3b621acd 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -345,7 +345,6 @@ Game::~Game() destroyGuiWindows(); delete beingManager; - delete player_node; delete floorItemManager; delete joystick; delete particleEngine; 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. */ diff --git a/src/main.cpp b/src/main.cpp index 9e7c91c0..a7032fb1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -437,16 +437,18 @@ void init_engine(const Options &options) state = LOGIN_STATE; /**< Initial game state */ // Initialize sound engine - try { - if (config.getValue("sound", 0) == 1) { + try + { + if (config.getValue("sound", 0) == 1) sound.init(); - } + sound.setSfxVolume((int) config.getValue("sfxVolume", defaultSfxVolume)); sound.setMusicVolume((int) config.getValue("musicVolume", defaultMusicVolume)); } - catch (const char *err) { + catch (const char *err) + { state = ERROR_STATE; errorMessage = err; logger->log("Warning: %s", err); @@ -830,17 +832,18 @@ int main(int argc, char *argv[]) while (state != EXIT_STATE) { // Handle SDL events - while (SDL_PollEvent(&event)) { - switch (event.type) { + while (SDL_PollEvent(&event)) + { + switch (event.type) + { case SDL_QUIT: state = EXIT_STATE; break; case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_ESCAPE) - { state = EXIT_STATE; - } + break; } @@ -855,11 +858,10 @@ int main(int argc, char *argv[]) { state = ERROR_STATE; - if (!network->getError().empty()) { + if (!network->getError().empty()) errorMessage = network->getError(); - } else { + else errorMessage = _("Got disconnected from server!"); - } } if (progressBar->isVisible()) @@ -882,7 +884,8 @@ int main(int argc, char *argv[]) gui->draw(); graphics->updateScreen(); - if (state != oldstate) { + if (state != oldstate) + { switch (oldstate) { case UPDATE_STATE: @@ -913,12 +916,14 @@ int main(int argc, char *argv[]) oldstate = state; if (currentDialog && state != ACCOUNT_STATE && - state != CHAR_CONNECT_STATE) { + state != CHAR_CONNECT_STATE) + { delete currentDialog; currentDialog = NULL; } - switch (state) { + switch (state) + { case LOADDATA_STATE: logger->log("State: LOADDATA"); @@ -941,10 +946,13 @@ int main(int argc, char *argv[]) case LOGIN_STATE: logger->log("State: LOGIN"); - if (!loginData.password.empty()) { + if (!loginData.password.empty()) + { loginData.registerLogin = false; state = ACCOUNT_STATE; - } else { + } + else + { currentDialog = new LoginDialog(&loginData); positionDialog(currentDialog, screenWidth, screenHeight); @@ -1029,9 +1037,12 @@ int main(int argc, char *argv[]) break; case UPDATE_STATE: - if (options.skipUpdate) { + if (options.skipUpdate) + { state = LOADDATA_STATE; - } else { + } + else + { // Determine which source to use for the update host if (!options.updateHost.empty()) updateHost = options.updateHost; @@ -1109,9 +1120,8 @@ int main(int argc, char *argv[]) SDLNet_Quit(); if (nullFile) - { fclose(nullFile); - } + logger->log("State: EXIT"); exit_engine(); PHYSFS_deinit(); @@ -1123,16 +1133,12 @@ void SetupListener::action(const gcn::ActionEvent &event) Window *window = NULL; if (event.getId() == "Setup") - { window = setupWindow; - } if (window) { window->setVisible(!window->isVisible()); if (window->isVisible()) - { window->requestMoveToTop(); - } } } |