26 #include "gui/theme.h"
81 mMinimumOpacity(-1.0F),
124 =
CAST_S32(ThemeColorId::HIGHLIGHT_OUTLINE);
130 =
CAST_S32(ThemeColorId::WHISPER_TAB_OUTLINE);
132 =
CAST_S32(ThemeColorId::WHISPER_TAB_OFFLINE_OUTLINE);
135 =
CAST_S32(ThemeColorId::PARTY_CHAT_TAB_OUTLINE);
137 =
CAST_S32(ThemeColorId::GUILD_CHAT_TAB_OUTLINE);
141 =
CAST_S32(ThemeColorId::HYPERLINK_OUTLINE);
156 const float progress)
158 int color[3] = {0, 0, 0};
160 if (
theme !=
nullptr)
176 return Color(color[0], color[1], color[2], 255U);
180 const std::string &filename2,
182 const std::string &
restrict defaultPath)
187 if (
mSkins.end() != skinIterator)
189 if (skinIterator->second !=
nullptr)
190 skinIterator->second->instances++;
191 return skinIterator->second;
194 Skin *skin =
nullptr;
198 if ((skin ==
nullptr) && !filename2.empty() && filename2 != filename)
200 if ((skin ==
nullptr) && filename2 !=
"window.xml")
201 skin =
readSkin(
"window.xml", full);
206 std::string name = filename;
208 skin =
readSkin(name + endStr, full);
211 if ((skin ==
nullptr) && !filename2.empty() && filename2 != filename)
215 skin =
readSkin(name + endStr, full);
219 if ((skin ==
nullptr) && filename2 !=
"window.xml")
221 skin =
readSkin(
"window" + endStr, full);
223 skin =
readSkin(
"window.xml", full);
230 if (filename != defaultPath)
232 logger->
log(
"Error loading skin '%s', falling back on default.",
241 "Make sure the skin file is valid.",
242 defaultPath.c_str()));
261 if (it->second == skin)
274 if (minimumOpacity > 1.0F)
285 Skin *
const skin = iter->second;
305 {0,
"top-left-corner"},
315 {1,
"in-highlighted"},
317 {2,
"top-right-corner"},
327 {3,
"out-highlighted"},
328 {3,
"disabled-checked"},
331 {4,
"normal-highlighted"},
334 {5,
"checked-highlighted"},
335 {6,
"bottom-left-corner"},
339 {8,
"bottom-right-corner"},
345 {1,
"closeImageHighlighted"},
346 {2,
"stickyImageUp"},
347 {3,
"stickyImageDown"},
378 for (
size_t f = 0; f <
size; f ++)
381 if (partType == param.
name)
396 if (filename.empty())
399 const std::string path = resolveThemePath(filename);
407 XmlNodeConstPtr rootNode = doc->
rootNode();
408 if ((rootNode ==
nullptr) || !xmlNameEqual(rootNode,
"skinset"))
416 if (skinSetImage.empty())
418 logger->
log1(
"Theme::readSkin(): Skinset does not define an image!");
427 int titlePadding = 4;
428 int titlebarHeight = 0;
429 int titlebarHeightRelative = 0;
430 int closePadding = 3;
431 int stickySpacing = 3;
432 int stickyPadding = 3;
433 int resizePadding = 2;
439 if (!xmlNameEqual(widgetNode,
"widget"))
442 const std::string widgetType =
444 if (widgetType ==
"Window")
451 if (xmlNameEqual(partNode,
"part"))
454 partNode,
"type",
"unknown");
456 partNode,
"xpos", 0) + globalXPos;
458 partNode,
"ypos", 0) + globalYPos;
463 helper.
image = dBorders;
465 helper.
rect = border;
469 helper.
rect = images;
474 else if (full && xmlNameEqual(partNode,
"option"))
477 partNode,
"name",
"");
478 if (
name ==
"padding")
482 else if (
name ==
"titlePadding")
486 else if (
name ==
"closePadding")
490 else if (
name ==
"stickySpacing")
494 else if (
name ==
"stickyPadding")
498 else if (
name ==
"titlebarHeight")
501 partNode,
"value", 0);
503 else if (
name ==
"titlebarHeightRelative")
506 partNode,
"value", 0);
508 else if (
name ==
"resizePadding")
511 partNode,
"value", 2);
516 partNode,
"value", 0);
523 logger->
log(
"Theme::readSkin(): Unknown widget type '%s'",
528 if (dBorders !=
nullptr)
531 (*mOptions)[
"closePadding"] = closePadding;
532 (*mOptions)[
"stickyPadding"] = stickyPadding;
533 (*mOptions)[
"stickySpacing"] = stickySpacing;
534 (*mOptions)[
"titlebarHeight"] = titlebarHeight;
535 (*mOptions)[
"titlebarHeightRelative"] = titlebarHeightRelative;
536 (*mOptions)[
"resizePadding"] = resizePadding;
538 Skin *
const skin =
new Skin(border, images, filename,
"", padding,
548 if (!themeName.empty())
554 mThemeName = themeName;
555 if (
theme !=
nullptr)
567 std::sort(list.begin(), list.end());
574 std::sort(list.begin(), list.end());
586 "systemsounds") + *i)))
588 std::string str = *i;
595 std::sort(list.begin(), list.end());
619 if (mThemePath.empty())
620 mThemePath =
"graphics/gui";
624 logger->
log(
"Selected Theme: " + mThemePath);
630 const int pos =
CAST_S32(path.find(
'|'));
633 file = path.substr(0, pos);
638 if (file.find(
'/') != std::string::npos)
646 file =
pathJoin(getThemePath(), file);
649 return pathJoin(getThemePath(), path);
661 const int w,
const int h)
666 #define themeEnumStart(name) #name,
667 #define themeEnum(name) #name,
668 #define themeEnumEnd(name)
672 static const std::string colors[
CAST_SIZE(
673 ThemeColorId::THEME_COLORS_END)] =
675 #include "gui/themecolortype.inc"
681 for (
int i = 0; i <
CAST_S32(ThemeColorId::THEME_COLORS_END); i++)
692 #undef themeEnumStart
695 #undef THEMECOLORTYPE_VOID
699 const int size =
static_cast<int>(description.length());
700 if (
size < 7 || description[0] !=
'#')
702 logger->
log(
"Error, invalid theme color palette: %s",
703 description.c_str());
708 for (
int i = 1; i < 7; ++i)
710 signed const char c = description[i];
713 if (
'0' <= c && c <=
'9')
717 else if (
'A' <= c && c <=
'F')
721 else if (
'a' <= c && c <=
'f')
727 logger->
log(
"Error, invalid theme color palette: %s",
728 description.c_str());
740 static const std::string grads[] =
751 for (
int i = 0; i < 4; i++)
762 static const std::string colors[
CAST_SIZE(
796 file =
pathJoin(file,
"colors.xml");
803 XmlNodeConstPtrConst root = doc->
rootNode();
805 if ((root ==
nullptr) || !xmlNameEqual(root,
"colors"))
807 logger->
log(
"Error loading colors file: %s", file.c_str());
812 logger->
log(
"Loading colors file: %s", file.c_str());
816 if (xmlNameEqual(paletteNode,
"progressbar"))
819 paletteNode,
"id",
""));
824 paletteNode,
"color",
""), 6);
826 else if (!xmlNameEqual(paletteNode,
"palette"))
837 if (xmlNameEqual(node,
"color"))
852 ThemeColorId::THEME_COLORS_END) + type].set(
853 type, color, grad, 10);
860 const int idx = paletteId
861 *
CAST_S32(ThemeColorId::THEME_COLORS_END);
872 const ImageRect &rect = skin->getBorder(); \
873 for (int f = start; f <= end; f ++) \
877 image.grid[f] = rect.grid[f]; \
878 image.grid[f]->incRef(); \
884 const std::string &
name,
885 const std::string &name2,
901 const std::string &
name,
902 const std::string &name2,
919 for (
int f =
start; f <= end; f ++)
921 if (rect.
grid[f] !=
nullptr)
922 rect.
grid[f]->decRef();
927 const std::string &name2)
929 if (
theme ==
nullptr)
939 if (rect.
grid[0] !=
nullptr)
952 const std::string &name2,
953 const int w,
const int h)
955 if (
theme ==
nullptr)
965 if (rect.
grid[0] !=
nullptr)
968 const SDL_Rect &rect2 = image->mBounds;
969 if ((rect2.w != 0U) && (rect2.h != 0U))
982 #define readValue(name) \
984 tmpData = reinterpret_cast<XmlChar*>( \
985 XmlNodeGetContent(infoNode)); \
986 info->name = tmpData; \
990 #define readIntValue(name) \
992 tmpData = reinterpret_cast<XmlChar*>( \
993 XmlNodeGetContent(infoNode)); \
994 info->name = atoi(tmpData); \
998 #define readFloatValue(name) \
1000 tmpData = reinterpret_cast<XmlChar*>( \
1001 XmlNodeGetContent(infoNode)); \
1002 info->name = static_cast<float>(atof(tmpData)); \
1009 if (themeName.empty())
1011 path =
"graphics/gui/info.xml";
1025 XmlNodeConstPtrConst rootNode = doc->
rootNode();
1027 if ((rootNode ==
nullptr) || !xmlNameEqual(rootNode,
"info"))
1035 const std::string fontSize2(
"fontSize_" + mScreenDensity);
1036 const std::string npcfontSize2(
"npcfontSize_" + mScreenDensity);
1037 XmlChar *tmpData =
nullptr;
1040 if (xmlNameEqual(infoNode,
"name"))
1042 else if (xmlNameEqual(infoNode,
"copyright"))
1044 else if (xmlNameEqual(infoNode,
"font"))
1046 else if (xmlNameEqual(infoNode,
"boldFont"))
1048 else if (xmlNameEqual(infoNode,
"particleFont"))
1050 else if (xmlNameEqual(infoNode,
"helpFont"))
1052 else if (xmlNameEqual(infoNode,
"secureFont"))
1054 else if (xmlNameEqual(infoNode,
"npcFont"))
1056 else if (xmlNameEqual(infoNode,
"japanFont"))
1058 else if (xmlNameEqual(infoNode,
"chinaFont"))
1060 else if (xmlNameEqual(infoNode,
"fontSize"))
1062 else if (xmlNameEqual(infoNode,
"npcfontSize"))
1064 else if (xmlNameEqual(infoNode,
"guialpha"))
1066 else if (xmlNameEqual(infoNode, fontSize2.c_str()))
1068 else if (xmlNameEqual(infoNode, npcfontSize2.c_str()))
1077 const CharColors::const_iterator it = mCharColors.find(c);
1078 if (it != mCharColors.end())
1085 return ThemeColorId::BROWSERBOX;
#define loadList(key, mob)
std::string getStringValue(const std::string &key) const
void addListener(const std::string &key, ConfigListener *const listener)
void removeListener(const std::string &key, ConfigListener *const listener)
void getColor(const unsigned int intensity, unsigned int(&color)[3]) const
std::string getDensityString() const
void log(const char *const log_text,...)
void log1(const char *const log_text)
const ImageRect & getBorder() const
void updateAlpha(const float minimumOpacityAllowed)
static void fillSoundsList(StringVect &list)
void unload(Skin *const skin)
void loadColors(std::string file)
static void prepareThemePath()
std::vector< DyePalette * > ProgressColors
static std::string mThemePath
static std::string resolveThemePath(const std::string &path)
static std::string getThemePath()
static Image * getImageFromThemeXml(const std::string &name, const std::string &name2)
void optionChanged(const std::string &name)
static ThemeInfo * loadInfo(const std::string &themeName)
static ImageSet * getImageSetFromThemeXml(const std::string &name, const std::string &name2, const int w, const int h)
Skins::iterator SkinIterator
static void unloadRect(const ImageRect &rect, const int start, const int end)
ProgressColors mProgressColors
static void fillFontsList(StringVect &list)
static std::string mThemeName
Skin * load(const std::string &filename, const std::string &filename2, const bool full, const std::string &defaultPath)
static void fillSkinsList(StringVect &list)
static std::string mScreenDensity
void loadRect(ImageRect &image, const std::string &name, const std::string &name2, const int start, const int end)
void setMinimumOpacity(const float minimumOpacity)
static bool tryThemePath(const std::string &themePath)
Skin * loadSkinRect(ImageRect &image, const std::string &name, const std::string &name2, const int start, const int end)
static Image * getImageFromTheme(const std::string &path)
static Color getProgressColor(const ProgressColorIdT type, const float progress)
ThemeColorIdT getIdByChar(const signed char c, bool &valid) const
static ImageSet * getImageSetFromTheme(const std::string &path, const int w, const int h)
Skin * readSkin(const std::string &filename0, const bool full)
void delete_all(Container &c)
#define FOR_EACH(type, iter, array)
GradientType ::T GradientTypeT
GraphicsManager graphicsManager
#define for_each_xml_child_node(var, parent)
#define A_DELETE_COPY(func)
#define A_DEFAULT_COPY(func)
bool info(InputEvent &event)
std::string toString(T const &value)
converts any type to a string
XML::Document * getXml(const std::string &idPath, const UseVirtFs useResman, const SkipError skipError)
ImageSet * getSubImageSet(Image *const parent, const int width, const int height)
Image * getImage(const std::string &idPath)
ImageSet * getImageSet(const std::string &imagePath, const int w, const int h)
Image * getSubImage(Image *const parent, const int x, const int y, const int width, const int height)
void getDirs(std::string dirName, StringVect &list)
void freeList(List *const handle)
bool isDirectory(std::string name)
void permitLinks(const bool val)
List * enumerateFiles(std::string dirName)
void getFiles(std::string dirName, StringVect &list)
bool exists(std::string name)
int getProperty(const xmlNodePtr node, const char *const name, int def)
ItemOptionDb::OptionInfos mOptions
std::map< std::string, DyeColor > mColors
ProgressColorId ::T ProgressColorIdT
const bool SkipError_false
const bool SkipError_true
std::map< std::string, int > StringIntMap
std::string strprintf(const char *const format,...)
int compareStrI(const std::string &a, const std::string &b)
bool findLast(const std::string &str1, const std::string &str2)
bool findCutLast(std::string &str1, const std::string &str2)
std::string pathJoin(std::string str1, const std::string &str2)
StringVect::const_iterator StringVectCIter
std::vector< std::string > StringVect
bool loadList(const SkinParameter *const params, const size_t size)
static void initDefaultThemePath()
#define readIntValue(name)
static std::string defaultThemePath
static const SkinParameter skinParam[]
static int readColorType(const std::string &type)
static const SkinParameter imageParam[]
static Color readColor(const std::string &description)
#define readFloatValue(name)
static GradientTypeT readColorGradient(const std::string &grad)
static int readProgressType(const std::string &type)
ThemeColorId ::T ThemeColorIdT
const bool UseVirtFs_true