summaryrefslogtreecommitdiff
path: root/src/gui/skin.cpp
diff options
context:
space:
mode:
authorJared Adams <jaxad0127@gmail.com>2010-03-05 07:39:43 -0700
committerJared Adams <jaxad0127@gmail.com>2010-03-05 07:58:02 -0700
commit78ab7c7a2877efd245293ad00cd36bcaa8646507 (patch)
tree28ea749d784a3dbee334f6a076a7ac77bc0333e1 /src/gui/skin.cpp
parentb60e6d82d6e843f9e65c81555ec281d237c3ce41 (diff)
downloadmana-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.cpp367
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);
-}