summaryrefslogtreecommitdiff
path: root/src/gui/theme.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/theme.cpp')
-rw-r--r--src/gui/theme.cpp1283
1 files changed, 0 insertions, 1283 deletions
diff --git a/src/gui/theme.cpp b/src/gui/theme.cpp
deleted file mode 100644
index cbc0d654c..000000000
--- a/src/gui/theme.cpp
+++ /dev/null
@@ -1,1283 +0,0 @@
-/*
- * The ManaPlus Client
- * 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
- * Copyright (C) 2011-2017 The ManaPlus Developers
- *
- * This file is part of The ManaPlus 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/theme.h"
-
-#include "configuration.h"
-#include "graphicsmanager.h"
-
-#include "const/gui/theme.h"
-
-#include "fs/virtfs/fs.h"
-#include "fs/virtfs/list.h"
-
-#include "gui/skin.h"
-#include "gui/themeinfo.h"
-
-#include "resources/imagerect.h"
-
-#include "resources/dye/dyepalette.h"
-
-#include "resources/image/image.h"
-
-#include "resources/loaders/imageloader.h"
-#include "resources/loaders/imagesetloader.h"
-#include "resources/loaders/subimageloader.h"
-#include "resources/loaders/subimagesetloader.h"
-#include "resources/loaders/xmlloader.h"
-
-#include "utils/dtor.h"
-#include "utils/foreach.h"
-
-#include "debug.h"
-
-static std::string defaultThemePath;
-
-std::string Theme::mThemePath;
-std::string Theme::mThemeName;
-std::string Theme::mScreenDensity;
-
-Theme *theme = nullptr;
-
-// Set the theme path...
-static void initDefaultThemePath()
-{
- defaultThemePath = branding.getStringValue("guiThemePath");
-
- logger->log("defaultThemePath: " + defaultThemePath);
- if (!defaultThemePath.empty() &&
- VirtFs::isDirectory(defaultThemePath))
- {
- return;
- }
- defaultThemePath = "themes/";
-}
-
-Theme::Theme() :
- Palette(CAST_S32(ThemeColorId::THEME_COLORS_END) * THEME_PALETTES),
- mSkins(),
- mMinimumOpacity(-1.0F),
- mProgressColors(ProgressColors(CAST_SIZE(
- ProgressColorId::THEME_PROG_END)))
-{
- initDefaultThemePath();
-
- config.addListener("guialpha", this);
-
- mColors[CAST_SIZE(ThemeColorId::HIGHLIGHT)].ch = 'H';
- mColors[CAST_SIZE(ThemeColorId::CHAT)].ch = 'C';
- mColors[CAST_SIZE(ThemeColorId::GM)].ch = 'G';
- mColors[CAST_SIZE(ThemeColorId::GLOBAL)].ch = 'g';
- mColors[CAST_SIZE(ThemeColorId::PLAYER)].ch = 'Y';
- mColors[CAST_SIZE(ThemeColorId::WHISPER_TAB)].ch = 'W';
- mColors[CAST_SIZE(ThemeColorId::WHISPER_TAB_OFFLINE)].ch = 'w';
- mColors[CAST_SIZE(ThemeColorId::IS)].ch = 'I';
- mColors[CAST_SIZE(ThemeColorId::PARTY_CHAT_TAB)].ch = 'P';
- mColors[CAST_SIZE(ThemeColorId::GUILD_CHAT_TAB)].ch = 'U';
- mColors[CAST_SIZE(ThemeColorId::SERVER)].ch = 'S';
- mColors[CAST_SIZE(ThemeColorId::LOGGER)].ch = 'L';
- mColors[CAST_SIZE(ThemeColorId::HYPERLINK)].ch = '<';
- mColors[CAST_SIZE(ThemeColorId::SELFNICK)].ch = 's';
- mColors[CAST_SIZE(ThemeColorId::OLDCHAT)].ch = 'o';
- mColors[CAST_SIZE(ThemeColorId::AWAYCHAT)].ch = 'a';
- mCharColors['H'] = CAST_S32(ThemeColorId::HIGHLIGHT);
- mCharColors['C'] = CAST_S32(ThemeColorId::CHAT);
- mCharColors['G'] = CAST_S32(ThemeColorId::GM);
- mCharColors['g'] = CAST_S32(ThemeColorId::GLOBAL);
- mCharColors['Y'] = CAST_S32(ThemeColorId::PLAYER);
- mCharColors['W'] = CAST_S32(ThemeColorId::WHISPER_TAB);
- mCharColors['w'] = CAST_S32(ThemeColorId::WHISPER_TAB_OFFLINE);
- mCharColors['I'] = CAST_S32(ThemeColorId::IS);
- mCharColors['P'] = CAST_S32(ThemeColorId::PARTY_CHAT_TAB);
- mCharColors['U'] = CAST_S32(ThemeColorId::GUILD_CHAT_TAB);
- mCharColors['S'] = CAST_S32(ThemeColorId::SERVER);
- mCharColors['L'] = CAST_S32(ThemeColorId::LOGGER);
- mCharColors['<'] = CAST_S32(ThemeColorId::HYPERLINK);
- mCharColors['s'] = CAST_S32(ThemeColorId::SELFNICK);
- mCharColors['o'] = CAST_S32(ThemeColorId::OLDCHAT);
- mCharColors['a'] = CAST_S32(ThemeColorId::AWAYCHAT);
-
- // here need use outlined colors
- mCharColors['H' | 0x80]
- = CAST_S32(ThemeColorId::HIGHLIGHT_OUTLINE);
- mCharColors['C' | 0x80] = CAST_S32(ThemeColorId::CHAT_OUTLINE);
- mCharColors['G' | 0x80] = CAST_S32(ThemeColorId::GM_OUTLINE);
- mCharColors['g' | 0x80] = CAST_S32(ThemeColorId::GLOBAL_OUTLINE);
- mCharColors['Y' | 0x80] = CAST_S32(ThemeColorId::PLAYER_OUTLINE);
- mCharColors['W' | 0x80]
- = CAST_S32(ThemeColorId::WHISPER_TAB_OUTLINE);
- mCharColors['w' | 0x80]
- = CAST_S32(ThemeColorId::WHISPER_TAB_OFFLINE_OUTLINE);
- mCharColors['I' | 0x80] = CAST_S32(ThemeColorId::IS_OUTLINE);
- mCharColors['P' | 0x80]
- = CAST_S32(ThemeColorId::PARTY_CHAT_TAB_OUTLINE);
- mCharColors['U' | 0x80]
- = CAST_S32(ThemeColorId::GUILD_CHAT_TAB_OUTLINE);
- mCharColors['S' | 0x80] = CAST_S32(ThemeColorId::SERVER_OUTLINE);
- mCharColors['L' | 0x80] = CAST_S32(ThemeColorId::LOGGER_OUTLINE);
- mCharColors['<' | 0x80]
- = CAST_S32(ThemeColorId::HYPERLINK_OUTLINE);
- mCharColors['s' | 0x80] = CAST_S32(ThemeColorId::SELFNICK_OUTLINE);
- mCharColors['o' | 0x80] = CAST_S32(ThemeColorId::OLDCHAT_OUTLINE);
- mCharColors['a' | 0x80] = CAST_S32(ThemeColorId::AWAYCHAT_OUTLINE);
-}
-
-Theme::~Theme()
-{
- delete_all(mSkins);
- config.removeListener("guialpha", this);
- CHECKLISTENERS
- delete_all(mProgressColors);
-}
-
-Color Theme::getProgressColor(const ProgressColorIdT type,
- const float progress)
-{
- int color[3] = {0, 0, 0};
-
- if (theme != nullptr)
- {
- const DyePalette *const dye
- = theme->mProgressColors[CAST_SIZE(type)];
-
- if (dye != nullptr)
- {
- dye->getColor(progress, color);
- }
- else
- {
- logger->log("color not found: "
- + toString(CAST_S32(type)));
- }
- }
-
- return Color(color[0], color[1], color[2]);
-}
-
-Skin *Theme::load(const std::string &filename,
- const std::string &filename2,
- const bool full,
- const std::string &restrict defaultPath)
-{
- // Check if this skin was already loaded
-
- const SkinIterator skinIterator = mSkins.find(filename);
- if (mSkins.end() != skinIterator)
- {
- if (skinIterator->second != nullptr)
- skinIterator->second->instances++;
- return skinIterator->second;
- }
-
- Skin *skin = nullptr;
- if (mScreenDensity.empty())
- { // if no density detected
- skin = readSkin(filename, full);
- if ((skin == nullptr) && !filename2.empty() && filename2 != filename)
- skin = readSkin(filename2, full);
- if ((skin == nullptr) && filename2 != "window.xml")
- skin = readSkin("window.xml", full);
- }
- else
- { // first use correct density images
- const std::string endStr("_" + mScreenDensity + ".xml");
- std::string name = filename;
- if (findCutLast(name, ".xml"))
- skin = readSkin(name + endStr, full);
- if (skin == nullptr)
- skin = readSkin(filename, full);
- if ((skin == nullptr) && !filename2.empty() && filename2 != filename)
- {
- name = filename2;
- if (findCutLast(name, ".xml"))
- skin = readSkin(name + endStr, full);
- if (skin == nullptr)
- skin = readSkin(filename2, full);
- }
- if ((skin == nullptr) && filename2 != "window.xml")
- {
- skin = readSkin("window" + endStr, full);
- if (skin == nullptr)
- skin = readSkin("window.xml", full);
- }
- }
-
- if (skin == nullptr)
- {
- // 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, full);
- }
-
- if (skin == nullptr)
- {
- logger->log(strprintf("Error: Loading default skin '%s' failed. "
- "Make sure the skin file is valid.",
- defaultPath.c_str()));
- }
- }
-
- mSkins[filename] = skin;
- return skin;
-}
-
-void Theme::unload(Skin *const skin)
-{
- if (skin == nullptr)
- return;
- skin->instances --;
- if (skin->instances == 0)
- {
- SkinIterator it = mSkins.begin();
- const SkinIterator it_end = mSkins.end();
- while (it != it_end)
- {
- if (it->second == skin)
- {
- mSkins.erase(it);
- break;
- }
- ++ it;
- }
- delete skin;
- }
-}
-
-void Theme::setMinimumOpacity(const float minimumOpacity)
-{
- if (minimumOpacity > 1.0F)
- return;
-
- mMinimumOpacity = minimumOpacity;
- updateAlpha();
-}
-
-void Theme::updateAlpha()
-{
- FOR_EACH (SkinIterator, iter, mSkins)
- {
- Skin *const skin = iter->second;
- if (skin != nullptr)
- skin->updateAlpha(mMinimumOpacity);
- }
-}
-
-void Theme::optionChanged(const std::string &name A_UNUSED)
-{
- updateAlpha();
-}
-
-struct SkinParameter final
-{
- A_DEFAULT_COPY(SkinParameter)
- int index;
- std::string name;
-};
-
-static const SkinParameter skinParam[] =
-{
- {0, "top-left-corner"},
- {0, "standart"},
- {0, "up"},
- {0, "hstart"},
- {0, "in"},
- {0, "normal"},
- {1, "top-edge"},
- {1, "highlighted"},
- {1, "down"},
- {1, "hmiddle"},
- {1, "in-highlighted"},
- {1, "checked"},
- {2, "top-right-corner"},
- {2, "pressed"},
- {2, "left"},
- {2, "hend"},
- {2, "out"},
- {2, "disabled"},
- {3, "left-edge"},
- {3, "disabled"},
- {3, "right"},
- {3, "hgrip"},
- {3, "out-highlighted"},
- {3, "disabled-checked"},
- {4, "bg-quad"},
- {4, "vstart"},
- {4, "normal-highlighted"},
- {5, "right-edge"},
- {5, "vmiddle"},
- {5, "checked-highlighted"},
- {6, "bottom-left-corner"},
- {6, "vend"},
- {7, "bottom-edge"},
- {7, "vgrip"},
- {8, "bottom-right-corner"},
-};
-
-static const SkinParameter imageParam[] =
-{
- {0, "closeImage"},
- {1, "closeImageHighlighted"},
- {2, "stickyImageUp"},
- {3, "stickyImageDown"},
-};
-
-struct SkinHelper final
-{
- SkinHelper() :
- partType(),
- xPos(),
- yPos(),
- width(),
- height(),
- rect(),
- node(),
- image()
- {
- }
-
- A_DELETE_COPY(SkinHelper)
-
- std::string partType;
- int xPos;
- int yPos;
- int width;
- int height;
- ImageRect *rect;
- XmlNodePtr *node;
- Image *image;
-
- bool loadList(const SkinParameter *const params,
- const size_t size) A_NONNULL(2)
- {
- for (size_t f = 0; f < size; f ++)
- {
- const SkinParameter &param = params[f];
- if (partType == param.name)
- {
- rect->grid[param.index] = Loader::getSubImage(
- image,
- xPos, yPos,
- width, height);
- return true;
- }
- }
- return false;
- }
-};
-
-Skin *Theme::readSkin(const std::string &filename, const bool full)
-{
- if (filename.empty())
- return nullptr;
-
- const std::string path = resolveThemePath(filename);
- if (!VirtFs::exists(path))
- return nullptr;
- XML::Document *const doc = Loader::getXml(path,
- UseVirtFs_true,
- SkipError_true);
- if (doc == nullptr)
- return nullptr;
- XmlNodeConstPtr rootNode = doc->rootNode();
- if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "skinset"))
- {
- doc->decRef();
- return nullptr;
- }
-
- const std::string skinSetImage = XML::getProperty(rootNode, "image", "");
-
- if (skinSetImage.empty())
- {
- logger->log1("Theme::readSkin(): Skinset does not define an image!");
- doc->decRef();
- return nullptr;
- }
-
- Image *const dBorders = Theme::getImageFromTheme(skinSetImage);
- ImageRect *const border = new ImageRect;
- ImageRect *const images = new ImageRect;
- int padding = 3;
- int titlePadding = 4;
- int titlebarHeight = 0;
- int titlebarHeightRelative = 0;
- int closePadding = 3;
- int stickySpacing = 3;
- int stickyPadding = 3;
- int resizePadding = 2;
- StringIntMap *const mOptions = new StringIntMap;
-
- // iterate <widget>'s
- for_each_xml_child_node(widgetNode, rootNode)
- {
- if (!xmlNameEqual(widgetNode, "widget"))
- continue;
-
- const std::string widgetType =
- XML::getProperty(widgetNode, "type", "unknown");
- if (widgetType == "Window")
- {
- SkinHelper helper;
- const int globalXPos = XML::getProperty(widgetNode, "xpos", 0);
- const int globalYPos = XML::getProperty(widgetNode, "ypos", 0);
- for_each_xml_child_node(partNode, widgetNode)
- {
- if (xmlNameEqual(partNode, "part"))
- {
- helper.partType = XML::getProperty(
- partNode, "type", "unknown");
- helper.xPos = XML::getProperty(
- partNode, "xpos", 0) + globalXPos;
- helper.yPos = XML::getProperty(
- partNode, "ypos", 0) + globalYPos;
- helper.width = XML::getProperty(partNode, "width", 0);
- helper.height = XML::getProperty(partNode, "height", 0);
- if ((helper.width == 0) || (helper.height == 0))
- continue;
- helper.image = dBorders;
-
- helper.rect = border;
- if (!helper.loadList(skinParam,
- sizeof(skinParam) / sizeof(SkinParameter)))
- {
- helper.rect = images;
- helper.loadList(imageParam,
- sizeof(imageParam) / sizeof(SkinParameter));
- }
- }
- else if (full && xmlNameEqual(partNode, "option"))
- {
- const std::string name = XML::getProperty(
- partNode, "name", "");
- if (name == "padding")
- {
- padding = XML::getProperty(partNode, "value", 3);
- }
- else if (name == "titlePadding")
- {
- titlePadding = XML::getProperty(partNode, "value", 4);
- }
- else if (name == "closePadding")
- {
- closePadding = XML::getProperty(partNode, "value", 3);
- }
- else if (name == "stickySpacing")
- {
- stickySpacing = XML::getProperty(partNode, "value", 3);
- }
- else if (name == "stickyPadding")
- {
- stickyPadding = XML::getProperty(partNode, "value", 3);
- }
- else if (name == "titlebarHeight")
- {
- titlebarHeight = XML::getProperty(
- partNode, "value", 0);
- }
- else if (name == "titlebarHeightRelative")
- {
- titlebarHeightRelative = XML::getProperty(
- partNode, "value", 0);
- }
- else if (name == "resizePadding")
- {
- resizePadding = XML::getProperty(
- partNode, "value", 2);
- }
- else
- {
- (*mOptions)[name] = XML::getProperty(
- partNode, "value", 0);
- }
- }
- }
- }
- else
- {
- logger->log("Theme::readSkin(): Unknown widget type '%s'",
- widgetType.c_str());
- }
- }
-
- if (dBorders != nullptr)
- dBorders->decRef();
-
- (*mOptions)["closePadding"] = closePadding;
- (*mOptions)["stickyPadding"] = stickyPadding;
- (*mOptions)["stickySpacing"] = stickySpacing;
- (*mOptions)["titlebarHeight"] = titlebarHeight;
- (*mOptions)["titlebarHeightRelative"] = titlebarHeightRelative;
- (*mOptions)["resizePadding"] = resizePadding;
-
- Skin *const skin = new Skin(border, images, filename, "", padding,
- titlePadding, mOptions);
- delete images;
- skin->updateAlpha(mMinimumOpacity);
- doc->decRef();
- return skin;
-}
-
-bool Theme::tryThemePath(const std::string &themeName)
-{
- if (!themeName.empty())
- {
- const std::string path = defaultThemePath + themeName;
- if (VirtFs::exists(path))
- {
- mThemePath = path;
- mThemeName = themeName;
- if (theme != nullptr)
- theme->loadColors("");
- return true;
- }
- }
-
- return false;
-}
-
-void Theme::fillSkinsList(StringVect &list)
-{
- VirtFs::getDirs(branding.getStringValue("guiThemePath"), list);
- std::sort(list.begin(), list.end());
-}
-
-void Theme::fillFontsList(StringVect &list)
-{
- VirtFs::permitLinks(true);
- VirtFs::getFiles(branding.getStringValue("fontsPath"), list);
- std::sort(list.begin(), list.end());
- VirtFs::permitLinks(false);
-}
-
-void Theme::fillSoundsList(StringVect &list)
-{
- VirtFs::List *const skins = VirtFs::enumerateFiles(
- branding.getStringValue("systemsounds"));
-
- FOR_EACH (StringVectCIter, i, skins->names)
- {
- if (!VirtFs::isDirectory((branding.getStringValue(
- "systemsounds") + *i)))
- {
- std::string str = *i;
- if (findCutLast(str, ".ogg"))
- list.push_back(str);
- }
- }
-
- VirtFs::freeList(skins);
- std::sort(list.begin(), list.end());
-}
-
-void Theme::selectSkin()
-{
- prepareThemePath();
- mScreenDensity = graphicsManager.getDensityString();
-}
-
-void Theme::prepareThemePath()
-{
- initDefaultThemePath();
-
- mThemePath.clear();
- mThemeName.clear();
-
- // Try theme from settings
- if (tryThemePath(config.getStringValue("theme")))
- return;
-
- // Try theme from branding
- if (tryThemePath(branding.getStringValue("theme")))
- return;
-
- if (mThemePath.empty())
- mThemePath = "graphics/gui";
-
- theme->loadColors(mThemePath);
-
- logger->log("Selected Theme: " + mThemePath);
-}
-
-std::string Theme::resolveThemePath(const std::string &path)
-{
- // Need to strip off any dye info for the existence tests
- const int pos = CAST_S32(path.find('|'));
- std::string file;
- if (pos > 0)
- file = path.substr(0, pos);
- else
- file = path;
-
- // File with path
- if (file.find('/') != std::string::npos)
- {
- // Might be a valid path already
- if (VirtFs::exists(file))
- return path;
- }
-
- // Try the theme
- file = pathJoin(getThemePath(), file);
-
- if (VirtFs::exists(file))
- return pathJoin(getThemePath(), path);
-
- // Backup
- return pathJoin(branding.getStringValue("guiPath"), path);
-}
-
-Image *Theme::getImageFromTheme(const std::string &path)
-{
- return Loader::getImage(resolveThemePath(path));
-}
-
-ImageSet *Theme::getImageSetFromTheme(const std::string &path,
- const int w, const int h)
-{
- return Loader::getImageSet(resolveThemePath(path), w, h);
-}
-
-static int readColorType(const std::string &type)
-{
- static const std::string colors[CAST_SIZE(
- ThemeColorId::THEME_COLORS_END)] =
- {
- "BROWSERBOX",
- "BROWSERBOX_OUTLINE",
- "SELFNICK",
- "SELFNICK_OUTLINE",
- "TEXT",
- "TEXT_OUTLINE",
- "CARET",
- "SHADOW",
- "OUTLINE",
- "BORDER",
- "PROGRESS_BAR",
- "PROGRESS_BAR_OUTLINE",
- "BUTTON",
- "BUTTON_OUTLINE",
- "BUTTON_DISABLED",
- "BUTTON_DISABLED_OUTLINE",
- "BUTTON_HIGHLIGHTED",
- "BUTTON_HIGHLIGHTED_OUTLINE",
- "BUTTON_PRESSED",
- "BUTTON_PRESSED_OUTLINE",
- "CHECKBOX",
- "CHECKBOX_OUTLINE",
- "DROPDOWN",
- "DROPDOWN_OUTLINE",
- "LABEL",
- "LABEL_OUTLINE",
- "LISTBOX",
- "LISTBOX_OUTLINE",
- "LISTBOX_SELECTED",
- "LISTBOX_SELECTED_OUTLINE",
- "RADIOBUTTON",
- "RADIOBUTTON_OUTLINE",
- "POPUP",
- "POPUP_OUTLINE",
- "TAB",
- "TAB_OUTLINE",
- "TAB_HIGHLIGHTED",
- "TAB_HIGHLIGHTED_OUTLINE",
- "TAB_SELECTED",
- "TAB_SELECTED_OUTLINE",
- "TEXTBOX",
- "TEXTFIELD",
- "TEXTFIELD_OUTLINE",
- "WINDOW",
- "WINDOW_OUTLINE",
- "BATTLE_CHAT_TAB",
- "BATTLE_CHAT_TAB_OUTLINE",
- "CHANNEL_CHAT_TAB",
- "CHANNEL_CHAT_TAB_OUTLINE",
- "PARTY_CHAT_TAB",
- "PARTY_CHAT_TAB_OUTLINE",
- "PARTY_SOCIAL_TAB",
- "PARTY_SOCIAL_TAB_OUTLINE",
- "GUILD_CHAT_TAB",
- "GUILD_CHAT_TAB_OUTLINE",
- "GUILD_SOCIAL_TAB",
- "GUILD_SOCIAL_TAB_OUTLINE",
- "GM_CHAT_TAB",
- "GM_CHAT_TAB_OUTLINE",
- "BATTLE_CHAT_TAB_HIGHLIGHTED",
- "BATTLE_CHAT_TAB_HIGHLIGHTED_OUTLINE",
- "CHANNEL_CHAT_TAB_HIGHLIGHTED",
- "CHANNEL_CHAT_TAB_HIGHLIGHTED_OUTLINE",
- "PARTY_CHAT_TAB_HIGHLIGHTED",
- "PARTY_CHAT_TAB_HIGHLIGHTED_OUTLINE",
- "PARTY_SOCIAL_TAB_HIGHLIGHTED",
- "PARTY_SOCIAL_TAB_HIGHLIGHTED_OUTLINE",
- "GUILD_CHAT_TAB_HIGHLIGHTED",
- "GUILD_CHAT_TAB_HIGHLIGHTED_OUTLINE",
- "GUILD_SOCIAL_TAB_HIGHLIGHTED",
- "GUILD_SOCIAL_TAB_HIGHLIGHTED_OUTLINE",
- "GM_CHAT_TAB_HIGHLIGHTED",
- "GM_CHAT_TAB_HIGHLIGHTED_OUTLINE",
- "BATTLE_CHAT_TAB_SELECTED",
- "BATTLE_CHAT_TAB_SELECTED_OUTLINE",
- "CHANNEL_CHAT_TAB_SELECTED",
- "CHANNEL_CHAT_TAB_SELECTED_OUTLINE",
- "PARTY_CHAT_TAB_SELECTED",
- "PARTY_CHAT_TAB_SELECTED_OUTLINE",
- "PARTY_SOCIAL_TAB_SELECTED",
- "PARTY_SOCIAL_TAB_SELECTED_OUTLINE",
- "GUILD_CHAT_TAB_SELECTED",
- "GUILD_CHAT_TAB_SELECTED_OUTLINE",
- "GUILD_SOCIAL_TAB_SELECTED",
- "GUILD_SOCIAL_TAB_SELECTED_OUTLINE",
- "GM_CHAT_TAB_SELECTED",
- "GM_CHAT_TAB_SELECTED_OUTLINE",
- "BACKGROUND",
- "BACKGROUND_GRAY",
- "SCROLLBAR_GRAY",
- "DROPDOWN_SHADOW",
- "HIGHLIGHT",
- "HIGHLIGHT_OUTLINE",
- "TAB_FLASH",
- "TAB_FLASH_OUTLINE",
- "TAB_PLAYER_FLASH",
- "TAB_PLAYER_FLASH_OUTLINE",
- "SHOP_WARNING",
- "ITEM_EQUIPPED",
- "ITEM_EQUIPPED_OUTLINE",
- "ITEM_NOT_EQUIPPED",
- "ITEM_NOT_EQUIPPED_OUTLINE",
- "CHAT",
- "CHAT_OUTLINE",
- "GM",
- "GM_OUTLINE",
- "GLOBAL",
- "GLOBAL_OUTLINE",
- "PLAYER",
- "PLAYER_OUTLINE",
- "WHISPER_TAB",
- "WHISPER_TAB_OUTLINE",
- "WHISPER_TAB_OFFLINE",
- "WHISPER_TAB_OFFLINE_OUTLINE",
- "WHISPER_TAB_HIGHLIGHTED",
- "WHISPER_TAB_HIGHLIGHTED_OUTLINE",
- "WHISPER_TAB_OFFLINE_HIGHLIGHTED",
- "WHISPER_TAB_OFFLINE_HIGHLIGHTED_OUTLINE",
- "WHISPER_TAB_SELECTED",
- "WHISPER_TAB_SELECTED_OUTLINE",
- "WHISPER_TAB_OFFLINE_SELECTED",
- "WHISPER_TAB_OFFLINE_SELECTED_OUTLINE",
- "IS",
- "IS_OUTLINE",
- "SERVER",
- "SERVER_OUTLINE",
- "LOGGER",
- "LOGGER_OUTLINE",
- "HYPERLINK",
- "HYPERLINK_OUTLINE",
- "UNKNOWN_ITEM",
- "UNKNOWN_ITEM_OUTLINE",
- "GENERIC",
- "GENERIC_OUTLINE",
- "HEAD",
- "HEAD_OUTLINE",
- "USABLE",
- "USABLE_OUTLINE",
- "TORSO",
- "TORSO_OUTLINE",
- "ONEHAND",
- "ONEHAND_OUTLINE",
- "LEGS",
- "LEGS_OUTLINE",
- "FEET",
- "FEET_OUTLINE",
- "TWOHAND",
- "TWOHAND_OUTLINE",
- "SHIELD",
- "SHIELD_OUTLINE",
- "RING",
- "RING_OUTLINE",
- "NECKLACE",
- "NECKLACE_OUTLINE",
- "ARMS",
- "ARMS_OUTLINE",
- "AMMO",
- "AMMO_OUTLINE",
- "SERVER_VERSION_NOT_SUPPORTED",
- "SERVER_VERSION_NOT_SUPPORTED_OUTLINE",
- "WARNING",
- "WARNING_OUTLINE",
- "CHARM",
- "CHARM_OUTLINE",
- "CARD",
- "CARD_OUTLINE",
- "PLAYER_ADVANCED",
- "PLAYER_ADVANCED_OUTLINE",
- "BUBBLE_NAME",
- "BUBBLE_NAME_OUTLINE",
- "BUBBLE_TEXT",
- "BUBBLE_TEXT_OUTLINE",
- "BLACK",
- "BLACK_OUTLINE",
- "RED",
- "RED_OUTLINE",
- "GREEN",
- "GREEN_OUTLINE",
- "BLUE",
- "BLUE_OUTLINE",
- "ORANGE",
- "ORANGE_OUTLINE",
- "YELLOW",
- "YELLOW_OUTLINE",
- "PINK",
- "PINK_OUTLINE",
- "PURPLE",
- "PURPLE_OUTLINE",
- "GRAY",
- "GRAY_OUTLINE",
- "BROWN",
- "BROWN_OUTLINE",
- "STATUSBAR_ON",
- "STATUSBAR_OFF",
- "TABLE_BACKGROUND",
- "SLOTS_BAR",
- "SLOTS_BAR_OUTLINE",
- "HP_BAR",
- "HP_BAR_OUTLINE",
- "MP_BAR",
- "MP_BAR_OUTLINE",
- "NO_MP_BAR",
- "NO_MP_BAR_OUTLINE",
- "XP_BAR",
- "XP_BAR_OUTLINE",
- "WEIGHT_BAR",
- "WEIGHT_BAR_OUTLINE",
- "MONEY_BAR",
- "MONEY_BAR_OUTLINE",
- "ARROWS_BAR",
- "ARROWS_BAR_OUTLINE",
- "STATUS_BAR",
- "STATUS_BAR_OUTLINE",
- "JOB_BAR",
- "JOB_BAR_OUTLINE",
- "OLDCHAT",
- "OLDCHAT_OUTLINE",
- "AWAYCHAT",
- "AWAYCHAT_OUTLINE",
- "SKILL_COOLDOWN",
- "TEXT_DISABLED",
- "TEXT_DISABLED_OUTLINE"
- };
-
- if (type.empty())
- return -1;
-
- for (int i = 0; i < CAST_S32(ThemeColorId::THEME_COLORS_END); i++)
- {
- if (compareStrI(type, colors[i]) == 0)
- return i;
- }
-
- return -1;
-}
-
-static Color readColor(const std::string &description)
-{
- const int size = static_cast<int>(description.length());
- if (size < 7 || description[0] != '#')
- {
- logger->log("Error, invalid theme color palette: %s",
- description.c_str());
- return Palette::BLACK;
- }
-
- unsigned int v = 0;
- for (int i = 1; i < 7; ++i)
- {
- signed const 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
- {
- logger->log("Error, invalid theme color palette: %s",
- description.c_str());
- return Palette::BLACK;
- }
-
- v = (v << 4) | n;
- }
-
- return Color(v);
-}
-
-static GradientTypeT readColorGradient(const std::string &grad)
-{
- static const std::string grads[] =
- {
- "STATIC",
- "PULSE",
- "SPECTRUM",
- "RAINBOW"
- };
-
- if (grad.empty())
- return GradientType::STATIC;
-
- for (int i = 0; i < 4; i++)
- {
- if (compareStrI(grad, grads[i]) != 0)
- return static_cast<GradientTypeT>(i);
- }
-
- return GradientType::STATIC;
-}
-
-static int readProgressType(const std::string &type)
-{
- static const std::string colors[CAST_SIZE(
- ProgressColorId::THEME_PROG_END)] =
- {
- "HP",
- "HP_POISON",
- "MP",
- "NO_MP",
- "EXP",
- "INVY_SLOTS",
- "WEIGHT",
- "JOB",
- "UPDATE",
- "MONEY",
- "ARROWS",
- "STATUS"
- };
-
- if (type.empty())
- return -1;
-
- for (int i = 0; i < CAST_S32(ProgressColorId::THEME_PROG_END); i++)
- {
- if (compareStrI(type, colors[i]) == 0)
- return i;
- }
-
- return -1;
-}
-
-void Theme::loadColors(std::string file)
-{
- if (file.empty())
- file = "colors.xml";
- else
- file = pathJoin(file, "colors.xml");
-
- XML::Document *const doc = Loader::getXml(resolveThemePath(file),
- UseVirtFs_true,
- SkipError_false);
- if (doc == nullptr)
- return;
- XmlNodeConstPtrConst root = doc->rootNode();
-
- if ((root == nullptr) || !xmlNameEqual(root, "colors"))
- {
- logger->log("Error loading colors file: %s", file.c_str());
- doc->decRef();
- return;
- }
-
- logger->log("Loading colors file: %s", file.c_str());
-
- for_each_xml_child_node(paletteNode, root)
- {
- if (xmlNameEqual(paletteNode, "progressbar"))
- {
- const int type = readProgressType(XML::getProperty(
- paletteNode, "id", ""));
- if (type < 0)
- continue;
-
- mProgressColors[type] = new DyePalette(XML::getProperty(
- paletteNode, "color", ""), 6);
- }
- else if (!xmlNameEqual(paletteNode, "palette"))
- {
- continue;
- }
-
- const int paletteId = XML::getProperty(paletteNode, "id", 1);
- if (paletteId < 0 || paletteId >= THEME_PALETTES)
- continue;
-
- for_each_xml_child_node(node, paletteNode)
- {
- if (xmlNameEqual(node, "color"))
- {
- const std::string id = XML::getProperty(node, "id", "");
- const int type = readColorType(id);
- if (type < 0)
- continue;
-
- const std::string temp = XML::getProperty(node, "color", "");
- if (temp.empty())
- continue;
-
- const Color color = readColor(temp);
- const GradientTypeT grad = readColorGradient(
- XML::getProperty(node, "effect", ""));
- mColors[paletteId * CAST_SIZE(
- ThemeColorId::THEME_COLORS_END) + type].set(
- type, color, grad, 10);
-
- if (!findLast(id, "_OUTLINE"))
- {
- const int type2 = readColorType(id + "_OUTLINE");
- if (type2 < 0)
- continue;
- const int idx = paletteId
- * CAST_S32(ThemeColorId::THEME_COLORS_END);
- mColors[idx + type2] = mColors[idx + type];
- }
- }
- }
- }
- doc->decRef();
-}
-
-#define loadGrid() \
- { \
- const ImageRect &rect = skin->getBorder(); \
- for (int f = start; f <= end; f ++) \
- { \
- if (rect.grid[f]) \
- { \
- image.grid[f] = rect.grid[f]; \
- image.grid[f]->incRef(); \
- } \
- } \
- }
-
-void Theme::loadRect(ImageRect &image,
- const std::string &name,
- const std::string &name2,
- const int start,
- const int end)
-{
- Skin *const skin = load(name, name2, false);
- if (skin != nullptr)
- {
- loadGrid();
- unload(skin);
- }
-}
-
-Skin *Theme::loadSkinRect(ImageRect &image,
- const std::string &name,
- const std::string &name2,
- const int start,
- const int end)
-{
- Skin *const skin = load(name, name2);
- if (skin != nullptr)
- loadGrid();
- return skin;
-}
-
-void Theme::unloadRect(const ImageRect &rect,
- const int start,
- const int end)
-{
- for (int f = start; f <= end; f ++)
- {
- if (rect.grid[f] != nullptr)
- rect.grid[f]->decRef();
- }
-}
-
-Image *Theme::getImageFromThemeXml(const std::string &name,
- const std::string &name2)
-{
- if (theme == nullptr)
- return nullptr;
-
- Skin *const skin = theme->load(name, name2, false);
- if (skin != nullptr)
- {
- const ImageRect &rect = skin->getBorder();
- if (rect.grid[0] != nullptr)
- {
- Image *const image = rect.grid[0];
- image->incRef();
- theme->unload(skin);
- return image;
- }
- theme->unload(skin);
- }
- return nullptr;
-}
-
-ImageSet *Theme::getImageSetFromThemeXml(const std::string &name,
- const std::string &name2,
- const int w, const int h)
-{
- if (theme == nullptr)
- return nullptr;
-
- Skin *const skin = theme->load(name, name2, false);
- if (skin != nullptr)
- {
- const ImageRect &rect = skin->getBorder();
- if (rect.grid[0] != nullptr)
- {
- Image *const image = rect.grid[0];
- const SDL_Rect &rect2 = image->mBounds;
- if ((rect2.w != 0u) && (rect2.h != 0u))
- {
- ImageSet *const imageSet = Loader::getSubImageSet(
- image, w, h);
- theme->unload(skin);
- return imageSet;
- }
- }
- theme->unload(skin);
- }
- return nullptr;
-}
-
-#define readValue(name) \
- { \
- tmpData = reinterpret_cast<XmlChar*>( \
- XmlNodeGetContent(infoNode)); \
- info->name = tmpData; \
- XmlFree(tmpData); \
- }
-
-#define readIntValue(name) \
- { \
- tmpData = reinterpret_cast<XmlChar*>( \
- XmlNodeGetContent(infoNode)); \
- info->name = atoi(tmpData); \
- XmlFree(tmpData); \
- }
-
-#define readFloatValue(name) \
- { \
- tmpData = reinterpret_cast<XmlChar*>( \
- XmlNodeGetContent(infoNode)); \
- info->name = static_cast<float>(atof(tmpData)); \
- XmlFree(tmpData); \
- }
-
-ThemeInfo *Theme::loadInfo(const std::string &themeName)
-{
- std::string path;
- if (themeName.empty())
- {
- path = "graphics/gui/info.xml";
- }
- else
- {
- path = pathJoin(defaultThemePath,
- themeName,
- "info.xml");
- }
- logger->log("loading: " + path);
- XML::Document *const doc = Loader::getXml(path,
- UseVirtFs_true,
- SkipError_false);
- if (doc == nullptr)
- return nullptr;
- XmlNodeConstPtrConst rootNode = doc->rootNode();
-
- if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "info"))
- {
- doc->decRef();
- return nullptr;
- }
-
- ThemeInfo *const info = new ThemeInfo;
-
- const std::string fontSize2("fontSize_" + mScreenDensity);
- const std::string npcfontSize2("npcfontSize_" + mScreenDensity);
- XmlChar *tmpData = nullptr;
- for_each_xml_child_node(infoNode, rootNode)
- {
- if (xmlNameEqual(infoNode, "name"))
- readValue(name)
- else if (xmlNameEqual(infoNode, "copyright"))
- readValue(copyright)
- else if (xmlNameEqual(infoNode, "font"))
- readValue(font)
- else if (xmlNameEqual(infoNode, "boldFont"))
- readValue(boldFont)
- else if (xmlNameEqual(infoNode, "particleFont"))
- readValue(particleFont)
- else if (xmlNameEqual(infoNode, "helpFont"))
- readValue(helpFont)
- else if (xmlNameEqual(infoNode, "secureFont"))
- readValue(secureFont)
- else if (xmlNameEqual(infoNode, "npcFont"))
- readValue(npcFont)
- else if (xmlNameEqual(infoNode, "japanFont"))
- readValue(japanFont)
- else if (xmlNameEqual(infoNode, "chinaFont"))
- readValue(chinaFont)
- else if (xmlNameEqual(infoNode, "fontSize"))
- readIntValue(fontSize)
- else if (xmlNameEqual(infoNode, "npcfontSize"))
- readIntValue(npcfontSize)
- else if (xmlNameEqual(infoNode, "guialpha"))
- readFloatValue(guiAlpha)
- else if (xmlNameEqual(infoNode, fontSize2.c_str()))
- readIntValue(fontSize)
- else if (xmlNameEqual(infoNode, npcfontSize2.c_str()))
- readIntValue(npcfontSize)
- }
- doc->decRef();
- return info;
-}
-
-ThemeColorIdT Theme::getIdByChar(const signed char c, bool &valid) const
-{
- const CharColors::const_iterator it = mCharColors.find(c);
- if (it != mCharColors.end())
- {
- valid = true;
- return static_cast<ThemeColorIdT>((*it).second);
- }
-
- valid = false;
- return ThemeColorId::BROWSERBOX;
-}