Files
imhex/plugins/builtin/source/content/views/view_theme_manager.cpp

134 lines
5.8 KiB
C++

#include "content/views/view_theme_manager.hpp"
#include <hex/api/content_registry/user_interface.hpp>
#include <hex/api/theme_manager.hpp>
#include <hex/api/events/events_interaction.hpp>
#include <wolv/io/file.hpp>
#include <fonts/vscode_icons.hpp>
namespace hex::plugin::builtin {
ViewThemeManager::ViewThemeManager() : View::Floating("hex.builtin.view.theme_manager.name", ICON_VS_SYMBOL_COLOR) {
ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.extras", "hex.builtin.view.theme_manager.name" }, ICON_VS_SYMBOL_COLOR, 2000, Shortcut::None, [&, this] {
this->getWindowOpenState() = true;
});
}
void ViewThemeManager::drawContent() {
ImGuiExt::Header("hex.builtin.view.theme_manager.colors"_lang, true);
// Draw theme handlers
ImGui::PushID(1);
// 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())) {
// Loop over all the individual theme settings
for (auto &[colorName, colorId] : handler.colorMap) {
if (m_startingColor.has_value()) {
if (m_hoveredColorId == colorId && m_hoveredHandlerName == name) {
handler.setFunction(colorId, m_startingColor.value());
}
}
// Get the current color value
auto color = handler.getFunction(colorId);
// Draw a color picker for the color
if (ImGui::ColorEdit4(colorName.c_str(), &color.Value.x, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_AlphaPreviewHalf)) {
// Update the color value
handler.setFunction(colorId, color);
EventThemeChanged::post();
}
if (ImGui::IsItemHovered()) {
anyColorHovered = true;
if (!m_hoveredColorId.has_value()) {
m_hoveredColorId = colorId;
m_startingColor = color;
m_hoveredHandlerName = name;
}
}
}
}
if (m_hoveredHandlerName == name && m_startingColor.has_value() && m_hoveredColorId.has_value()) {
auto flashingColor = m_startingColor.value();
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;
handler.setFunction(*m_hoveredColorId, flashingColor);
if (!anyColorHovered) {
handler.setFunction(m_hoveredColorId.value(), m_startingColor.value());
m_startingColor.reset();
m_hoveredColorId.reset();
}
}
}
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")) {
EventThemeChanged::post();
}
} else if (auto vecValue = std::get_if<ImVec2*>(&value); vecValue != nullptr) {
if (ImGui::SliderFloat2(styleName.c_str(), &(*vecValue)->x, min, max, "%.1f")) {
EventThemeChanged::post();
}
}
}
}
}
ImGui::PopID();
// Draw export settings
ImGuiExt::Header("hex.builtin.view.theme_manager.export"_lang);
ImGuiExt::InputTextIcon("hex.builtin.view.theme_manager.export.name"_lang, ICON_VS_SYMBOL_KEY, m_themeName);
// 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
auto json = ThemeManager::exportCurrentTheme(m_themeName);
// Write the json to the file
wolv::io::File outputFile(path, wolv::io::File::Mode::Create);
outputFile.writeString(json.dump(4));
});
}
}
void ViewThemeManager::drawHelpText() {
ImGuiExt::TextFormattedWrapped("This view allows you to customize the colors and styles of the ImHex interface. You can modify individual colors and styles and save them as themes that you can load later or share with others.");
}
}