2023-02-16 18:06:40 +01:00
|
|
|
#include "content/views/view_theme_manager.hpp"
|
|
|
|
|
2023-11-10 20:47:08 +01:00
|
|
|
#include <hex/api/content_registry.hpp>
|
2023-02-16 18:06:40 +01:00
|
|
|
#include <hex/api/theme_manager.hpp>
|
|
|
|
|
2023-03-12 18:27:29 +01:00
|
|
|
#include <wolv/io/file.hpp>
|
2023-02-16 18:06:40 +01:00
|
|
|
|
|
|
|
namespace hex::plugin::builtin {
|
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ViewThemeManager::ViewThemeManager() : View::Floating("hex.builtin.view.theme_manager.name") {
|
2024-01-08 21:51:48 +01:00
|
|
|
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.extras", "hex.builtin.view.theme_manager.name" }, ICON_VS_SYMBOL_COLOR, 2000, Shortcut::None, [&, this] {
|
2023-03-20 13:11:43 +01:00
|
|
|
this->getWindowOpenState() = true;
|
2023-02-16 18:06:40 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void ViewThemeManager::drawContent() {
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGuiExt::Header("hex.builtin.view.theme_manager.colors"_lang, true);
|
2023-02-16 18:06:40 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// Draw theme handlers
|
|
|
|
ImGui::PushID(1);
|
2023-08-29 12:14:12 +02:00
|
|
|
|
2023-11-14 22:27:29 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// Loop over each theme handler
|
|
|
|
bool anyColorHovered = false;
|
|
|
|
for (auto &[name, handler] : ThemeManager::getThemeHandlers()) {
|
|
|
|
// Create a new collapsable header for each category
|
|
|
|
if (ImGui::CollapsingHeader(name.c_str())) {
|
2023-08-29 12:14:12 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// Loop over all the individual theme settings
|
|
|
|
for (auto &[colorName, colorId] : handler.colorMap) {
|
2023-12-19 13:10:25 +01:00
|
|
|
if (m_startingColor.has_value()) {
|
|
|
|
if (m_hoveredColorId == colorId && m_hoveredHandlerName == name) {
|
|
|
|
handler.setFunction(colorId, m_startingColor.value());
|
2023-11-16 13:23:47 +01:00
|
|
|
}
|
2023-11-21 13:47:50 +01:00
|
|
|
}
|
2023-11-16 13:23:47 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// Get the current color value
|
|
|
|
auto color = handler.getFunction(colorId);
|
2023-08-29 12:14:12 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// Draw a color picker for the color
|
2024-01-04 21:33:30 +01:00
|
|
|
if (ImGui::ColorEdit4(colorName.c_str(), &color.Value.x, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreviewHalf)) {
|
2023-11-21 13:47:50 +01:00
|
|
|
// Update the color value
|
|
|
|
handler.setFunction(colorId, color);
|
2023-12-08 10:29:44 +01:00
|
|
|
EventThemeChanged::post();
|
2023-11-21 13:47:50 +01:00
|
|
|
}
|
2023-11-14 22:27:29 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
if (ImGui::IsItemHovered()) {
|
|
|
|
anyColorHovered = true;
|
2023-11-14 22:27:29 +01:00
|
|
|
|
2023-12-19 13:10:25 +01:00
|
|
|
if (!m_hoveredColorId.has_value()) {
|
|
|
|
m_hoveredColorId = colorId;
|
|
|
|
m_startingColor = color;
|
|
|
|
m_hoveredHandlerName = name;
|
2023-11-14 22:27:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-11-21 13:47:50 +01:00
|
|
|
}
|
2023-11-14 22:27:29 +01:00
|
|
|
|
2023-12-19 13:10:25 +01:00
|
|
|
if (m_hoveredHandlerName == name && m_startingColor.has_value() && m_hoveredColorId.has_value()) {
|
|
|
|
auto flashingColor = m_startingColor.value();
|
2023-11-14 22:27:29 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
const float flashProgress = std::min(1.0F, (1.0F + sinf(ImGui::GetTime() * 6)) / 2.0F);
|
|
|
|
flashingColor.Value.x = std::lerp(flashingColor.Value.x / 2, 1.0F, flashProgress);
|
|
|
|
flashingColor.Value.y = std::lerp(flashingColor.Value.y / 2, 1.0F, flashProgress);
|
|
|
|
flashingColor.Value.z = flashingColor.Value.z / 2;
|
|
|
|
flashingColor.Value.w = 1.0F;
|
2023-11-14 22:27:29 +01:00
|
|
|
|
2023-12-19 13:10:25 +01:00
|
|
|
handler.setFunction(*m_hoveredColorId, flashingColor);
|
2023-11-14 22:27:29 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
if (!anyColorHovered) {
|
2023-12-19 13:10:25 +01:00
|
|
|
handler.setFunction(m_hoveredColorId.value(), m_startingColor.value());
|
|
|
|
m_startingColor.reset();
|
|
|
|
m_hoveredColorId.reset();
|
2023-02-16 18:06:40 +01:00
|
|
|
}
|
|
|
|
}
|
2023-11-21 13:47:50 +01:00
|
|
|
}
|
|
|
|
ImGui::PopID();
|
|
|
|
|
|
|
|
|
|
|
|
ImGuiExt::Header("hex.builtin.view.theme_manager.styles"_lang);
|
|
|
|
|
|
|
|
// Draw style handlers
|
|
|
|
ImGui::PushID(2);
|
|
|
|
|
|
|
|
// Loop over each style handler
|
|
|
|
for (auto &[name, handler] : ThemeManager::getStyleHandlers()) {
|
|
|
|
// Create a new collapsable header for each category
|
|
|
|
if (ImGui::CollapsingHeader(name.c_str())) {
|
|
|
|
|
|
|
|
// Loop over all the individual style settings
|
|
|
|
for (auto &[styleName, style] : handler.styleMap) {
|
|
|
|
// Get the current style value
|
|
|
|
auto &[value, min, max, needsScaling] = style;
|
|
|
|
|
|
|
|
// Styles can either be floats or ImVec2s
|
|
|
|
// Determine which one it is and draw the appropriate slider
|
|
|
|
if (auto floatValue = std::get_if<float*>(&value); floatValue != nullptr) {
|
|
|
|
if (ImGui::SliderFloat(styleName.c_str(), *floatValue, min, max, "%.1f")) {
|
2023-12-08 10:29:44 +01:00
|
|
|
EventThemeChanged::post();
|
2023-11-21 13:47:50 +01:00
|
|
|
}
|
|
|
|
} else if (auto vecValue = std::get_if<ImVec2*>(&value); vecValue != nullptr) {
|
|
|
|
if (ImGui::SliderFloat2(styleName.c_str(), &(*vecValue)->x, min, max, "%.1f")) {
|
2023-12-08 10:29:44 +01:00
|
|
|
EventThemeChanged::post();
|
2023-05-22 13:20:25 +02:00
|
|
|
}
|
2023-02-16 18:06:40 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::PopID();
|
|
|
|
|
|
|
|
// Draw export settings
|
|
|
|
ImGuiExt::Header("hex.builtin.view.theme_manager.export"_lang);
|
2023-12-19 13:10:25 +01:00
|
|
|
ImGuiExt::InputTextIcon("hex.builtin.view.theme_manager.export.name"_lang, ICON_VS_SYMBOL_KEY, m_themeName);
|
2023-11-21 13:47:50 +01:00
|
|
|
|
|
|
|
// Draw the export buttons
|
|
|
|
if (ImGui::Button("hex.builtin.view.theme_manager.save_theme"_lang, ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
|
|
|
|
fs::openFileBrowser(fs::DialogMode::Save, { { "ImHex Theme", "json" } }, [this](const std::fs::path &path){
|
|
|
|
// Export the current theme as json
|
2023-12-19 13:10:25 +01:00
|
|
|
auto json = ThemeManager::exportCurrentTheme(m_themeName);
|
2023-11-21 13:47:50 +01:00
|
|
|
|
|
|
|
// Write the json to the file
|
|
|
|
wolv::io::File outputFile(path, wolv::io::File::Mode::Create);
|
|
|
|
outputFile.writeString(json.dump(4));
|
|
|
|
});
|
|
|
|
}
|
2023-02-16 18:06:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|