diff options
author | Jared Adams <jaxad0127@gmail.com> | 2010-03-04 22:41:19 -0700 |
---|---|---|
committer | Jared Adams <jaxad0127@gmail.com> | 2010-03-12 14:49:27 -0700 |
commit | 781b3c9f17708cc5fe08eb3c9ee38d596364d97c (patch) | |
tree | 833797c9b9168ab58864ffe4cf8ed028060e44a2 /src/gui/theme.cpp | |
parent | 96b64757954f07d196599b3c1131a6603982c930 (diff) | |
download | mana-client-781b3c9f17708cc5fe08eb3c9ee38d596364d97c.tar.gz mana-client-781b3c9f17708cc5fe08eb3c9ee38d596364d97c.tar.bz2 mana-client-781b3c9f17708cc5fe08eb3c9ee38d596364d97c.tar.xz mana-client-781b3c9f17708cc5fe08eb3c9ee38d596364d97c.zip |
Split Palette into Theme and UserPalette
Themes can now control the colors they use. Colors in the Viewport (being
names, particles, etc) can still be changed by the user. Also make
ProgressBars more easily colored. DyePalette was made more flexible in the
process.
Also fixes comparing strings of different lengths insensitively.
Reviewed-by: Thorbjørn Lindeijer
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", "")); + } + } +} |