From 7773f04b4beb1a24214fe1a367b645a689d2c852 Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Mon, 2 Aug 2010 23:54:57 -0600 Subject: Move Theme and UserPalette to the resources folder Reviewed-by: Yohann Ferreira --- src/CMakeLists.txt | 8 +- src/Makefile.am | 8 +- src/actorsprite.cpp | 3 +- src/being.cpp | 4 +- src/client.cpp | 4 +- src/gui/emotepopup.cpp | 3 +- src/gui/equipmentwindow.cpp | 2 +- src/gui/gui.cpp | 2 +- src/gui/inventorywindow.cpp | 2 +- src/gui/itempopup.cpp | 2 +- src/gui/minimap.cpp | 2 +- src/gui/ministatus.cpp | 3 +- src/gui/serverdialog.cpp | 4 +- src/gui/setup_colors.cpp | 5 +- src/gui/skilldialog.cpp | 2 +- src/gui/socialwindow.cpp | 3 +- src/gui/specialswindow.cpp | 2 +- src/gui/speechbubble.cpp | 3 +- src/gui/speechbubble.h | 4 +- src/gui/statuswindow.cpp | 3 +- src/gui/theme.cpp | 572 ----------------------------- src/gui/theme.h | 250 ------------- src/gui/userpalette.cpp | 237 ------------ src/gui/userpalette.h | 207 ----------- src/gui/widgets/avatarlistbox.cpp | 2 +- src/gui/widgets/browserbox.cpp | 4 +- src/gui/widgets/button.cpp | 2 +- src/gui/widgets/checkbox.cpp | 2 +- src/gui/widgets/dropdown.cpp | 2 +- src/gui/widgets/emoteshortcutcontainer.cpp | 2 +- src/gui/widgets/itemcontainer.cpp | 2 +- src/gui/widgets/itemshortcutcontainer.cpp | 2 +- src/gui/widgets/label.cpp | 2 +- src/gui/widgets/listbox.cpp | 3 +- src/gui/widgets/playerbox.cpp | 3 +- src/gui/widgets/popup.cpp | 2 +- src/gui/widgets/progressbar.cpp | 2 +- src/gui/widgets/progressindicator.cpp | 3 +- src/gui/widgets/radiobutton.cpp | 3 +- src/gui/widgets/resizegrip.cpp | 3 +- src/gui/widgets/scrollarea.cpp | 3 +- src/gui/widgets/shoplistbox.cpp | 2 +- src/gui/widgets/slider.cpp | 3 +- src/gui/widgets/tab.cpp | 2 +- src/gui/widgets/table.cpp | 3 +- src/gui/widgets/textbox.cpp | 2 +- src/gui/widgets/textfield.cpp | 2 +- src/gui/widgets/whispertab.cpp | 4 +- src/gui/widgets/window.cpp | 2 +- src/item.cpp | 4 +- src/localplayer.cpp | 4 +- src/localplayer.h | 2 +- src/net/tmwa/gui/guildtab.cpp | 3 +- src/net/tmwa/gui/partytab.cpp | 3 +- src/resources/theme.cpp | 572 +++++++++++++++++++++++++++++ src/resources/theme.h | 250 +++++++++++++ src/resources/userpalette.cpp | 237 ++++++++++++ src/resources/userpalette.h | 207 +++++++++++ src/text.cpp | 2 +- src/textrenderer.h | 2 +- 60 files changed, 1340 insertions(+), 1343 deletions(-) delete mode 100644 src/gui/theme.cpp delete mode 100644 src/gui/theme.h delete mode 100644 src/gui/userpalette.cpp delete mode 100644 src/gui/userpalette.h create mode 100644 src/resources/theme.cpp create mode 100644 src/resources/theme.h create mode 100644 src/resources/userpalette.cpp create mode 100644 src/resources/userpalette.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9e4d43e3..ba929208 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -296,8 +296,6 @@ SET(SRCS gui/textdialog.h gui/textpopup.cpp gui/textpopup.h - gui/theme.cpp - gui/theme.h gui/trade.cpp gui/trade.h gui/truetypefont.cpp @@ -306,8 +304,6 @@ SET(SRCS gui/unregisterdialog.h gui/updatewindow.cpp gui/updatewindow.h - gui/userpalette.cpp - gui/userpalette.h gui/viewport.cpp gui/viewport.h gui/windowmenu.cpp @@ -386,6 +382,10 @@ SET(SRCS resources/specialdb.h resources/spritedef.h resources/spritedef.cpp + resources/theme.cpp + resources/theme.h + resources/userpalette.cpp + resources/userpalette.h resources/wallpaper.cpp resources/wallpaper.h utils/base64.cpp diff --git a/src/Makefile.am b/src/Makefile.am index fdec70be..6de1e6dd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -193,8 +193,6 @@ mana_SOURCES = gui/widgets/avatarlistbox.cpp \ gui/textdialog.h \ gui/textpopup.cpp \ gui/textpopup.h \ - gui/theme.cpp \ - gui/theme.h \ gui/trade.cpp \ gui/trade.h \ gui/truetypefont.cpp \ @@ -203,8 +201,6 @@ mana_SOURCES = gui/widgets/avatarlistbox.cpp \ gui/unregisterdialog.h \ gui/updatewindow.cpp \ gui/updatewindow.h \ - gui/userpalette.cpp \ - gui/userpalette.h \ gui/viewport.cpp \ gui/viewport.h \ gui/windowmenu.cpp \ @@ -283,6 +279,10 @@ mana_SOURCES = gui/widgets/avatarlistbox.cpp \ resources/specialdb.cpp \ resources/spritedef.h \ resources/spritedef.cpp \ + resources/theme.cpp \ + resources/theme.h \ + resources/userpalette.cpp \ + resources/userpalette.h \ resources/wallpaper.cpp \ resources/wallpaper.h \ utils/base64.cpp \ diff --git a/src/actorsprite.cpp b/src/actorsprite.cpp index 3d0e7d54..535708f0 100644 --- a/src/actorsprite.cpp +++ b/src/actorsprite.cpp @@ -31,13 +31,12 @@ #include "sound.h" #include "statuseffect.h" -#include "gui/theme.h" - #include "net/net.h" #include "resources/image.h" #include "resources/imageset.h" #include "resources/resourcemanager.h" +#include "resources/theme.h" #include diff --git a/src/being.cpp b/src/being.cpp index 280a5a1b..344636a5 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -42,8 +42,6 @@ #include "gui/gui.h" #include "gui/socialwindow.h" #include "gui/speechbubble.h" -#include "gui/theme.h" -#include "gui/userpalette.h" #include "net/charhandler.h" #include "net/gamehandler.h" @@ -60,6 +58,8 @@ #include "resources/monsterdb.h" #include "resources/npcdb.h" #include "resources/resourcemanager.h" +#include "resources/theme.h" +#include "resources/userpalette.h" #include "utils/dtor.h" #include "utils/stringutils.h" diff --git a/src/client.cpp b/src/client.cpp index 23f7a76d..4209e2fa 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -49,10 +49,8 @@ #include "gui/sdlinput.h" #include "gui/serverdialog.h" #include "gui/setup.h" -#include "gui/theme.h" #include "gui/unregisterdialog.h" #include "gui/updatewindow.h" -#include "gui/userpalette.h" #include "gui/worldselectdialog.h" #include "gui/widgets/button.h" @@ -74,6 +72,8 @@ #include "resources/specialdb.h" #include "resources/npcdb.h" #include "resources/resourcemanager.h" +#include "resources/theme.h" +#include "resources/userpalette.h" #include "utils/gettext.h" #include "utils/mkdir.h" diff --git a/src/gui/emotepopup.cpp b/src/gui/emotepopup.cpp index 3e06fdcf..f9dc8e0f 100644 --- a/src/gui/emotepopup.cpp +++ b/src/gui/emotepopup.cpp @@ -29,11 +29,10 @@ #include "localplayer.h" #include "log.h" -#include "gui/theme.h" - #include "resources/emotedb.h" #include "resources/image.h" #include "resources/iteminfo.h" +#include "resources/theme.h" #include "utils/dtor.h" diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp index 43e330f4..dcc372cd 100644 --- a/src/gui/equipmentwindow.cpp +++ b/src/gui/equipmentwindow.cpp @@ -29,7 +29,6 @@ #include "gui/equipmentwindow.h" #include "gui/itempopup.h" -#include "gui/theme.h" #include "gui/setup.h" #include "gui/viewport.h" @@ -41,6 +40,7 @@ #include "resources/image.h" #include "resources/iteminfo.h" #include "resources/resourcemanager.h" +#include "resources/theme.h" #include "utils/gettext.h" #include "utils/stringutils.h" diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 0fff3496..f8dc3e82 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -24,7 +24,6 @@ #include "gui/focushandler.h" #include "gui/palette.h" #include "gui/sdlinput.h" -#include "gui/theme.h" #include "gui/truetypefont.h" #include "gui/widgets/window.h" @@ -39,6 +38,7 @@ #include "resources/imageset.h" #include "resources/imageloader.h" #include "resources/resourcemanager.h" +#include "resources/theme.h" #include #include diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index 3bb84ab8..41ac96b4 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -30,7 +30,6 @@ #include "gui/itemamount.h" #include "gui/setup.h" #include "gui/sdlinput.h" -#include "gui/theme.h" #include "gui/viewport.h" #include "gui/widgets/button.h" @@ -44,6 +43,7 @@ #include "net/net.h" #include "resources/iteminfo.h" +#include "resources/theme.h" #include "utils/gettext.h" #include "utils/stringutils.h" diff --git a/src/gui/itempopup.cpp b/src/gui/itempopup.cpp index 5e7271ea..ce4d1126 100644 --- a/src/gui/itempopup.cpp +++ b/src/gui/itempopup.cpp @@ -26,7 +26,6 @@ #include "units.h" #include "gui/gui.h" -#include "gui/theme.h" #include "gui/widgets/icon.h" #include "gui/widgets/textbox.h" @@ -36,6 +35,7 @@ #include "resources/image.h" #include "resources/resourcemanager.h" +#include "resources/theme.h" #include diff --git a/src/gui/minimap.cpp b/src/gui/minimap.cpp index 1d01f48c..dd447f95 100644 --- a/src/gui/minimap.cpp +++ b/src/gui/minimap.cpp @@ -30,10 +30,10 @@ #include "map.h" #include "gui/setup.h" -#include "gui/userpalette.h" #include "resources/image.h" #include "resources/resourcemanager.h" +#include "resources/userpalette.h" #include "utils/gettext.h" diff --git a/src/gui/ministatus.cpp b/src/gui/ministatus.cpp index 620754ef..1642d1b0 100644 --- a/src/gui/ministatus.cpp +++ b/src/gui/ministatus.cpp @@ -30,7 +30,6 @@ #include "gui/gui.h" #include "gui/statuswindow.h" #include "gui/textpopup.h" -#include "gui/theme.h" #include "gui/widgets/progressbar.h" @@ -38,6 +37,8 @@ #include "net/playerhandler.h" #include "net/gamehandler.h" +#include "resources/theme.h" + #include "utils/gettext.h" #include "utils/stringutils.h" diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp index b1375ad0..115b582c 100644 --- a/src/gui/serverdialog.cpp +++ b/src/gui/serverdialog.cpp @@ -30,7 +30,6 @@ #include "gui/okdialog.h" #include "gui/sdlinput.h" -#include "gui/theme.h" #include "gui/widgets/button.h" #include "gui/widgets/dropdown.h" @@ -42,10 +41,11 @@ #include "net/net.h" +#include "resources/theme.h" + #include "utils/gettext.h" #include "utils/stringutils.h" #include "utils/xml.h" -#include "widgets/dropdown.h" #include diff --git a/src/gui/setup_colors.cpp b/src/gui/setup_colors.cpp index 12dba82a..6b3b3fec 100644 --- a/src/gui/setup_colors.cpp +++ b/src/gui/setup_colors.cpp @@ -23,8 +23,6 @@ #include "configuration.h" #include "gui/gui.h" -#include "gui/theme.h" -#include "gui/userpalette.h" #include "gui/widgets/browserbox.h" #include "gui/widgets/itemlinkhandler.h" @@ -36,6 +34,9 @@ #include "gui/widgets/textfield.h" #include "gui/widgets/textpreview.h" +#include "resources/theme.h" +#include "resources/userpalette.h" + #include "utils/gettext.h" #include "utils/stringutils.h" diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index c990274a..168553f6 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -26,7 +26,6 @@ #include "configuration.h" #include "gui/setup.h" -#include "gui/theme.h" #include "gui/widgets/button.h" #include "gui/widgets/container.h" @@ -44,6 +43,7 @@ #include "resources/image.h" #include "resources/resourcemanager.h" +#include "resources/theme.h" #include "utils/dtor.h" #include "utils/gettext.h" diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp index cd9471aa..8911c8fd 100644 --- a/src/gui/socialwindow.cpp +++ b/src/gui/socialwindow.cpp @@ -29,7 +29,6 @@ #include "gui/okdialog.h" #include "gui/setup.h" #include "gui/textdialog.h" -#include "gui/theme.h" #include "gui/widgets/avatarlistbox.h" #include "gui/widgets/browserbox.h" @@ -47,6 +46,8 @@ #include "net/guildhandler.h" #include "net/partyhandler.h" +#include "resources/theme.h" + #include "utils/dtor.h" #include "utils/gettext.h" #include "utils/stringutils.h" diff --git a/src/gui/specialswindow.cpp b/src/gui/specialswindow.cpp index c751d6cb..b511e4a3 100644 --- a/src/gui/specialswindow.cpp +++ b/src/gui/specialswindow.cpp @@ -23,7 +23,6 @@ #include "log.h" #include "gui/setup.h" -#include "gui/theme.h" #include "gui/widgets/button.h" #include "gui/widgets/container.h" @@ -42,6 +41,7 @@ #include "net/specialhandler.h" #include "resources/specialdb.h" +#include "resources/theme.h" #include "utils/dtor.h" #include "utils/gettext.h" diff --git a/src/gui/speechbubble.cpp b/src/gui/speechbubble.cpp index 08d00038..af42feb7 100644 --- a/src/gui/speechbubble.cpp +++ b/src/gui/speechbubble.cpp @@ -25,10 +25,11 @@ #include "graphics.h" #include "gui/gui.h" -#include "gui/theme.h" #include "gui/widgets/textbox.h" +#include "resources/theme.h" + #include #include diff --git a/src/gui/speechbubble.h b/src/gui/speechbubble.h index 8682ab7e..6017398a 100644 --- a/src/gui/speechbubble.h +++ b/src/gui/speechbubble.h @@ -23,10 +23,10 @@ #ifndef SPEECHBUBBLE_H #define SPEECHBUBBLE_H -#include "gui/theme.h" - #include "gui/widgets/popup.h" +#include "resources/theme.h" + class TextBox; class SpeechBubble : public Popup diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp index 3dd50232..493f5ee6 100644 --- a/src/gui/statuswindow.cpp +++ b/src/gui/statuswindow.cpp @@ -26,7 +26,6 @@ #include "units.h" #include "gui/setup.h" -#include "gui/theme.h" #include "gui/widgets/button.h" #include "gui/widgets/label.h" @@ -40,6 +39,8 @@ #include "net/playerhandler.h" #include "net/gamehandler.h" +#include "resources/theme.h" + #include "utils/gettext.h" #include "utils/mathutils.h" #include "utils/stringutils.h" diff --git a/src/gui/theme.cpp b/src/gui/theme.cpp deleted file mode 100644 index 152bf773..00000000 --- a/src/gui/theme.cpp +++ /dev/null @@ -1,572 +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 . - */ - -#include "gui/theme.h" - -#include "client.h" -#include "configuration.h" -#include "log.h" - -#include "resources/dye.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 - -#include - -static std::string defaultThemePath; -std::string Theme::mThemePath; -Theme *Theme::mInstance = 0; - -// Set the theme path... -static void initDefaultThemePath() -{ - ResourceManager *resman = ResourceManager::getInstance(); - defaultThemePath = branding.getStringValue("guiThemePath"); - - if (!defaultThemePath.empty() && resman->isDirectory(defaultThemePath)) - return; - else - defaultThemePath = "graphics/gui/"; -} - -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(minimumOpacityAllowed, - config.getFloatValue("guialpha")); - - 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(); -} - -Theme::Theme(): - Palette(THEME_COLORS_END), - mMinimumOpacity(-1.0f), - mProgressColors(ProgressColors(THEME_PROG_END)) -{ - initDefaultThemePath(); - - config.addListener("guialpha", this); - loadColors(); - - mColors[HIGHLIGHT].ch = 'H'; - mColors[CHAT].ch = 'C'; - mColors[GM].ch = 'G'; - mColors[PLAYER].ch = 'Y'; - mColors[WHISPER].ch = 'W'; - mColors[IS].ch = 'I'; - mColors[PARTY].ch = 'P'; - mColors[GUILD].ch = 'U'; - mColors[SERVER].ch = 'S'; - mColors[LOGGER].ch = 'L'; - mColors[HYPERLINK].ch = '<'; -} - -Theme::~Theme() -{ - delete_all(mSkins); - config.removeListener("guialpha", this); - delete_all(mProgressColors); -} - -Theme *Theme::instance() -{ - if (!mInstance) - mInstance = new Theme; - - return mInstance; -} - -void Theme::deleteInstance() -{ - delete mInstance; - mInstance = 0; -} - -gcn::Color Theme::getProgressColor(int type, float progress) -{ - DyePalette *dye = mInstance->mProgressColors[type]; - - int color[3] = {0, 0, 0}; - dye->getColor(progress, 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 - 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 Theme::setMinimumOpacity(float minimumOpacity) -{ - if (minimumOpacity > 1.0f) return; - - mMinimumOpacity = minimumOpacity; - updateAlpha(); -} - -void Theme::updateAlpha() -{ - for (SkinIterator iter = mSkins.begin(); iter != mSkins.end(); ++iter) - iter->second->updateAlpha(mMinimumOpacity); -} - -void Theme::optionChanged(const std::string &) -{ - updateAlpha(); -} - -Skin *Theme::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("Theme::readSkin(): Skinset does not define an image!"); - return 0; - } - - logger->log("Theme::load(): defines '%s' as a skin image.", - skinSetImage.c_str()); - - Image *dBorders = Theme::getImageFromTheme(skinSetImage); - ImageRect border; - memset(&border, 0, sizeof(ImageRect)); - - // iterate '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 '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("Theme::readSkin(): Unknown part type '%s'", - partType.c_str()); - } - } - else - { - logger->log("Theme::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 = Theme::getImageFromTheme("close_button.png"); - Image *sticky = Theme::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 Theme::tryThemePath(std::string themePath) -{ - if (!themePath.empty()) - { - themePath = defaultThemePath + themePath; - if (PHYSFS_exists(themePath.c_str())) - { - mThemePath = themePath; - return true; - } - } - - return false; -} - -void Theme::prepareThemePath() -{ - // Try theme from settings - if (!tryThemePath(config.getStringValue("theme"))) - // Try theme from branding - if (!tryThemePath(branding.getStringValue("theme"))) - // Use default - mThemePath = defaultThemePath; - - instance()->loadColors(mThemePath); -} - -std::string Theme::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 std::string(defaultThemePath) + "/" + path; -} - -Image *Theme::getImageFromTheme(const std::string &path) -{ - ResourceManager *resman = ResourceManager::getInstance(); - return resman->getImage(resolveThemePath(path)); -} - -ImageSet *Theme::getImageSetFromTheme(const std::string &path, - int w, int h) -{ - 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", - "SERVER_VERSION_NOT_SUPPORTED" - }; - - 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 == defaultThemePath) - return; // No need to reload - - if (file == "") - file = defaultThemePath; - - 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, 10); - } - else 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", "")); - } - } -} diff --git a/src/gui/theme.h b/src/gui/theme.h deleted file mode 100644 index 6798bed5..00000000 --- a/src/gui/theme.h +++ /dev/null @@ -1,250 +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 . - */ - -#ifndef SKIN_H -#define SKIN_H - -#include "configlistener.h" -#include "graphics.h" - -#include "gui/palette.h" - -#include -#include - -class DyePalette; -class Image; -class ImageSet; -class ProgressBar; - -class Skin -{ - public: - Skin(ImageRect skin, Image *close, Image *stickyUp, Image *stickyDown, - const std::string &filePath, - const std::string &name = ""); - - ~Skin(); - - /** - * Returns the skin's name. Useful for giving a human friendly skin - * name if a dialog for skin selection for a specific window type is - * done. - */ - const std::string &getName() const { return mName; } - - /** - * Returns the skin's xml file path. - */ - const std::string &getFilePath() const { return mFilePath; } - - /** - * Returns the background skin. - */ - const ImageRect &getBorder() const { return mBorder; } - - /** - * Returns the image used by a close button for this skin. - */ - Image *getCloseImage() const { return mCloseImage; } - - /** - * Returns the image used by a sticky button for this skin. - */ - Image *getStickyImage(bool state) const - { return state ? mStickyImageDown : mStickyImageUp; } - - /** - * Returns the minimum width which can be used with this skin. - */ - int getMinWidth() const; - - /** - * Returns the minimum height which can be used with this skin. - */ - int getMinHeight() const; - - /** - * Updates the alpha value of the skin - */ - void updateAlpha(float minimumOpacityAllowed = 0.0f); - - int instances; - - private: - std::string mFilePath; /**< File name path for the skin */ - std::string mName; /**< Name of the skin to use */ - ImageRect mBorder; /**< The window border and background */ - Image *mCloseImage; /**< Close Button Image */ - Image *mStickyImageUp; /**< Sticky Button Image */ - Image *mStickyImageDown; /**< Sticky Button Image */ -}; - -class Theme : public Palette, public ConfigListener -{ - public: - static Theme *instance(); - static void deleteInstance(); - - static void prepareThemePath(); - static std::string getThemePath() { return mThemePath; } - - /** - * Returns the patch to the given gui resource relative to the theme - * or, if it isn't in the theme, relative to 'graphics/gui'. - */ - static std::string resolveThemePath(const std::string &path); - - static Image *getImageFromTheme(const std::string &path); - static ImageSet *getImageSetFromTheme(const std::string &path, - int w, int h); - - enum ThemePalette { - 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, - SERVER_VERSION_NOT_SUPPORTED, - THEME_COLORS_END - }; - - enum ProgressPalette { - PROG_DEFAULT, - PROG_HP, - PROG_MP, - PROG_NO_MP, - PROG_EXP, - PROG_INVY_SLOTS, - PROG_WEIGHT, - PROG_JOB, - THEME_PROG_END - }; - - /** - * Gets the color associated with the type. Sets the alpha channel - * before returning. - * - * @param type the color type requested - * @param alpha alpha channel to use - * - * @return the requested color - */ - inline static const gcn::Color &getThemeColor(int type, int alpha = 255) - { - return mInstance->getColor(type, alpha); - } - - const static gcn::Color &getThemeColor(char c, bool &valid) - { - return mInstance->getColor(c, valid); - } - - static gcn::Color getProgressColor(int type, float progress); - - /** - * Loads a skin. - */ - Skin *load(const std::string &filename, - const std::string &defaultPath = getThemePath()); - - /** - * Updates the alpha values of all of the skins. - */ - void updateAlpha(); - - /** - * Get the minimum opacity allowed to skins. - */ - float getMinimumOpacity() - { return mMinimumOpacity; } - - /** - * Set the minimum opacity allowed to skins. - * Set a negative value to free the minimum allowed. - */ - void setMinimumOpacity(float minimumOpacity); - - void optionChanged(const std::string &); - - private: - Theme(); - ~Theme(); - - Skin *readSkin(const std::string &filename); - - // Map containing all window skins - typedef std::map Skins; - typedef Skins::iterator SkinIterator; - - Skins mSkins; - - static std::string mThemePath; - static Theme *mInstance; - - static bool tryThemePath(std::string themePath); - - void loadColors(std::string file = ""); - - /** - * Tells if the current skins opacity - * should not get less than the given value - */ - float mMinimumOpacity; - - typedef std::vector ProgressColors; - ProgressColors mProgressColors; -}; - -#endif diff --git a/src/gui/userpalette.cpp b/src/gui/userpalette.cpp deleted file mode 100644 index 0f30b752..00000000 --- a/src/gui/userpalette.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Configurable text colors - * Copyright (C) 2008 Douglas Boffey - * 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 . - */ - -#include "userpalette.h" - -#include "configuration.h" -#include "client.h" - -#include "gui/gui.h" - -#include "utils/gettext.h" -#include "utils/stringutils.h" - -#include - -const std::string ColorTypeNames[] = { - "Being", - "Player", - "Self", - "GM", - "NPC", - "Monster", - "Party", - "Guild", - "Particle", - "Experience", - "Pickup", - "Hit Player Monster", - "Hit Monster Player", - "Hit Critical", - "Miss" -}; - -std::string UserPalette::getConfigName(const std::string &typeName) -{ - std::string res = "Color" + typeName; - - int pos = 5; - for (size_t i = 0; i < typeName.length(); i++) - { - if (i == 0 || typeName[i] == '_') - { - if (i > 0) - i++; - - res[pos] = typeName[i]; - } - else - { - res[pos] = tolower(typeName[i]); - } - pos++; - } - res.erase(pos, res.length() - pos); - - return res; -} - -UserPalette::UserPalette(): - Palette(USER_COLOR_LAST) -{ - mColors[BEING] = ColorElem(); - mColors[PC] = ColorElem(); - mColors[SELF] = ColorElem(); - mColors[GM] = ColorElem(); - mColors[NPC] = ColorElem(); - mColors[MONSTER] = ColorElem(); - - addColor(BEING, 0xffffff, STATIC, _("Being")); - addColor(PC, 0xffffff, STATIC, _("Other Players' Names")); - addColor(SELF, 0xff8040, STATIC, _("Own Name")); - addColor(GM, 0x00ff00, STATIC, _("GM Names")); - addColor(NPC, 0xc8c8ff, STATIC, _("NPCs")); - addColor(MONSTER, 0xff4040, STATIC, _("Monsters")); - addColor(PARTY, 0xff00d8, STATIC, _("Party Members")); - addColor(GUILD, 0xff00d8, STATIC, _("Guild Members")); - addColor(PARTICLE, 0xffffff, STATIC, _("Particle Effects")); - addColor(PICKUP_INFO, 0x28dc28, STATIC, _("Pickup Notification")); - addColor(EXP_INFO, 0xffff00, STATIC, _("Exp Notification")); - addColor(HIT_PLAYER_MONSTER, 0x0064ff, STATIC, _("Player Hits Monster")); - addColor(HIT_MONSTER_PLAYER, 0xff3232, STATIC, _("Monster Hits Player")); - addColor(HIT_CRITICAL, 0xff0000, RAINBOW, _("Critical Hit")); - addColor(MISS, 0xffff00, STATIC, _("Misses")); - commit(true); -} - -UserPalette::~UserPalette() -{ - for (Colors::iterator col = mColors.begin(), - colEnd = mColors.end(); col != colEnd; ++col) - { - const std::string &configName = ColorTypeNames[col->type]; - config.setValue(configName + "Gradient", col->committedGrad); - - if (col->grad != STATIC) - config.setValue(configName + "Delay", col->delay); - - if (col->grad == STATIC || col->grad == PULSE) - { - char buffer[20]; - sprintf(buffer, "0x%06x", col->getRGB()); - config.setValue(configName, std::string(buffer)); - } - } -} - -void UserPalette::setColor(int type, int r, int g, int b) -{ - mColors[type].color.r = r; - mColors[type].color.g = g; - mColors[type].color.b = b; -} - -void UserPalette::setGradient(int type, GradientType grad) -{ - ColorElem *elem = &mColors[type]; - if (elem->grad != STATIC && grad == STATIC) - { - for (size_t i = 0; i < mGradVector.size(); i++) - { - if (mGradVector[i] == elem) - { - mGradVector.erase(mGradVector.begin() + i); - break; - } - } - } - else if (elem->grad == STATIC && grad != STATIC) - { - mGradVector.push_back(elem); - } - - if (elem->grad != grad) - { - elem->grad = grad; - } -} - -std::string UserPalette::getElementAt(int i) -{ - if (i < 0 || i >= getNumberOfElements()) - { - return ""; - } - return mColors[i].text; -} - -void UserPalette::commit(bool commitNonStatic) -{ - for (Colors::iterator i = mColors.begin(), iEnd = mColors.end(); - i != iEnd; ++i) - { - i->committedGrad = i->grad; - i->committedDelay = i->delay; - if (commitNonStatic || i->grad == STATIC) - { - i->committedColor = i->color; - } - else if (i->grad == PULSE) - { - i->committedColor = i->testColor; - } - } -} - -void UserPalette::rollback() -{ - for (Colors::iterator i = mColors.begin(), iEnd = mColors.end(); - i != iEnd; ++i) - { - if (i->grad != i->committedGrad) - { - setGradient(i->type, i->committedGrad); - } - setGradientDelay(i->type, i->committedDelay); - setColor(i->type, i->committedColor.r, - i->committedColor.g, i->committedColor.b); - if (i->grad == PULSE) - { - i->testColor.r = i->committedColor.r; - i->testColor.g = i->committedColor.g; - i->testColor.b = i->committedColor.b; - } - } -} - -int UserPalette::getColorTypeAt(int i) -{ - if (i < 0 || i >= getNumberOfElements()) - { - return BEING; - } - - return mColors[i].type; -} - -void UserPalette::addColor(int type, int rgb, Palette::GradientType grad, - const std::string &text, int delay) -{ - const std::string &configName = ColorTypeNames[type]; - char buffer[20]; - sprintf(buffer, "0x%06x", rgb); - const std::string rgbString = config.getValue(configName, - std::string(buffer)); - unsigned int rgbValue = 0; - if (rgbString.length() == 8 && rgbString[0] == '0' && rgbString[1] == 'x') - rgbValue = atox(rgbString); - else - rgbValue = atoi(rgbString.c_str()); - gcn::Color trueCol = rgbValue; - grad = (GradientType) config.getValue(configName + "Gradient", grad); - delay = (int) config.getValue(configName + "Delay", delay); - mColors[type].set(type, trueCol, grad, delay); - mColors[type].text = text; - - if (grad != STATIC) - mGradVector.push_back(&mColors[type]); -} diff --git a/src/gui/userpalette.h b/src/gui/userpalette.h deleted file mode 100644 index 82bcea1c..00000000 --- a/src/gui/userpalette.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Configurable text colors - * Copyright (C) 2008 Douglas Boffey - * 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 . - */ - -#ifndef USER_PALETTE_H -#define USER_PALETTE_H - -#include "gui/palette.h" - -#include - -/** - * Class controlling the game's color palette. - */ -class UserPalette : public Palette, public gcn::ListModel -{ - public: - /** List of all colors that are configurable. */ - enum { - BEING, - PC, - SELF, - GM, - NPC, - MONSTER, - PARTY, - GUILD, - PARTICLE, - EXP_INFO, - PICKUP_INFO, - HIT_PLAYER_MONSTER, - HIT_MONSTER_PLAYER, - HIT_CRITICAL, - MISS, - USER_COLOR_LAST - }; - - /** - * Constructor - */ - UserPalette(); - - /** - * Destructor - */ - ~UserPalette(); - - /** - * Gets the committed color associated with the specified type. - * - * @param type the color type requested - * - * @return the requested committed color - */ - inline const gcn::Color &getCommittedColor(int type) - { - return mColors[type].committedColor; - } - - /** - * Gets the test color associated with the specified type. - * - * @param type the color type requested - * - * @return the requested test color - */ - inline const gcn::Color &getTestColor(int type) - { - return mColors[type].testColor; - } - - /** - * Sets the test color associated with the specified type. - * - * @param type the color type requested - * @param color the color that should be tested - */ - inline void setTestColor(int type, gcn::Color color) - { - mColors[type].testColor = color; - } - - /** - * Sets the color for the specified type. - * - * @param type color to be set - * @param r red component - * @param g green component - * @param b blue component - */ - void setColor(int type, int r, int g, int b); - - /** - * Sets the gradient type for the specified color. - * - * @param grad gradient type to set - */ - void setGradient(int type, Palette::GradientType grad); - - /** - * Sets the gradient delay for the specified color. - * - * @param grad gradient type to set - */ - void setGradientDelay(int type, int delay) - { mColors[type].delay = delay; } - - /** - * Returns the number of colors known. - * - * @return the number of colors known - */ - inline int getNumberOfElements() { return mColors.size(); } - - /** - * Returns the name of the ith color. - * - * @param i index of color interested in - * - * @return the name of the color - */ - std::string getElementAt(int i); - - /** - * Commit the colors - */ - inline void commit() - { - commit(false); - } - - /** - * Rollback the colors - */ - void rollback(); - - /** - * Gets the ColorType used by the color for the element at index i in - * the current color model. - * - * @param i the index of the color - * - * @return the color type of the color with the given index - */ - int getColorTypeAt(int i); - - private: - /** - * Define a color replacement. - * - * @param i the index of the color to replace - * @param r red component - * @param g green component - * @param b blue component - */ - void setColorAt(int i, int r, int g, int b); - - /** - * Commit the colors. Commit the non-static color values, if - * commitNonStatic is true. Only needed in the constructor. - */ - void commit(bool commitNonStatic); - - /** - * Prefixes the given string with "Color", lowercases all letters but - * the first and all following a '_'. All '_'s will be removed. - * - * E.g.: HIT_PLAYER_MONSTER -> HitPlayerMonster - * - * @param typeName string to transform - * - * @return the transformed string - */ - static std::string getConfigName(const std::string &typeName); - - /** - * Initialise color - * - * @param c character that needs initialising - * @param rgb default color if not found in config - * @param text identifier of color - */ - void addColor(int type, int rgb, GradientType grad, - const std::string &text, int delay = GRADIENT_DELAY); -}; - -extern UserPalette *userPalette; - -#endif // USER_PALETTE_H diff --git a/src/gui/widgets/avatarlistbox.cpp b/src/gui/widgets/avatarlistbox.cpp index 6ec4d1e8..6551aa04 100644 --- a/src/gui/widgets/avatarlistbox.cpp +++ b/src/gui/widgets/avatarlistbox.cpp @@ -25,10 +25,10 @@ #include "gui/chat.h" #include "gui/gui.h" #include "gui/palette.h" -#include "gui/theme.h" #include "resources/image.h" #include "resources/resourcemanager.h" +#include "resources/theme.h" #include "utils/stringutils.h" diff --git a/src/gui/widgets/browserbox.cpp b/src/gui/widgets/browserbox.cpp index d43afed7..d890f138 100644 --- a/src/gui/widgets/browserbox.cpp +++ b/src/gui/widgets/browserbox.cpp @@ -21,10 +21,10 @@ #include "gui/widgets/browserbox.h" -#include "gui/theme.h" - #include "gui/widgets/linkhandler.h" +#include "resources/theme.h" + #include #include #include diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp index dbaa357c..3d3a07c2 100644 --- a/src/gui/widgets/button.cpp +++ b/src/gui/widgets/button.cpp @@ -25,9 +25,9 @@ #include "graphics.h" #include "gui/palette.h" -#include "gui/theme.h" #include "resources/image.h" +#include "resources/theme.h" #include "utils/dtor.h" diff --git a/src/gui/widgets/checkbox.cpp b/src/gui/widgets/checkbox.cpp index 64594940..6a44132d 100644 --- a/src/gui/widgets/checkbox.cpp +++ b/src/gui/widgets/checkbox.cpp @@ -25,9 +25,9 @@ #include "graphics.h" #include "gui/palette.h" -#include "gui/theme.h" #include "resources/image.h" +#include "resources/theme.h" int CheckBox::instances = 0; float CheckBox::mAlpha = 1.0; diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp index e694137d..ced9c38b 100644 --- a/src/gui/widgets/dropdown.cpp +++ b/src/gui/widgets/dropdown.cpp @@ -26,12 +26,12 @@ #include "gui/palette.h" #include "gui/sdlinput.h" -#include "gui/theme.h" #include "gui/widgets/listbox.h" #include "gui/widgets/scrollarea.h" #include "resources/image.h" +#include "resources/theme.h" #include "utils/dtor.h" diff --git a/src/gui/widgets/emoteshortcutcontainer.cpp b/src/gui/widgets/emoteshortcutcontainer.cpp index 28727429..7a24c464 100644 --- a/src/gui/widgets/emoteshortcutcontainer.cpp +++ b/src/gui/widgets/emoteshortcutcontainer.cpp @@ -32,10 +32,10 @@ #include "log.h" #include "gui/palette.h" -#include "gui/theme.h" #include "resources/emotedb.h" #include "resources/image.h" +#include "resources/theme.h" #include "utils/dtor.h" diff --git a/src/gui/widgets/itemcontainer.cpp b/src/gui/widgets/itemcontainer.cpp index 7648eb24..b98cac66 100644 --- a/src/gui/widgets/itemcontainer.cpp +++ b/src/gui/widgets/itemcontainer.cpp @@ -32,7 +32,6 @@ #include "gui/outfitwindow.h" #include "gui/palette.h" #include "gui/sdlinput.h" -#include "gui/theme.h" #include "gui/viewport.h" #include "net/net.h" @@ -40,6 +39,7 @@ #include "resources/image.h" #include "resources/iteminfo.h" +#include "resources/theme.h" #include "utils/stringutils.h" diff --git a/src/gui/widgets/itemshortcutcontainer.cpp b/src/gui/widgets/itemshortcutcontainer.cpp index 869264f7..f2982de9 100644 --- a/src/gui/widgets/itemshortcutcontainer.cpp +++ b/src/gui/widgets/itemshortcutcontainer.cpp @@ -32,11 +32,11 @@ #include "gui/inventorywindow.h" #include "gui/itempopup.h" #include "gui/palette.h" -#include "gui/theme.h" #include "gui/viewport.h" #include "resources/image.h" #include "resources/iteminfo.h" +#include "resources/theme.h" #include "utils/stringutils.h" diff --git a/src/gui/widgets/label.cpp b/src/gui/widgets/label.cpp index 4c607edf..cefddae0 100644 --- a/src/gui/widgets/label.cpp +++ b/src/gui/widgets/label.cpp @@ -20,7 +20,7 @@ #include "gui/widgets/label.h" -#include "gui/theme.h" +#include "resources/theme.h" Label::Label() { diff --git a/src/gui/widgets/listbox.cpp b/src/gui/widgets/listbox.cpp index 2193b888..d79d8d0c 100644 --- a/src/gui/widgets/listbox.cpp +++ b/src/gui/widgets/listbox.cpp @@ -25,7 +25,8 @@ #include "gui/palette.h" #include "gui/sdlinput.h" -#include "gui/theme.h" + +#include "resources/theme.h" #include #include diff --git a/src/gui/widgets/playerbox.cpp b/src/gui/widgets/playerbox.cpp index cc9e963e..559ac5a6 100644 --- a/src/gui/widgets/playerbox.cpp +++ b/src/gui/widgets/playerbox.cpp @@ -26,9 +26,8 @@ #include "configuration.h" #include "graphics.h" -#include "gui/theme.h" - #include "resources/image.h" +#include "resources/theme.h" #include "utils/dtor.h" diff --git a/src/gui/widgets/popup.cpp b/src/gui/widgets/popup.cpp index 4dc58f72..e242bcf4 100644 --- a/src/gui/widgets/popup.cpp +++ b/src/gui/widgets/popup.cpp @@ -26,12 +26,12 @@ #include "graphics.h" #include "log.h" -#include "gui/theme.h" #include "gui/viewport.h" #include "gui/widgets/windowcontainer.h" #include "resources/image.h" +#include "resources/theme.h" #include diff --git a/src/gui/widgets/progressbar.cpp b/src/gui/widgets/progressbar.cpp index 60c44fe2..15838952 100644 --- a/src/gui/widgets/progressbar.cpp +++ b/src/gui/widgets/progressbar.cpp @@ -27,9 +27,9 @@ #include "gui/gui.h" #include "gui/palette.h" -#include "gui/theme.h" #include "resources/image.h" +#include "resources/theme.h" #include "utils/dtor.h" diff --git a/src/gui/widgets/progressindicator.cpp b/src/gui/widgets/progressindicator.cpp index 6bda617f..91b40751 100644 --- a/src/gui/widgets/progressindicator.cpp +++ b/src/gui/widgets/progressindicator.cpp @@ -23,11 +23,10 @@ #include "graphics.h" #include "simpleanimation.h" -#include "gui/theme.h" - #include "resources/animation.h" #include "resources/imageset.h" #include "resources/resourcemanager.h" +#include "resources/theme.h" #include diff --git a/src/gui/widgets/radiobutton.cpp b/src/gui/widgets/radiobutton.cpp index 4cbc22e7..1296feb6 100644 --- a/src/gui/widgets/radiobutton.cpp +++ b/src/gui/widgets/radiobutton.cpp @@ -24,9 +24,8 @@ #include "configuration.h" #include "graphics.h" -#include "gui/theme.h" - #include "resources/image.h" +#include "resources/theme.h" int RadioButton::instances = 0; float RadioButton::mAlpha = 1.0; diff --git a/src/gui/widgets/resizegrip.cpp b/src/gui/widgets/resizegrip.cpp index 496e3727..7850643f 100644 --- a/src/gui/widgets/resizegrip.cpp +++ b/src/gui/widgets/resizegrip.cpp @@ -24,9 +24,8 @@ #include "configuration.h" #include "graphics.h" -#include "gui/theme.h" - #include "resources/image.h" +#include "resources/theme.h" #include diff --git a/src/gui/widgets/scrollarea.cpp b/src/gui/widgets/scrollarea.cpp index d8ffe5ab..7d42883a 100644 --- a/src/gui/widgets/scrollarea.cpp +++ b/src/gui/widgets/scrollarea.cpp @@ -24,9 +24,8 @@ #include "configuration.h" #include "graphics.h" -#include "gui/theme.h" - #include "resources/image.h" +#include "resources/theme.h" #include "utils/dtor.h" diff --git a/src/gui/widgets/shoplistbox.cpp b/src/gui/widgets/shoplistbox.cpp index b92ec6cb..c0a79500 100644 --- a/src/gui/widgets/shoplistbox.cpp +++ b/src/gui/widgets/shoplistbox.cpp @@ -26,12 +26,12 @@ #include "shopitem.h" #include "gui/itempopup.h" -#include "gui/theme.h" #include "gui/viewport.h" #include "gui/widgets/shopitems.h" #include "resources/image.h" +#include "resources/theme.h" #include #include diff --git a/src/gui/widgets/slider.cpp b/src/gui/widgets/slider.cpp index 00a8e86f..c044d55d 100644 --- a/src/gui/widgets/slider.cpp +++ b/src/gui/widgets/slider.cpp @@ -24,9 +24,8 @@ #include "configuration.h" #include "graphics.h" -#include "gui/theme.h" - #include "resources/image.h" +#include "resources/theme.h" Image *Slider::hStart, *Slider::hMid, *Slider::hEnd, *Slider::hGrip; Image *Slider::vStart, *Slider::vMid, *Slider::vEnd, *Slider::vGrip; diff --git a/src/gui/widgets/tab.cpp b/src/gui/widgets/tab.cpp index 503a8e55..10a51afe 100644 --- a/src/gui/widgets/tab.cpp +++ b/src/gui/widgets/tab.cpp @@ -25,11 +25,11 @@ #include "graphics.h" #include "gui/palette.h" -#include "gui/theme.h" #include "gui/widgets/tabbedarea.h" #include "resources/image.h" +#include "resources/theme.h" #include "utils/dtor.h" diff --git a/src/gui/widgets/table.cpp b/src/gui/widgets/table.cpp index 663d6d02..3d8680ce 100644 --- a/src/gui/widgets/table.cpp +++ b/src/gui/widgets/table.cpp @@ -24,7 +24,8 @@ #include "configuration.h" #include "gui/sdlinput.h" -#include "gui/theme.h" + +#include "resources/theme.h" #include "utils/dtor.h" diff --git a/src/gui/widgets/textbox.cpp b/src/gui/widgets/textbox.cpp index f248f35d..5b112e54 100644 --- a/src/gui/widgets/textbox.cpp +++ b/src/gui/widgets/textbox.cpp @@ -21,7 +21,7 @@ #include "gui/widgets/textbox.h" -#include "gui/theme.h" +#include "resources/theme.h" #include diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp index f89f6239..9696cd59 100644 --- a/src/gui/widgets/textfield.cpp +++ b/src/gui/widgets/textfield.cpp @@ -26,9 +26,9 @@ #include "gui/palette.h" #include "gui/sdlinput.h" -#include "gui/theme.h" #include "resources/image.h" +#include "resources/theme.h" #include "utils/copynpaste.h" #include "utils/dtor.h" diff --git a/src/gui/widgets/whispertab.cpp b/src/gui/widgets/whispertab.cpp index 685d28ab..864f1f51 100644 --- a/src/gui/widgets/whispertab.cpp +++ b/src/gui/widgets/whispertab.cpp @@ -25,11 +25,11 @@ #include "commandhandler.h" #include "localplayer.h" -#include "gui/theme.h" - #include "net/chathandler.h" #include "net/net.h" +#include "resources/theme.h" + #include "utils/gettext.h" #include "utils/stringutils.h" diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp index dafaaeed..aa8e6df3 100644 --- a/src/gui/widgets/window.cpp +++ b/src/gui/widgets/window.cpp @@ -26,7 +26,6 @@ #include "gui/gui.h" #include "gui/palette.h" -#include "gui/theme.h" #include "gui/viewport.h" #include "gui/widgets/layout.h" @@ -34,6 +33,7 @@ #include "gui/widgets/windowcontainer.h" #include "resources/image.h" +#include "resources/theme.h" #include #include diff --git a/src/item.cpp b/src/item.cpp index 83e12cef..6b13dd1b 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -21,12 +21,12 @@ #include "item.h" -#include "gui/theme.h" +#include "configuration.h" #include "resources/image.h" #include "resources/iteminfo.h" #include "resources/resourcemanager.h" -#include "configuration.h" +#include "resources/theme.h" Item::Item(int id, int quantity, bool equipment, bool equipped): mImage(0), diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 2d17cf90..7034cf31 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -39,8 +39,6 @@ #include "gui/gui.h" #include "gui/okdialog.h" -#include "gui/theme.h" -#include "gui/userpalette.h" #include "gui/widgets/chattab.h" @@ -57,6 +55,8 @@ #include "resources/imageset.h" #include "resources/iteminfo.h" #include "resources/resourcemanager.h" +#include "resources/theme.h" +#include "resources/userpalette.h" #include "utils/gettext.h" #include "utils/stringutils.h" diff --git a/src/localplayer.h b/src/localplayer.h index 64ff6e30..14ab5482 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -26,7 +26,7 @@ #include "being.h" #include "listener.h" -#include "gui/userpalette.h" +#include "resources/userpalette.h" #include diff --git a/src/net/tmwa/gui/guildtab.cpp b/src/net/tmwa/gui/guildtab.cpp index 8b788bad..ca922e55 100644 --- a/src/net/tmwa/gui/guildtab.cpp +++ b/src/net/tmwa/gui/guildtab.cpp @@ -26,13 +26,12 @@ #include "guild.h" #include "localplayer.h" -#include "gui/theme.h" - #include "net/net.h" #include "net/guildhandler.h" #include "resources/iteminfo.h" #include "resources/itemdb.h" +#include "resources/theme.h" #include "utils/dtor.h" #include "utils/gettext.h" diff --git a/src/net/tmwa/gui/partytab.cpp b/src/net/tmwa/gui/partytab.cpp index 0f3e8e24..d5781971 100644 --- a/src/net/tmwa/gui/partytab.cpp +++ b/src/net/tmwa/gui/partytab.cpp @@ -26,13 +26,12 @@ #include "localplayer.h" #include "party.h" -#include "gui/theme.h" - #include "net/net.h" #include "net/partyhandler.h" #include "resources/iteminfo.h" #include "resources/itemdb.h" +#include "resources/theme.h" #include "utils/dtor.h" #include "utils/gettext.h" diff --git a/src/resources/theme.cpp b/src/resources/theme.cpp new file mode 100644 index 00000000..6633f1e0 --- /dev/null +++ b/src/resources/theme.cpp @@ -0,0 +1,572 @@ +/* + * 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 . + */ + +#include "resources/theme.h" + +#include "client.h" +#include "configuration.h" +#include "log.h" + +#include "resources/dye.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 + +#include + +static std::string defaultThemePath; +std::string Theme::mThemePath; +Theme *Theme::mInstance = 0; + +// Set the theme path... +static void initDefaultThemePath() +{ + ResourceManager *resman = ResourceManager::getInstance(); + defaultThemePath = branding.getStringValue("guiThemePath"); + + if (!defaultThemePath.empty() && resman->isDirectory(defaultThemePath)) + return; + else + defaultThemePath = "graphics/gui/"; +} + +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(minimumOpacityAllowed, + config.getFloatValue("guialpha")); + + 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(); +} + +Theme::Theme(): + Palette(THEME_COLORS_END), + mMinimumOpacity(-1.0f), + mProgressColors(ProgressColors(THEME_PROG_END)) +{ + initDefaultThemePath(); + + config.addListener("guialpha", this); + loadColors(); + + mColors[HIGHLIGHT].ch = 'H'; + mColors[CHAT].ch = 'C'; + mColors[GM].ch = 'G'; + mColors[PLAYER].ch = 'Y'; + mColors[WHISPER].ch = 'W'; + mColors[IS].ch = 'I'; + mColors[PARTY].ch = 'P'; + mColors[GUILD].ch = 'U'; + mColors[SERVER].ch = 'S'; + mColors[LOGGER].ch = 'L'; + mColors[HYPERLINK].ch = '<'; +} + +Theme::~Theme() +{ + delete_all(mSkins); + config.removeListener("guialpha", this); + delete_all(mProgressColors); +} + +Theme *Theme::instance() +{ + if (!mInstance) + mInstance = new Theme; + + return mInstance; +} + +void Theme::deleteInstance() +{ + delete mInstance; + mInstance = 0; +} + +gcn::Color Theme::getProgressColor(int type, float progress) +{ + DyePalette *dye = mInstance->mProgressColors[type]; + + int color[3] = {0, 0, 0}; + dye->getColor(progress, 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 + 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 Theme::setMinimumOpacity(float minimumOpacity) +{ + if (minimumOpacity > 1.0f) return; + + mMinimumOpacity = minimumOpacity; + updateAlpha(); +} + +void Theme::updateAlpha() +{ + for (SkinIterator iter = mSkins.begin(); iter != mSkins.end(); ++iter) + iter->second->updateAlpha(mMinimumOpacity); +} + +void Theme::optionChanged(const std::string &) +{ + updateAlpha(); +} + +Skin *Theme::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("Theme::readSkin(): Skinset does not define an image!"); + return 0; + } + + logger->log("Theme::load(): defines '%s' as a skin image.", + skinSetImage.c_str()); + + Image *dBorders = Theme::getImageFromTheme(skinSetImage); + ImageRect border; + memset(&border, 0, sizeof(ImageRect)); + + // iterate '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 '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("Theme::readSkin(): Unknown part type '%s'", + partType.c_str()); + } + } + else + { + logger->log("Theme::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 = Theme::getImageFromTheme("close_button.png"); + Image *sticky = Theme::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 Theme::tryThemePath(std::string themePath) +{ + if (!themePath.empty()) + { + themePath = defaultThemePath + themePath; + if (PHYSFS_exists(themePath.c_str())) + { + mThemePath = themePath; + return true; + } + } + + return false; +} + +void Theme::prepareThemePath() +{ + // Try theme from settings + if (!tryThemePath(config.getStringValue("theme"))) + // Try theme from branding + if (!tryThemePath(branding.getStringValue("theme"))) + // Use default + mThemePath = defaultThemePath; + + instance()->loadColors(mThemePath); +} + +std::string Theme::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 std::string(defaultThemePath) + "/" + path; +} + +Image *Theme::getImageFromTheme(const std::string &path) +{ + ResourceManager *resman = ResourceManager::getInstance(); + return resman->getImage(resolveThemePath(path)); +} + +ImageSet *Theme::getImageSetFromTheme(const std::string &path, + int w, int h) +{ + 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", + "SERVER_VERSION_NOT_SUPPORTED" + }; + + 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 == defaultThemePath) + return; // No need to reload + + if (file == "") + file = defaultThemePath; + + 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, 10); + } + else 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", "")); + } + } +} diff --git a/src/resources/theme.h b/src/resources/theme.h new file mode 100644 index 00000000..6798bed5 --- /dev/null +++ b/src/resources/theme.h @@ -0,0 +1,250 @@ +/* + * 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 . + */ + +#ifndef SKIN_H +#define SKIN_H + +#include "configlistener.h" +#include "graphics.h" + +#include "gui/palette.h" + +#include +#include + +class DyePalette; +class Image; +class ImageSet; +class ProgressBar; + +class Skin +{ + public: + Skin(ImageRect skin, Image *close, Image *stickyUp, Image *stickyDown, + const std::string &filePath, + const std::string &name = ""); + + ~Skin(); + + /** + * Returns the skin's name. Useful for giving a human friendly skin + * name if a dialog for skin selection for a specific window type is + * done. + */ + const std::string &getName() const { return mName; } + + /** + * Returns the skin's xml file path. + */ + const std::string &getFilePath() const { return mFilePath; } + + /** + * Returns the background skin. + */ + const ImageRect &getBorder() const { return mBorder; } + + /** + * Returns the image used by a close button for this skin. + */ + Image *getCloseImage() const { return mCloseImage; } + + /** + * Returns the image used by a sticky button for this skin. + */ + Image *getStickyImage(bool state) const + { return state ? mStickyImageDown : mStickyImageUp; } + + /** + * Returns the minimum width which can be used with this skin. + */ + int getMinWidth() const; + + /** + * Returns the minimum height which can be used with this skin. + */ + int getMinHeight() const; + + /** + * Updates the alpha value of the skin + */ + void updateAlpha(float minimumOpacityAllowed = 0.0f); + + int instances; + + private: + std::string mFilePath; /**< File name path for the skin */ + std::string mName; /**< Name of the skin to use */ + ImageRect mBorder; /**< The window border and background */ + Image *mCloseImage; /**< Close Button Image */ + Image *mStickyImageUp; /**< Sticky Button Image */ + Image *mStickyImageDown; /**< Sticky Button Image */ +}; + +class Theme : public Palette, public ConfigListener +{ + public: + static Theme *instance(); + static void deleteInstance(); + + static void prepareThemePath(); + static std::string getThemePath() { return mThemePath; } + + /** + * Returns the patch to the given gui resource relative to the theme + * or, if it isn't in the theme, relative to 'graphics/gui'. + */ + static std::string resolveThemePath(const std::string &path); + + static Image *getImageFromTheme(const std::string &path); + static ImageSet *getImageSetFromTheme(const std::string &path, + int w, int h); + + enum ThemePalette { + 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, + SERVER_VERSION_NOT_SUPPORTED, + THEME_COLORS_END + }; + + enum ProgressPalette { + PROG_DEFAULT, + PROG_HP, + PROG_MP, + PROG_NO_MP, + PROG_EXP, + PROG_INVY_SLOTS, + PROG_WEIGHT, + PROG_JOB, + THEME_PROG_END + }; + + /** + * Gets the color associated with the type. Sets the alpha channel + * before returning. + * + * @param type the color type requested + * @param alpha alpha channel to use + * + * @return the requested color + */ + inline static const gcn::Color &getThemeColor(int type, int alpha = 255) + { + return mInstance->getColor(type, alpha); + } + + const static gcn::Color &getThemeColor(char c, bool &valid) + { + return mInstance->getColor(c, valid); + } + + static gcn::Color getProgressColor(int type, float progress); + + /** + * Loads a skin. + */ + Skin *load(const std::string &filename, + const std::string &defaultPath = getThemePath()); + + /** + * Updates the alpha values of all of the skins. + */ + void updateAlpha(); + + /** + * Get the minimum opacity allowed to skins. + */ + float getMinimumOpacity() + { return mMinimumOpacity; } + + /** + * Set the minimum opacity allowed to skins. + * Set a negative value to free the minimum allowed. + */ + void setMinimumOpacity(float minimumOpacity); + + void optionChanged(const std::string &); + + private: + Theme(); + ~Theme(); + + Skin *readSkin(const std::string &filename); + + // Map containing all window skins + typedef std::map Skins; + typedef Skins::iterator SkinIterator; + + Skins mSkins; + + static std::string mThemePath; + static Theme *mInstance; + + static bool tryThemePath(std::string themePath); + + void loadColors(std::string file = ""); + + /** + * Tells if the current skins opacity + * should not get less than the given value + */ + float mMinimumOpacity; + + typedef std::vector ProgressColors; + ProgressColors mProgressColors; +}; + +#endif diff --git a/src/resources/userpalette.cpp b/src/resources/userpalette.cpp new file mode 100644 index 00000000..5067c794 --- /dev/null +++ b/src/resources/userpalette.cpp @@ -0,0 +1,237 @@ +/* + * Configurable text colors + * Copyright (C) 2008 Douglas Boffey + * 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 . + */ + +#include "resources/userpalette.h" + +#include "configuration.h" +#include "client.h" + +#include "gui/gui.h" + +#include "utils/gettext.h" +#include "utils/stringutils.h" + +#include + +const std::string ColorTypeNames[] = { + "Being", + "Player", + "Self", + "GM", + "NPC", + "Monster", + "Party", + "Guild", + "Particle", + "Experience", + "Pickup", + "Hit Player Monster", + "Hit Monster Player", + "Hit Critical", + "Miss" +}; + +std::string UserPalette::getConfigName(const std::string &typeName) +{ + std::string res = "Color" + typeName; + + int pos = 5; + for (size_t i = 0; i < typeName.length(); i++) + { + if (i == 0 || typeName[i] == '_') + { + if (i > 0) + i++; + + res[pos] = typeName[i]; + } + else + { + res[pos] = tolower(typeName[i]); + } + pos++; + } + res.erase(pos, res.length() - pos); + + return res; +} + +UserPalette::UserPalette(): + Palette(USER_COLOR_LAST) +{ + mColors[BEING] = ColorElem(); + mColors[PC] = ColorElem(); + mColors[SELF] = ColorElem(); + mColors[GM] = ColorElem(); + mColors[NPC] = ColorElem(); + mColors[MONSTER] = ColorElem(); + + addColor(BEING, 0xffffff, STATIC, _("Being")); + addColor(PC, 0xffffff, STATIC, _("Other Players' Names")); + addColor(SELF, 0xff8040, STATIC, _("Own Name")); + addColor(GM, 0x00ff00, STATIC, _("GM Names")); + addColor(NPC, 0xc8c8ff, STATIC, _("NPCs")); + addColor(MONSTER, 0xff4040, STATIC, _("Monsters")); + addColor(PARTY, 0xff00d8, STATIC, _("Party Members")); + addColor(GUILD, 0xff00d8, STATIC, _("Guild Members")); + addColor(PARTICLE, 0xffffff, STATIC, _("Particle Effects")); + addColor(PICKUP_INFO, 0x28dc28, STATIC, _("Pickup Notification")); + addColor(EXP_INFO, 0xffff00, STATIC, _("Exp Notification")); + addColor(HIT_PLAYER_MONSTER, 0x0064ff, STATIC, _("Player Hits Monster")); + addColor(HIT_MONSTER_PLAYER, 0xff3232, STATIC, _("Monster Hits Player")); + addColor(HIT_CRITICAL, 0xff0000, RAINBOW, _("Critical Hit")); + addColor(MISS, 0xffff00, STATIC, _("Misses")); + commit(true); +} + +UserPalette::~UserPalette() +{ + for (Colors::iterator col = mColors.begin(), + colEnd = mColors.end(); col != colEnd; ++col) + { + const std::string &configName = ColorTypeNames[col->type]; + config.setValue(configName + "Gradient", col->committedGrad); + + if (col->grad != STATIC) + config.setValue(configName + "Delay", col->delay); + + if (col->grad == STATIC || col->grad == PULSE) + { + char buffer[20]; + sprintf(buffer, "0x%06x", col->getRGB()); + config.setValue(configName, std::string(buffer)); + } + } +} + +void UserPalette::setColor(int type, int r, int g, int b) +{ + mColors[type].color.r = r; + mColors[type].color.g = g; + mColors[type].color.b = b; +} + +void UserPalette::setGradient(int type, GradientType grad) +{ + ColorElem *elem = &mColors[type]; + if (elem->grad != STATIC && grad == STATIC) + { + for (size_t i = 0; i < mGradVector.size(); i++) + { + if (mGradVector[i] == elem) + { + mGradVector.erase(mGradVector.begin() + i); + break; + } + } + } + else if (elem->grad == STATIC && grad != STATIC) + { + mGradVector.push_back(elem); + } + + if (elem->grad != grad) + { + elem->grad = grad; + } +} + +std::string UserPalette::getElementAt(int i) +{ + if (i < 0 || i >= getNumberOfElements()) + { + return ""; + } + return mColors[i].text; +} + +void UserPalette::commit(bool commitNonStatic) +{ + for (Colors::iterator i = mColors.begin(), iEnd = mColors.end(); + i != iEnd; ++i) + { + i->committedGrad = i->grad; + i->committedDelay = i->delay; + if (commitNonStatic || i->grad == STATIC) + { + i->committedColor = i->color; + } + else if (i->grad == PULSE) + { + i->committedColor = i->testColor; + } + } +} + +void UserPalette::rollback() +{ + for (Colors::iterator i = mColors.begin(), iEnd = mColors.end(); + i != iEnd; ++i) + { + if (i->grad != i->committedGrad) + { + setGradient(i->type, i->committedGrad); + } + setGradientDelay(i->type, i->committedDelay); + setColor(i->type, i->committedColor.r, + i->committedColor.g, i->committedColor.b); + if (i->grad == PULSE) + { + i->testColor.r = i->committedColor.r; + i->testColor.g = i->committedColor.g; + i->testColor.b = i->committedColor.b; + } + } +} + +int UserPalette::getColorTypeAt(int i) +{ + if (i < 0 || i >= getNumberOfElements()) + { + return BEING; + } + + return mColors[i].type; +} + +void UserPalette::addColor(int type, int rgb, Palette::GradientType grad, + const std::string &text, int delay) +{ + const std::string &configName = ColorTypeNames[type]; + char buffer[20]; + sprintf(buffer, "0x%06x", rgb); + const std::string rgbString = config.getValue(configName, + std::string(buffer)); + unsigned int rgbValue = 0; + if (rgbString.length() == 8 && rgbString[0] == '0' && rgbString[1] == 'x') + rgbValue = atox(rgbString); + else + rgbValue = atoi(rgbString.c_str()); + gcn::Color trueCol = rgbValue; + grad = (GradientType) config.getValue(configName + "Gradient", grad); + delay = (int) config.getValue(configName + "Delay", delay); + mColors[type].set(type, trueCol, grad, delay); + mColors[type].text = text; + + if (grad != STATIC) + mGradVector.push_back(&mColors[type]); +} diff --git a/src/resources/userpalette.h b/src/resources/userpalette.h new file mode 100644 index 00000000..82bcea1c --- /dev/null +++ b/src/resources/userpalette.h @@ -0,0 +1,207 @@ +/* + * Configurable text colors + * Copyright (C) 2008 Douglas Boffey + * 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 . + */ + +#ifndef USER_PALETTE_H +#define USER_PALETTE_H + +#include "gui/palette.h" + +#include + +/** + * Class controlling the game's color palette. + */ +class UserPalette : public Palette, public gcn::ListModel +{ + public: + /** List of all colors that are configurable. */ + enum { + BEING, + PC, + SELF, + GM, + NPC, + MONSTER, + PARTY, + GUILD, + PARTICLE, + EXP_INFO, + PICKUP_INFO, + HIT_PLAYER_MONSTER, + HIT_MONSTER_PLAYER, + HIT_CRITICAL, + MISS, + USER_COLOR_LAST + }; + + /** + * Constructor + */ + UserPalette(); + + /** + * Destructor + */ + ~UserPalette(); + + /** + * Gets the committed color associated with the specified type. + * + * @param type the color type requested + * + * @return the requested committed color + */ + inline const gcn::Color &getCommittedColor(int type) + { + return mColors[type].committedColor; + } + + /** + * Gets the test color associated with the specified type. + * + * @param type the color type requested + * + * @return the requested test color + */ + inline const gcn::Color &getTestColor(int type) + { + return mColors[type].testColor; + } + + /** + * Sets the test color associated with the specified type. + * + * @param type the color type requested + * @param color the color that should be tested + */ + inline void setTestColor(int type, gcn::Color color) + { + mColors[type].testColor = color; + } + + /** + * Sets the color for the specified type. + * + * @param type color to be set + * @param r red component + * @param g green component + * @param b blue component + */ + void setColor(int type, int r, int g, int b); + + /** + * Sets the gradient type for the specified color. + * + * @param grad gradient type to set + */ + void setGradient(int type, Palette::GradientType grad); + + /** + * Sets the gradient delay for the specified color. + * + * @param grad gradient type to set + */ + void setGradientDelay(int type, int delay) + { mColors[type].delay = delay; } + + /** + * Returns the number of colors known. + * + * @return the number of colors known + */ + inline int getNumberOfElements() { return mColors.size(); } + + /** + * Returns the name of the ith color. + * + * @param i index of color interested in + * + * @return the name of the color + */ + std::string getElementAt(int i); + + /** + * Commit the colors + */ + inline void commit() + { + commit(false); + } + + /** + * Rollback the colors + */ + void rollback(); + + /** + * Gets the ColorType used by the color for the element at index i in + * the current color model. + * + * @param i the index of the color + * + * @return the color type of the color with the given index + */ + int getColorTypeAt(int i); + + private: + /** + * Define a color replacement. + * + * @param i the index of the color to replace + * @param r red component + * @param g green component + * @param b blue component + */ + void setColorAt(int i, int r, int g, int b); + + /** + * Commit the colors. Commit the non-static color values, if + * commitNonStatic is true. Only needed in the constructor. + */ + void commit(bool commitNonStatic); + + /** + * Prefixes the given string with "Color", lowercases all letters but + * the first and all following a '_'. All '_'s will be removed. + * + * E.g.: HIT_PLAYER_MONSTER -> HitPlayerMonster + * + * @param typeName string to transform + * + * @return the transformed string + */ + static std::string getConfigName(const std::string &typeName); + + /** + * Initialise color + * + * @param c character that needs initialising + * @param rgb default color if not found in config + * @param text identifier of color + */ + void addColor(int type, int rgb, GradientType grad, + const std::string &text, int delay = GRADIENT_DELAY); +}; + +extern UserPalette *userPalette; + +#endif // USER_PALETTE_H diff --git a/src/text.cpp b/src/text.cpp index 5e84392e..216b02e2 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -28,10 +28,10 @@ #include "gui/gui.h" #include "gui/palette.h" -#include "gui/theme.h" #include "resources/resourcemanager.h" #include "resources/image.h" +#include "resources/theme.h" #include diff --git a/src/textrenderer.h b/src/textrenderer.h index 4da868f1..fccdd3c7 100644 --- a/src/textrenderer.h +++ b/src/textrenderer.h @@ -24,7 +24,7 @@ #include "graphics.h" -#include "gui/theme.h" +#include "resources/theme.h" /** * Class for text rendering. Used by the TextParticle, the Text and FlashText -- cgit v1.2.3-70-g09d2