mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-04-02 21:47:40 -05:00
feat: Added a theme manager view to make it easier to make new themes
This commit is contained in:
@@ -8,15 +8,17 @@
|
||||
namespace hex::api {
|
||||
|
||||
std::map<std::string, nlohmann::json> ThemeManager::s_themes;
|
||||
std::map<std::string, std::function<void(std::string, std::string)>> ThemeManager::s_themeHandlers, ThemeManager::s_styleHandlers;
|
||||
std::map<std::string, ThemeManager::ThemeHandler> ThemeManager::s_themeHandlers;
|
||||
std::map<std::string, ThemeManager::StyleHandler> ThemeManager::s_styleHandlers;
|
||||
std::string ThemeManager::s_imagePostfix;
|
||||
std::string ThemeManager::s_currTheme;
|
||||
|
||||
void ThemeManager::addThemeHandler(const std::string &name, const std::function<void(std::string, std::string)> &handler) {
|
||||
s_themeHandlers[name] = handler;
|
||||
void ThemeManager::addThemeHandler(const std::string &name, const ColorMap &colorMap, const std::function<ImColor(u32)> &getFunction, const std::function<void(u32, ImColor)> &setFunction) {
|
||||
s_themeHandlers[name] = { colorMap, getFunction, setFunction };
|
||||
}
|
||||
|
||||
void ThemeManager::addStyleHandler(const std::string &name, const std::function<void(std::string, std::string)> &handler) {
|
||||
s_styleHandlers[name] = handler;
|
||||
void ThemeManager::addStyleHandler(const std::string &name, const StyleMap &styleMap) {
|
||||
s_styleHandlers[name] = { styleMap };
|
||||
}
|
||||
|
||||
void ThemeManager::addTheme(const std::string &content) {
|
||||
@@ -49,6 +51,42 @@ namespace hex::api {
|
||||
return ImColor(hex::changeEndianess(color, std::endian::big));
|
||||
}
|
||||
|
||||
nlohmann::json ThemeManager::exportCurrentTheme(const std::string &name) {
|
||||
nlohmann::json theme = {
|
||||
{ "name", name },
|
||||
{ "image_postfix", s_imagePostfix },
|
||||
{ "colors", {} },
|
||||
{ "styles", {} },
|
||||
{ "base", s_currTheme }
|
||||
};
|
||||
|
||||
for (const auto &[type, handler] : s_themeHandlers) {
|
||||
theme["colors"][type] = {};
|
||||
|
||||
for (const auto &[key, value] : handler.colorMap) {
|
||||
auto color = handler.getFunction(value);
|
||||
theme["colors"][type][key] = fmt::format("#{:08X}", hex::changeEndianess(u32(color), std::endian::big));
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &[type, handler] : s_styleHandlers) {
|
||||
theme["styles"][type] = {};
|
||||
|
||||
for (const auto &[key, style] : handler.styleMap) {
|
||||
if (std::holds_alternative<float*>(style.value))
|
||||
theme["styles"][type][key] = *std::get<float*>(style.value);
|
||||
else if (std::holds_alternative<ImVec2*>(style.value)) {
|
||||
theme["styles"][type][key] = {
|
||||
std::get<ImVec2*>(style.value)->x,
|
||||
std::get<ImVec2*>(style.value)->y
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
||||
void ThemeManager::changeTheme(std::string name) {
|
||||
if (!s_themes.contains(name)) {
|
||||
if (s_themes.empty()) {
|
||||
@@ -77,19 +115,52 @@ namespace hex::api {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const auto &[key, value] : content.items())
|
||||
s_themeHandlers[type](key, value.get<std::string>());
|
||||
const auto &handler = s_themeHandlers[type];
|
||||
for (const auto &[key, value] : content.items()) {
|
||||
if (!handler.colorMap.contains(key)) {
|
||||
log::warn("No color found for '{}.{}'", type, key);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto color = parseColorString(value.get<std::string>());
|
||||
if (!color.has_value()) {
|
||||
log::warn("Invalid color '{}' for '{}.{}'", value.get<std::string>(), type, key);
|
||||
continue;
|
||||
}
|
||||
|
||||
s_themeHandlers[type].setFunction(s_themeHandlers[type].colorMap.at(key), color.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (theme.contains("styles")) {
|
||||
for (const auto&[key, value] : theme["styles"].items()) {
|
||||
if (!s_styleHandlers.contains(key)) {
|
||||
log::warn("No style handler found for '{}'", key);
|
||||
for (const auto&[type, content] : theme["styles"].items()) {
|
||||
if (!s_styleHandlers.contains(type)) {
|
||||
log::warn("No style handler found for '{}'", type);
|
||||
continue;
|
||||
}
|
||||
|
||||
s_styleHandlers[key](name, value.get<std::string>());
|
||||
auto &handler = s_styleHandlers[type];
|
||||
for (const auto &[key, value] : content.items()) {
|
||||
if (!handler.styleMap.contains(key))
|
||||
continue;
|
||||
|
||||
auto &style = handler.styleMap.at(key);
|
||||
|
||||
if (value.is_number_float()) {
|
||||
if (auto newValue = std::get_if<float*>(&style.value); newValue != nullptr)
|
||||
**newValue = value.get<float>();
|
||||
else
|
||||
log::warn("Style variable '{}' was of type ImVec2 but a float was expected.", name);
|
||||
} else if (value.is_array() && value.size() == 2 && value[0].is_number_float() && value[1].is_number_float()) {
|
||||
if (auto newValue = std::get_if<ImVec2*>(&style.value); newValue != nullptr)
|
||||
**newValue = ImVec2(value[0].get<float>(), value[1].get<float>());
|
||||
else
|
||||
log::warn("Style variable '{}' was of type float but a ImVec2 was expected.", name);
|
||||
} else {
|
||||
hex::log::error("Theme '{}' has invalid style value for '{}.{}'!", name, type, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +171,8 @@ namespace hex::api {
|
||||
hex::log::error("Theme '{}' has invalid image postfix!", name);
|
||||
}
|
||||
}
|
||||
|
||||
s_currTheme = name;
|
||||
}
|
||||
|
||||
const std::string &ThemeManager::getThemeImagePostfix() {
|
||||
@@ -119,6 +192,7 @@ namespace hex::api {
|
||||
ThemeManager::s_styleHandlers.clear();
|
||||
ThemeManager::s_themeHandlers.clear();
|
||||
ThemeManager::s_imagePostfix.clear();
|
||||
ThemeManager::s_currTheme.clear();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user