mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 14:15:38 +00:00
Cleaned up ThemeData a bit.
This commit is contained in:
parent
644f79ebec
commit
dc20a9e21b
|
@ -1355,7 +1355,7 @@ std::vector<std::string> CollectionSystemsManager::getSystemsFromTheme()
|
|||
if (themeSets.empty())
|
||||
return systems; // No theme sets available.
|
||||
|
||||
std::map<std::string, ThemeSet>::const_iterator set =
|
||||
std::map<std::string, ThemeData::ThemeSet>::const_iterator set =
|
||||
themeSets.find(Settings::getInstance()->getString("ThemeSet"));
|
||||
if (set == themeSets.cend()) {
|
||||
// Currently selected theme set is missing, so just pick the first available set.
|
||||
|
|
|
@ -1235,7 +1235,9 @@ void SystemData::loadTheme()
|
|||
// No theme available for this platform.
|
||||
if (!mIsCustomCollectionSystem) {
|
||||
LOG(LogWarning) << "There is no \"" << mThemeFolder
|
||||
<< "\" theme configuration available, system will be unthemed";
|
||||
<< "\" configuration available for the selected theme set \""
|
||||
<< Settings::getInstance()->getString("ThemeSet")
|
||||
<< "\", system will be unthemed";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ void GuiMenu::openUIOptions()
|
|||
// Theme selection.
|
||||
auto themeSets = ThemeData::getThemeSets();
|
||||
if (!themeSets.empty()) {
|
||||
std::map<std::string, ThemeSet>::const_iterator selectedSet =
|
||||
std::map<std::string, ThemeData::ThemeSet>::const_iterator selectedSet =
|
||||
themeSets.find(Settings::getInstance()->getString("ThemeSet"));
|
||||
if (selectedSet == themeSets.cend())
|
||||
selectedSet = themeSets.cbegin();
|
||||
|
|
|
@ -236,54 +236,9 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"zIndex", FLOAT},
|
||||
{"legacyZIndexMode", STRING}}}};
|
||||
|
||||
// Helper.
|
||||
unsigned int getHexColor(const std::string& str)
|
||||
{
|
||||
ThemeException error;
|
||||
|
||||
if (str == "")
|
||||
throw error << "Empty color property";
|
||||
|
||||
size_t len {str.size()};
|
||||
if (len != 6 && len != 8)
|
||||
throw error << "Invalid color property \"" << str
|
||||
<< "\" (must be 6 or 8 characters in length)";
|
||||
|
||||
unsigned int val;
|
||||
std::stringstream ss;
|
||||
ss << str;
|
||||
ss >> std::hex >> val;
|
||||
|
||||
if (len == 6)
|
||||
val = (val << 8) | 0xFF;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> mVariables;
|
||||
|
||||
std::string resolvePlaceholders(const std::string& in)
|
||||
{
|
||||
if (in.empty())
|
||||
return in;
|
||||
|
||||
const size_t variableBegin {in.find("${")};
|
||||
const size_t variableEnd {in.find("}", variableBegin)};
|
||||
|
||||
if ((variableBegin == std::string::npos) || (variableEnd == std::string::npos))
|
||||
return in;
|
||||
|
||||
std::string prefix {in.substr(0, variableBegin)};
|
||||
std::string replace {in.substr(variableBegin + 2, variableEnd - (variableBegin + 2))};
|
||||
std::string suffix {resolvePlaceholders(in.substr(variableEnd + 1).c_str())};
|
||||
|
||||
return prefix + mVariables[replace] + suffix;
|
||||
}
|
||||
|
||||
ThemeData::ThemeData()
|
||||
: mVersion {0} // The version will be loaded from the theme set.
|
||||
{
|
||||
// The version will be loaded from the theme file.
|
||||
mVersion = 0;
|
||||
}
|
||||
|
||||
void ThemeData::loadFile(const std::map<std::string, std::string>& sysDataMap,
|
||||
|
@ -333,6 +288,203 @@ void ThemeData::loadFile(const std::map<std::string, std::string>& sysDataMap,
|
|||
parseFeatures(root);
|
||||
}
|
||||
|
||||
bool ThemeData::hasView(const std::string& view)
|
||||
{
|
||||
auto viewIt = mViews.find(view);
|
||||
return (viewIt != mViews.cend());
|
||||
}
|
||||
|
||||
std::vector<GuiComponent*> ThemeData::makeExtras(const std::shared_ptr<ThemeData>& theme,
|
||||
const std::string& view)
|
||||
{
|
||||
std::vector<GuiComponent*> comps;
|
||||
|
||||
auto viewIt = theme->mViews.find(view);
|
||||
if (viewIt == theme->mViews.cend())
|
||||
return comps;
|
||||
|
||||
for (auto it = viewIt->second.orderedKeys.cbegin(); // Line break.
|
||||
it != viewIt->second.orderedKeys.cend(); ++it) {
|
||||
ThemeElement& elem {viewIt->second.elements.at(*it)};
|
||||
if (elem.extra) {
|
||||
GuiComponent* comp {nullptr};
|
||||
const std::string& t {elem.type};
|
||||
if (t == "image")
|
||||
comp = new ImageComponent;
|
||||
else if (t == "text")
|
||||
comp = new TextComponent;
|
||||
else if (t == "animation")
|
||||
comp = new LottieComponent;
|
||||
|
||||
if (comp) {
|
||||
comp->setDefaultZIndex(10.0f);
|
||||
comp->applyTheme(theme, view, *it, ThemeFlags::ALL);
|
||||
comps.push_back(comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return comps;
|
||||
}
|
||||
|
||||
const ThemeData::ThemeElement* ThemeData::getElement(const std::string& view,
|
||||
const std::string& element,
|
||||
const std::string& expectedType) const
|
||||
{
|
||||
auto viewIt = mViews.find(view);
|
||||
if (viewIt == mViews.cend())
|
||||
return nullptr; // Not found.
|
||||
|
||||
auto elemIt = viewIt->second.elements.find(element);
|
||||
if (elemIt == viewIt->second.elements.cend())
|
||||
return nullptr;
|
||||
|
||||
if (elemIt->second.type != expectedType && !expectedType.empty()) {
|
||||
LOG(LogWarning) << " requested mismatched theme type for [" << view << "." << element
|
||||
<< "] - expected \"" << expectedType << "\", got \"" << elemIt->second.type
|
||||
<< "\"";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &elemIt->second;
|
||||
}
|
||||
|
||||
std::map<std::string, ThemeData::ThemeSet> ThemeData::getThemeSets()
|
||||
{
|
||||
std::map<std::string, ThemeSet> sets;
|
||||
|
||||
// Check for themes first under the home directory, then under the data installation
|
||||
// directory (Unix only) and last under the ES-DE binary directory.
|
||||
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
static const size_t pathCount = 3;
|
||||
#else
|
||||
static const size_t pathCount = 2;
|
||||
#endif
|
||||
std::string paths[pathCount] = {
|
||||
Utils::FileSystem::getExePath() + "/themes",
|
||||
#if defined(__APPLE__)
|
||||
Utils::FileSystem::getExePath() + "/../Resources/themes",
|
||||
#elif defined(__unix__)
|
||||
Utils::FileSystem::getProgramDataPath() + "/themes",
|
||||
#endif
|
||||
Utils::FileSystem::getHomePath() + "/.emulationstation/themes"
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < pathCount; ++i) {
|
||||
if (!Utils::FileSystem::isDirectory(paths[i]))
|
||||
continue;
|
||||
|
||||
Utils::FileSystem::StringList dirContent {Utils::FileSystem::getDirContent(paths[i])};
|
||||
|
||||
for (Utils::FileSystem::StringList::const_iterator it = dirContent.cbegin();
|
||||
it != dirContent.cend(); ++it) {
|
||||
if (Utils::FileSystem::isDirectory(*it)) {
|
||||
ThemeSet set = {*it};
|
||||
sets[set.getName()] = set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sets;
|
||||
}
|
||||
|
||||
std::string ThemeData::getThemeFromCurrentSet(const std::string& system)
|
||||
{
|
||||
std::map<std::string, ThemeSet> themeSets {ThemeData::getThemeSets()};
|
||||
if (themeSets.empty())
|
||||
// No theme sets available.
|
||||
return "";
|
||||
|
||||
std::map<std::string, ThemeSet>::const_iterator set =
|
||||
themeSets.find(Settings::getInstance()->getString("ThemeSet"));
|
||||
if (set == themeSets.cend()) {
|
||||
// Currently configured theme set is missing, attempt to load the default theme set
|
||||
// rbsimple-DE instead, and if that's also missing then pick the first available set.
|
||||
bool defaultSetFound {true};
|
||||
|
||||
set = themeSets.find("rbsimple-DE");
|
||||
|
||||
if (set == themeSets.cend()) {
|
||||
set = themeSets.cbegin();
|
||||
defaultSetFound = false;
|
||||
}
|
||||
|
||||
LOG(LogWarning) << "Configured theme set \""
|
||||
<< Settings::getInstance()->getString("ThemeSet")
|
||||
<< "\" does not exist, loading" << (defaultSetFound ? " default " : " ")
|
||||
<< "theme set \"" << set->first << "\" instead";
|
||||
|
||||
Settings::getInstance()->setString("ThemeSet", set->first);
|
||||
}
|
||||
|
||||
return set->second.getThemePath(system);
|
||||
}
|
||||
|
||||
const std::shared_ptr<ThemeData> ThemeData::getDefault()
|
||||
{
|
||||
static std::shared_ptr<ThemeData> theme = nullptr;
|
||||
if (theme == nullptr) {
|
||||
theme = std::shared_ptr<ThemeData>(new ThemeData());
|
||||
|
||||
const std::string path {Utils::FileSystem::getHomePath() +
|
||||
"/.emulationstation/es_theme_default.xml"};
|
||||
if (Utils::FileSystem::exists(path)) {
|
||||
try {
|
||||
std::map<std::string, std::string> emptyMap;
|
||||
theme->loadFile(emptyMap, path);
|
||||
}
|
||||
catch (ThemeException& e) {
|
||||
LOG(LogError) << e.what();
|
||||
theme = std::shared_ptr<ThemeData>(new ThemeData()); // Reset to empty.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
||||
unsigned int ThemeData::getHexColor(const std::string& str)
|
||||
{
|
||||
ThemeException error;
|
||||
|
||||
if (str == "")
|
||||
throw error << "Empty color property";
|
||||
|
||||
size_t len {str.size()};
|
||||
if (len != 6 && len != 8)
|
||||
throw error << "Invalid color property \"" << str
|
||||
<< "\" (must be 6 or 8 characters in length)";
|
||||
|
||||
unsigned int val;
|
||||
std::stringstream ss;
|
||||
ss << str;
|
||||
ss >> std::hex >> val;
|
||||
|
||||
if (len == 6)
|
||||
val = (val << 8) | 0xFF;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
std::string ThemeData::resolvePlaceholders(const std::string& in)
|
||||
{
|
||||
if (in.empty())
|
||||
return in;
|
||||
|
||||
const size_t variableBegin {in.find("${")};
|
||||
const size_t variableEnd {in.find("}", variableBegin)};
|
||||
|
||||
if ((variableBegin == std::string::npos) || (variableEnd == std::string::npos))
|
||||
return in;
|
||||
|
||||
std::string prefix {in.substr(0, variableBegin)};
|
||||
std::string replace {in.substr(variableBegin + 2, variableEnd - (variableBegin + 2))};
|
||||
std::string suffix {resolvePlaceholders(in.substr(variableEnd + 1).c_str())};
|
||||
|
||||
return prefix + mVariables[replace] + suffix;
|
||||
}
|
||||
|
||||
void ThemeData::parseIncludes(const pugi::xml_node& root)
|
||||
{
|
||||
ThemeException error;
|
||||
|
@ -539,7 +691,7 @@ void ThemeData::parseElement(const pugi::xml_node& root,
|
|||
std::string path = Utils::FileSystem::resolveRelativePath(str, mPaths.back(), true);
|
||||
if (!ResourceManager::getInstance().fileExists(path)) {
|
||||
std::stringstream ss;
|
||||
LOG(LogWarning) << error.msg << ":";
|
||||
LOG(LogWarning) << error.message << ":";
|
||||
LOG(LogWarning)
|
||||
<< "Couldn't find file \"" << node.text().get() << "\" "
|
||||
<< ((node.text().get() != path) ? "which resolves to \"" + path + "\"" :
|
||||
|
@ -607,159 +759,3 @@ void ThemeData::parseElement(const pugi::xml_node& root,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ThemeData::hasView(const std::string& view)
|
||||
{
|
||||
auto viewIt = mViews.find(view);
|
||||
return (viewIt != mViews.cend());
|
||||
}
|
||||
|
||||
const ThemeData::ThemeElement* ThemeData::getElement(const std::string& view,
|
||||
const std::string& element,
|
||||
const std::string& expectedType) const
|
||||
{
|
||||
auto viewIt = mViews.find(view);
|
||||
if (viewIt == mViews.cend())
|
||||
return nullptr; // Not found.
|
||||
|
||||
auto elemIt = viewIt->second.elements.find(element);
|
||||
if (elemIt == viewIt->second.elements.cend())
|
||||
return nullptr;
|
||||
|
||||
if (elemIt->second.type != expectedType && !expectedType.empty()) {
|
||||
LOG(LogWarning) << " requested mismatched theme type for [" << view << "." << element
|
||||
<< "] - expected \"" << expectedType << "\", got \"" << elemIt->second.type
|
||||
<< "\"";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &elemIt->second;
|
||||
}
|
||||
|
||||
const std::shared_ptr<ThemeData> ThemeData::getDefault()
|
||||
{
|
||||
static std::shared_ptr<ThemeData> theme = nullptr;
|
||||
if (theme == nullptr) {
|
||||
theme = std::shared_ptr<ThemeData>(new ThemeData());
|
||||
|
||||
const std::string path {Utils::FileSystem::getHomePath() +
|
||||
"/.emulationstation/es_theme_default.xml"};
|
||||
if (Utils::FileSystem::exists(path)) {
|
||||
try {
|
||||
std::map<std::string, std::string> emptyMap;
|
||||
theme->loadFile(emptyMap, path);
|
||||
}
|
||||
catch (ThemeException& e) {
|
||||
LOG(LogError) << e.what();
|
||||
theme = std::shared_ptr<ThemeData>(new ThemeData()); // Reset to empty.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
||||
std::vector<GuiComponent*> ThemeData::makeExtras(const std::shared_ptr<ThemeData>& theme,
|
||||
const std::string& view)
|
||||
{
|
||||
std::vector<GuiComponent*> comps;
|
||||
|
||||
auto viewIt = theme->mViews.find(view);
|
||||
if (viewIt == theme->mViews.cend())
|
||||
return comps;
|
||||
|
||||
for (auto it = viewIt->second.orderedKeys.cbegin(); // Line break.
|
||||
it != viewIt->second.orderedKeys.cend(); ++it) {
|
||||
ThemeElement& elem {viewIt->second.elements.at(*it)};
|
||||
if (elem.extra) {
|
||||
GuiComponent* comp {nullptr};
|
||||
const std::string& t {elem.type};
|
||||
if (t == "image")
|
||||
comp = new ImageComponent;
|
||||
else if (t == "text")
|
||||
comp = new TextComponent;
|
||||
else if (t == "animation")
|
||||
comp = new LottieComponent;
|
||||
|
||||
if (comp) {
|
||||
comp->setDefaultZIndex(10.0f);
|
||||
comp->applyTheme(theme, view, *it, ThemeFlags::ALL);
|
||||
comps.push_back(comp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return comps;
|
||||
}
|
||||
|
||||
std::map<std::string, ThemeSet> ThemeData::getThemeSets()
|
||||
{
|
||||
std::map<std::string, ThemeSet> sets;
|
||||
|
||||
// Check for themes first under the home directory, then under the data installation
|
||||
// directory (Unix only) and last under the ES-DE binary directory.
|
||||
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
static const size_t pathCount = 3;
|
||||
#else
|
||||
static const size_t pathCount = 2;
|
||||
#endif
|
||||
std::string paths[pathCount] = {
|
||||
Utils::FileSystem::getExePath() + "/themes",
|
||||
#if defined(__APPLE__)
|
||||
Utils::FileSystem::getExePath() + "/../Resources/themes",
|
||||
#elif defined(__unix__)
|
||||
Utils::FileSystem::getProgramDataPath() + "/themes",
|
||||
#endif
|
||||
Utils::FileSystem::getHomePath() + "/.emulationstation/themes"
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < pathCount; ++i) {
|
||||
if (!Utils::FileSystem::isDirectory(paths[i]))
|
||||
continue;
|
||||
|
||||
Utils::FileSystem::StringList dirContent {Utils::FileSystem::getDirContent(paths[i])};
|
||||
|
||||
for (Utils::FileSystem::StringList::const_iterator it = dirContent.cbegin();
|
||||
it != dirContent.cend(); ++it) {
|
||||
if (Utils::FileSystem::isDirectory(*it)) {
|
||||
ThemeSet set = {*it};
|
||||
sets[set.getName()] = set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sets;
|
||||
}
|
||||
|
||||
std::string ThemeData::getThemeFromCurrentSet(const std::string& system)
|
||||
{
|
||||
std::map<std::string, ThemeSet> themeSets {ThemeData::getThemeSets()};
|
||||
if (themeSets.empty())
|
||||
// No theme sets available.
|
||||
return "";
|
||||
|
||||
std::map<std::string, ThemeSet>::const_iterator set =
|
||||
themeSets.find(Settings::getInstance()->getString("ThemeSet"));
|
||||
if (set == themeSets.cend()) {
|
||||
// Currently configured theme set is missing, attempt to load the default theme set
|
||||
// rbsimple-DE instead, and if that's also missing then pick the first available set.
|
||||
bool defaultSetFound {true};
|
||||
|
||||
set = themeSets.find("rbsimple-DE");
|
||||
|
||||
if (set == themeSets.cend()) {
|
||||
set = themeSets.cbegin();
|
||||
defaultSetFound = false;
|
||||
}
|
||||
|
||||
LOG(LogWarning) << "Configured theme set \""
|
||||
<< Settings::getInstance()->getString("ThemeSet")
|
||||
<< "\" does not exist, loading" << (defaultSetFound ? " default " : " ")
|
||||
<< "theme set \"" << set->first << "\" instead";
|
||||
|
||||
Settings::getInstance()->setString("ThemeSet", set->first);
|
||||
}
|
||||
|
||||
return set->second.getThemePath(system);
|
||||
}
|
||||
|
|
|
@ -26,8 +26,6 @@ namespace pugi
|
|||
class xml_node;
|
||||
}
|
||||
|
||||
template <typename T> class TextListComponent;
|
||||
|
||||
class GuiComponent;
|
||||
class ImageComponent;
|
||||
class NinePatchComponent;
|
||||
|
@ -65,35 +63,25 @@ namespace ThemeFlags
|
|||
class ThemeException : public std::exception
|
||||
{
|
||||
public:
|
||||
std::string msg;
|
||||
std::string message;
|
||||
|
||||
const char* what() const throw() { return msg.c_str(); }
|
||||
const char* what() const throw() { return message.c_str(); }
|
||||
|
||||
template <typename T> friend ThemeException& operator<<(ThemeException& e, T msg);
|
||||
|
||||
void setFiles(const std::deque<std::string>& deque)
|
||||
{
|
||||
*this << "\"" << deque.front() << "\"";
|
||||
for (auto it = deque.cbegin() + 1; it != deque.cend(); ++it)
|
||||
*this << " -> \"" << (*it) << "\"";
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> ThemeException& operator<<(ThemeException& e, T appendMsg)
|
||||
template <typename T> friend ThemeException& operator<<(ThemeException& e, T message)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << e.msg << appendMsg;
|
||||
e.msg = ss.str();
|
||||
ss << e.message << message;
|
||||
e.message = ss.str();
|
||||
return e;
|
||||
}
|
||||
|
||||
struct ThemeSet {
|
||||
std::string path;
|
||||
|
||||
std::string getName() const { return Utils::FileSystem::getStem(path); }
|
||||
std::string getThemePath(const std::string& system) const
|
||||
void setFiles(const std::deque<std::string>& deque)
|
||||
{
|
||||
return path + "/" + system + "/theme.xml";
|
||||
// Add all paths to the error message, separated by -> so it's easy to read the log
|
||||
// output in case of theme loading errors.
|
||||
*this << "\"" << deque.front() << "\"";
|
||||
for (auto it = deque.cbegin() + 1; it != deque.cend(); ++it)
|
||||
*this << " -> \"" << (*it) << "\"";
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -168,19 +156,32 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
private:
|
||||
class ThemeView
|
||||
{
|
||||
public:
|
||||
std::map<std::string, ThemeElement> elements;
|
||||
std::vector<std::string> orderedKeys;
|
||||
};
|
||||
|
||||
public:
|
||||
ThemeData();
|
||||
|
||||
struct ThemeSet {
|
||||
std::string path;
|
||||
|
||||
std::string getName() const { return Utils::FileSystem::getStem(path); }
|
||||
std::string getThemePath(const std::string& system) const
|
||||
{
|
||||
return path + "/" + system + "/theme.xml";
|
||||
}
|
||||
};
|
||||
|
||||
// Throws ThemeException.
|
||||
void loadFile(const std::map<std::string, std::string>& sysDataMap, const std::string& path);
|
||||
bool hasView(const std::string& view);
|
||||
|
||||
static std::vector<GuiComponent*> makeExtras(const std::shared_ptr<ThemeData>& theme,
|
||||
const std::string& view);
|
||||
|
||||
// If expectedType is an empty string, then do no type checking.
|
||||
const ThemeElement* getElement(const std::string& view,
|
||||
const std::string& element,
|
||||
const std::string& expectedType) const;
|
||||
|
||||
static std::map<std::string, ThemeSet> getThemeSets();
|
||||
static std::string getThemeFromCurrentSet(const std::string& system);
|
||||
|
||||
enum ElementPropertyType {
|
||||
NORMALIZED_RECT,
|
||||
|
@ -192,22 +193,16 @@ public:
|
|||
BOOLEAN
|
||||
};
|
||||
|
||||
bool hasView(const std::string& view);
|
||||
|
||||
// If expectedType is an empty string, will do no type checking.
|
||||
const ThemeElement* getElement(const std::string& view,
|
||||
const std::string& element,
|
||||
const std::string& expectedType) const;
|
||||
|
||||
static std::vector<GuiComponent*> makeExtras(const std::shared_ptr<ThemeData>& theme,
|
||||
const std::string& view);
|
||||
|
||||
static const std::shared_ptr<ThemeData> getDefault();
|
||||
|
||||
static std::map<std::string, ThemeSet> getThemeSets();
|
||||
static std::string getThemeFromCurrentSet(const std::string& system);
|
||||
std::map<std::string, std::string> mVariables;
|
||||
|
||||
private:
|
||||
class ThemeView
|
||||
{
|
||||
public:
|
||||
std::map<std::string, ThemeElement> elements;
|
||||
std::vector<std::string> orderedKeys;
|
||||
};
|
||||
|
||||
static std::map<std::string, std::map<std::string, ElementPropertyType>> sElementMap;
|
||||
static std::vector<std::string> sSupportedFeatures;
|
||||
static std::vector<std::string> sSupportedViews;
|
||||
|
@ -215,8 +210,12 @@ private:
|
|||
std::deque<std::string> mPaths;
|
||||
float mVersion;
|
||||
|
||||
void parseFeatures(const pugi::xml_node& themeRoot);
|
||||
static const std::shared_ptr<ThemeData> getDefault();
|
||||
unsigned int getHexColor(const std::string& str);
|
||||
std::string resolvePlaceholders(const std::string& in);
|
||||
|
||||
void parseIncludes(const pugi::xml_node& themeRoot);
|
||||
void parseFeatures(const pugi::xml_node& themeRoot);
|
||||
void parseVariables(const pugi::xml_node& root);
|
||||
void parseViews(const pugi::xml_node& themeRoot);
|
||||
void parseView(const pugi::xml_node& viewNode, ThemeView& view);
|
||||
|
|
Loading…
Reference in a new issue