diff options
Diffstat (limited to 'src/gui/theme.cpp')
-rw-r--r-- | src/gui/theme.cpp | 225 |
1 files changed, 214 insertions, 11 deletions
diff --git a/src/gui/theme.cpp b/src/gui/theme.cpp index 961694e6..1841f8d9 100644 --- a/src/gui/theme.cpp +++ b/src/gui/theme.cpp @@ -27,6 +27,7 @@ #include "configuration.h" #include "log.h" +#include "resources/dye.h" #include "resources/image.h" #include "resources/imageset.h" #include "resources/resourcemanager.h" @@ -39,6 +40,8 @@ #include <algorithm> +#define GUI_ROOT "graphics/gui" + std::string Theme::mThemePath; Theme *Theme::mInstance = 0; @@ -92,9 +95,12 @@ int Skin::getMinHeight() const } Theme::Theme(): - mMinimumOpacity(-1.0f) + Palette(THEME_COLORS_END), + mMinimumOpacity(-1.0f), + mProgressColors(ProgressColors(THEME_PROG_END)) { config.addListener("guialpha", this); + loadColors(); } Theme::~Theme() @@ -117,6 +123,18 @@ void Theme::deleteInstance() mInstance = 0; } +gcn::Color Theme::getProgressColor(int type, float progress) +{ + DyePalette *dye = mInstance->mProgressColors[type]; + + int color[3] = {0, 0, 0}; + int intensity = (int) (255 * progress); + + dye->getColor(intensity, color); + + return gcn::Color(color[0], color[1], color[2]); +} + Skin *Theme::load(const std::string &filename, const std::string &defaultPath) { // Check if this skin was already loaded @@ -283,7 +301,7 @@ bool Theme::tryThemePath(std::string themePath) { if (!themePath.empty()) { - themePath = "graphics/gui/" + themePath; + themePath = GUI_ROOT + themePath; if (PHYSFS_exists(themePath.c_str())) { mThemePath = themePath; @@ -297,15 +315,13 @@ bool Theme::tryThemePath(std::string themePath) void Theme::prepareThemePath() { // Try theme from settings - if (tryThemePath(config.getValue("theme", ""))) - return; + if (!tryThemePath(config.getValue("theme", ""))) + // Try theme from branding + if (!tryThemePath(branding.getValue("theme", ""))) + // Use default + mThemePath = GUI_ROOT; - // Try theme from branding - if (tryThemePath(branding.getValue("theme", ""))) - return; - - // Use default - mThemePath = "graphics/gui"; + instance()->loadColors(mThemePath); } std::string Theme::resolveThemePath(const std::string &path) @@ -328,7 +344,7 @@ std::string Theme::resolveThemePath(const std::string &path) return getThemePath() + "/" + path; // Backup - return "graphics/gui/" + path; + return std::string(GUI_ROOT) + "/" + path; } Image *Theme::getImageFromTheme(const std::string &path) @@ -343,3 +359,190 @@ ImageSet *Theme::getImageSetFromTheme(const std::string &path, ResourceManager *resman = ResourceManager::getInstance(); return resman->getImageSet(resolveThemePath(path), w, h); } + +static int readColorType(const std::string &type) +{ + static std::string colors[] = { + "TEXT", + "SHADOW", + "OUTLINE", + "PROGRESS_BAR", + "BUTTON", + "BUTTON_DISABLED", + "TAB", + "BACKGROUND", + "HIGHLIGHT", + "TAB_FLASH", + "SHOP_WARNING", + "ITEM_EQUIPPED", + "CHAT", + "GM", + "PLAYER", + "WHISPER", + "IS", + "PARTY", + "GUILD", + "SERVER", + "LOGGER", + "HYPERLINK", + "UNKNOWN_ITEM", + "GENERIC", + "HEAD", + "USABLE", + "TORSO", + "ONEHAND", + "LEGS", + "FEET", + "TWOHAND", + "SHIELD", + "RING", + "NECKLACE", + "ARMS", + "AMMO" + }; + + if (type.empty()) + return -1; + + for (int i = 0; i < Theme::THEME_COLORS_END; i++) + { + if (compareStrI(type, colors[i]) == 0) + { + return i; + } + } + + return -1; +} + +static gcn::Color readColor(const std::string &description) +{ + int size = description.length(); + if (size < 7 || description[0] != '#') + { + error: + logger->log("Error, invalid theme color palette: %s", + description.c_str()); + return Palette::BLACK; + } + + int v = 0; + for (int i = 1; i < 7; ++i) + { + char c = description[i]; + int n; + + if ('0' <= c && c <= '9') + n = c - '0'; + else if ('A' <= c && c <= 'F') + n = c - 'A' + 10; + else if ('a' <= c && c <= 'f') + n = c - 'a' + 10; + else + goto error; + + v = (v << 4) | n; + } + + return gcn::Color(v); +} + +static Palette::GradientType readColorGradient(const std::string &grad) +{ + static std::string grads[] = { + "STATIC", + "PULSE", + "SPECTRUM", + "RAINBOW" + }; + + if (grad.empty()) + return Palette::STATIC; + + for (int i = 0; i < 4; i++) + { + if (compareStrI(grad, grads[i])) + return (Palette::GradientType) i; + } + + return Palette::STATIC; +} + +static int readProgressType(const std::string &type) +{ + static std::string colors[] = { + "DEFAULT", + "HP", + "MP", + "NO_MP", + "EXP", + "INVY_SLOTS", + "WEIGHT", + "JOB" + }; + + if (type.empty()) + return -1; + + for (int i = 0; i < Theme::THEME_PROG_END; i++) + { + if (compareStrI(type, colors[i]) == 0) + return i; + } + + return -1; +} + +void Theme::loadColors(std::string file) +{ + if (file == GUI_ROOT) + return; // No need to reload + + if (file == "") + file = GUI_ROOT; + + file += "/colors.xml"; + + XML::Document doc(file); + xmlNodePtr root = doc.rootNode(); + + if (!root || !xmlStrEqual(root->name, BAD_CAST "colors")) + { + logger->log("Error loading colors file: %s", file.c_str()); + return; + } + + int type; + std::string temp; + gcn::Color color; + GradientType grad; + + for_each_xml_child_node(node, root) + { + if (xmlStrEqual(node->name, BAD_CAST "color")) + { + type = readColorType(XML::getProperty(node, "id", "")); + if (type < 0) // invalid or no type given + continue; + + temp = XML::getProperty(node, "color", ""); + if (temp.empty()) // no color set, so move on + continue; + + color = readColor(temp); + grad = readColorGradient(XML::getProperty(node, "effect", "")); + + mColors[type].set(type, color, grad, "", 0, 10); + } + + if (xmlStrEqual(node->name, BAD_CAST "progressbar")) + { + type = readProgressType(XML::getProperty(node, "id", "")); + if (type < 0) // invalid or no type given + continue; + + mProgressColors[type] = new DyePalette(XML::getProperty(node, + "color", "")); + } + } +} |