diff options
author | Jared Adams <jaxad0127@gmail.com> | 2010-03-05 07:39:43 -0700 |
---|---|---|
committer | Jared Adams <jaxad0127@gmail.com> | 2010-03-05 07:58:02 -0700 |
commit | 78ab7c7a2877efd245293ad00cd36bcaa8646507 (patch) | |
tree | 28ea749d784a3dbee334f6a076a7ac77bc0333e1 /src/gui/skin.cpp | |
parent | b60e6d82d6e843f9e65c81555ec281d237c3ce41 (diff) | |
download | mana-78ab7c7a2877efd245293ad00cd36bcaa8646507.tar.gz mana-78ab7c7a2877efd245293ad00cd36bcaa8646507.tar.bz2 mana-78ab7c7a2877efd245293ad00cd36bcaa8646507.tar.xz mana-78ab7c7a2877efd245293ad00cd36bcaa8646507.zip |
Rename SkinLoader to Theme
Also merge the guialpha ConfigListener into Theme.
Reviewed-by: Thorbjørn Lindeijer
Diffstat (limited to 'src/gui/skin.cpp')
-rw-r--r-- | src/gui/skin.cpp | 367 |
1 files changed, 0 insertions, 367 deletions
diff --git a/src/gui/skin.cpp b/src/gui/skin.cpp deleted file mode 100644 index 22153720..00000000 --- a/src/gui/skin.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Gui Skinning - * Copyright (C) 2008 The Legend of Mazzeroth Development Team - * Copyright (C) 2009 Aethyra Development Team - * Copyright (C) 2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * - * This file is part of The Mana Client. - * - * 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, see <http://www.gnu.org/licenses/>. - */ - -#include "gui/skin.h" - -#include "client.h" -#include "configuration.h" -#include "configlistener.h" -#include "log.h" - -#include "resources/image.h" -#include "resources/imageset.h" -#include "resources/resourcemanager.h" - -#include "utils/dtor.h" -#include "utils/stringutils.h" -#include "utils/xml.h" - -#include <physfs.h> - -#include <algorithm> - -std::string SkinLoader::mThemePath; -SkinLoader *SkinLoader::mInstance = 0; - -class SkinConfigListener : public ConfigListener -{ - public: - SkinConfigListener(SkinLoader *skinLoader) - : mSkinLoader(skinLoader) - { - config.addListener("guialpha", this); - } - - ~SkinConfigListener() - { - config.removeListener("guialpha", this); - } - - void optionChanged(const std::string &) - { - mSkinLoader->updateAlpha(); - } - - private: - SkinLoader *mSkinLoader; -}; - - -Skin::Skin(ImageRect skin, Image *close, Image *stickyUp, Image *stickyDown, - const std::string &filePath, - const std::string &name): - instances(0), - mFilePath(filePath), - mName(name), - mBorder(skin), - mCloseImage(close), - mStickyImageUp(stickyUp), - mStickyImageDown(stickyDown) -{ -} - -Skin::~Skin() -{ - // Clean up static resources - for (int i = 0; i < 9; i++) - delete mBorder.grid[i]; - - mCloseImage->decRef(); - delete mStickyImageUp; - delete mStickyImageDown; -} - -void Skin::updateAlpha(float minimumOpacityAllowed) -{ - const float alpha = std::max((double)minimumOpacityAllowed, - config.getValue("guialpha", 0.8f)); - - for_each(mBorder.grid, mBorder.grid + 9, - std::bind2nd(std::mem_fun(&Image::setAlpha), alpha)); - - mCloseImage->setAlpha(alpha); - mStickyImageUp->setAlpha(alpha); - mStickyImageDown->setAlpha(alpha); -} - -int Skin::getMinWidth() const -{ - return mBorder.grid[ImageRect::UPPER_LEFT]->getWidth() + - mBorder.grid[ImageRect::UPPER_RIGHT]->getWidth(); -} - -int Skin::getMinHeight() const -{ - return mBorder.grid[ImageRect::UPPER_LEFT]->getHeight() + - mBorder.grid[ImageRect::LOWER_LEFT]->getHeight(); -} - -SkinLoader::SkinLoader() - : mSkinConfigListener(new SkinConfigListener(this)), - mMinimumOpacity(-1.0f) -{ -} - -SkinLoader::~SkinLoader() -{ - delete_all(mSkins); - delete mSkinConfigListener; -} - -SkinLoader *SkinLoader::instance() -{ - if (!mInstance) - mInstance = new SkinLoader; - - return mInstance; -} - -void SkinLoader::deleteInstance() -{ - delete mInstance; - mInstance = 0; -} - -Skin *SkinLoader::load(const std::string &filename, - const std::string &defaultPath) -{ - // Check if this skin was already loaded - SkinIterator skinIterator = mSkins.find(filename); - if (mSkins.end() != skinIterator) - { - skinIterator->second->instances++; - return skinIterator->second; - } - - Skin *skin = readSkin(filename); - - if (!skin) - { - // Try falling back on the defaultPath if this makes sense - if (filename != defaultPath) - { - logger->log("Error loading skin '%s', falling back on default.", - filename.c_str()); - - skin = readSkin(defaultPath); - } - - if (!skin) - { - logger->error(strprintf("Error: Loading default skin '%s' failed. " - "Make sure the skin file is valid.", - defaultPath.c_str())); - } - } - - // Add the skin to the loaded skins - mSkins[filename] = skin; - - return skin; -} - -void SkinLoader::setMinimumOpacity(float minimumOpacity) -{ - if (minimumOpacity > 1.0f) return; - - mMinimumOpacity = minimumOpacity; - updateAlpha(); -} - -void SkinLoader::updateAlpha() -{ - for (SkinIterator iter = mSkins.begin(); iter != mSkins.end(); ++iter) - iter->second->updateAlpha(mMinimumOpacity); -} - -Skin *SkinLoader::readSkin(const std::string &filename) -{ - if (filename.empty()) - return 0; - - logger->log("Loading skin '%s'.", filename.c_str()); - - XML::Document doc(resolveThemePath(filename)); - xmlNodePtr rootNode = doc.rootNode(); - - if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "skinset")) - return 0; - - const std::string skinSetImage = XML::getProperty(rootNode, "image", ""); - - if (skinSetImage.empty()) - { - logger->log("SkinLoader::readSkin(): Skinset does not define an " - "image!"); - return 0; - } - - logger->log("SkinLoader::load(): <skinset> defines " - "'%s' as a skin image.", skinSetImage.c_str()); - - Image *dBorders = SkinLoader::getImageFromTheme(skinSetImage); - ImageRect border; - - // iterate <widget>'s - for_each_xml_child_node(widgetNode, rootNode) - { - if (!xmlStrEqual(widgetNode->name, BAD_CAST "widget")) - continue; - - const std::string 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; - - const std::string 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") - border.grid[0] = dBorders->getSubImage(xPos, yPos, width, height); - else if (partType == "top-edge") - border.grid[1] = dBorders->getSubImage(xPos, yPos, width, height); - else if (partType == "top-right-corner") - border.grid[2] = dBorders->getSubImage(xPos, yPos, width, height); - - // MIDDLE ROW - else if (partType == "left-edge") - border.grid[3] = dBorders->getSubImage(xPos, yPos, width, height); - else if (partType == "bg-quad") - border.grid[4] = dBorders->getSubImage(xPos, yPos, width, height); - else if (partType == "right-edge") - border.grid[5] = dBorders->getSubImage(xPos, yPos, width, height); - - // BOTTOM ROW - else if (partType == "bottom-left-corner") - border.grid[6] = dBorders->getSubImage(xPos, yPos, width, height); - else if (partType == "bottom-edge") - border.grid[7] = dBorders->getSubImage(xPos, yPos, width, height); - else if (partType == "bottom-right-corner") - border.grid[8] = dBorders->getSubImage(xPos, yPos, width, height); - - else - logger->log("SkinLoader::readSkin(): Unknown part type '%s'", - partType.c_str()); - } - } - else - { - logger->log("SkinLoader::readSkin(): 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 - Image *closeImage = SkinLoader::getImageFromTheme("close_button.png"); - Image *sticky = SkinLoader::getImageFromTheme("sticky_button.png"); - Image *stickyImageUp = sticky->getSubImage(0, 0, 15, 15); - Image *stickyImageDown = sticky->getSubImage(15, 0, 15, 15); - sticky->decRef(); - - Skin *skin = new Skin(border, closeImage, stickyImageUp, stickyImageDown, - filename); - skin->updateAlpha(mMinimumOpacity); - return skin; -} - -bool SkinLoader::tryThemePath(std::string themePath) -{ - if (!themePath.empty()) - { - themePath = "graphics/gui/" + themePath; - if (PHYSFS_exists(themePath.c_str())) - { - mThemePath = themePath; - return true; - } - } - - return false; -} - -void SkinLoader::prepareThemePath() -{ - // Try theme from settings - if (tryThemePath(config.getValue("theme", ""))) - return; - - // Try theme from branding - if (tryThemePath(branding.getValue("theme", ""))) - return; - - // Use default - mThemePath = "graphics/gui"; -} - -std::string SkinLoader::resolveThemePath(const std::string &path) -{ - // Need to strip off any dye info for the existence tests - int pos = path.find('|'); - std::string file; - if (pos > 0) - file = path.substr(0, pos); - else - file = path; - - // Might be a valid path already - if (PHYSFS_exists(file.c_str())) - return path; - - // Try the theme - file = getThemePath() + "/" + file; - if (PHYSFS_exists(file.c_str())) - return getThemePath() + "/" + path; - - // Backup - return "graphics/gui/" + path; -} - -Image *SkinLoader::getImageFromTheme(const std::string &path) -{ - ResourceManager *resman = ResourceManager::getInstance(); - return resman->getImage(resolveThemePath(path)); -} - -ImageSet *SkinLoader::getImageSetFromTheme(const std::string &path, - int w, int h) -{ - ResourceManager *resman = ResourceManager::getInstance(); - return resman->getImageSet(resolveThemePath(path), w, h); -} |