356 lines
25 KiB
C++
356 lines
25 KiB
C++
#include <hex/api/theme_manager.hpp>
|
|
|
|
#include <imgui.h>
|
|
#include <imgui_internal.h>
|
|
#include <implot.h>
|
|
#include <hex/ui/imgui_imhex_extensions.h>
|
|
#include <imnodes.h>
|
|
#include <TextEditor.h>
|
|
#include <romfs/romfs.hpp>
|
|
|
|
#include <hex/helpers/utils.hpp>
|
|
#include <hex/helpers/fs.hpp>
|
|
|
|
#include <hex/api/event.hpp>
|
|
|
|
#include <wolv/io/file.hpp>
|
|
|
|
namespace hex::plugin::builtin {
|
|
|
|
void registerThemeHandlers() {
|
|
EventManager::subscribe<RequestInitThemeHandlers>([]() {
|
|
{
|
|
const static ThemeManager::ColorMap ImGuiColorMap = {
|
|
{ "text", ImGuiCol_Text },
|
|
{ "text-disabled", ImGuiCol_TextDisabled },
|
|
{ "window-background", ImGuiCol_WindowBg },
|
|
{ "child-background", ImGuiCol_ChildBg },
|
|
{ "popup-background", ImGuiCol_PopupBg },
|
|
{ "border", ImGuiCol_Border },
|
|
{ "border-shadow", ImGuiCol_BorderShadow },
|
|
{ "frame-background", ImGuiCol_FrameBg },
|
|
{ "frame-background-hovered", ImGuiCol_FrameBgHovered },
|
|
{ "frame-background-active", ImGuiCol_FrameBgActive },
|
|
{ "title-background", ImGuiCol_TitleBg },
|
|
{ "title-background-active", ImGuiCol_TitleBgActive },
|
|
{ "title-background-collapse", ImGuiCol_TitleBgCollapsed },
|
|
{ "menu-bar-background", ImGuiCol_MenuBarBg },
|
|
{ "scrollbar-background", ImGuiCol_ScrollbarBg },
|
|
{ "scrollbar-grab", ImGuiCol_ScrollbarGrab },
|
|
{ "scrollbar-grab-hovered", ImGuiCol_ScrollbarGrabHovered },
|
|
{ "scrollbar-grab-active", ImGuiCol_ScrollbarGrabActive },
|
|
{ "check-mark", ImGuiCol_CheckMark },
|
|
{ "slider-grab", ImGuiCol_SliderGrab },
|
|
{ "slider-grab-active", ImGuiCol_SliderGrabActive },
|
|
{ "button", ImGuiCol_Button },
|
|
{ "button-hovered", ImGuiCol_ButtonHovered },
|
|
{ "button-active", ImGuiCol_ButtonActive },
|
|
{ "header", ImGuiCol_Header },
|
|
{ "header-hovered", ImGuiCol_HeaderHovered },
|
|
{ "header-active", ImGuiCol_HeaderActive },
|
|
{ "separator", ImGuiCol_Separator },
|
|
{ "separator-hovered", ImGuiCol_SeparatorHovered },
|
|
{ "separator-active", ImGuiCol_SeparatorActive },
|
|
{ "resize-grip", ImGuiCol_ResizeGrip },
|
|
{ "resize-grip-hovered", ImGuiCol_ResizeGripHovered },
|
|
{ "resize-grip-active", ImGuiCol_ResizeGripActive },
|
|
{ "tab", ImGuiCol_Tab },
|
|
{ "tab-hovered", ImGuiCol_TabHovered },
|
|
{ "tab-active", ImGuiCol_TabActive },
|
|
{ "tab-unfocused", ImGuiCol_TabUnfocused },
|
|
{ "tab-unfocused-active", ImGuiCol_TabUnfocusedActive },
|
|
{ "docking-preview", ImGuiCol_DockingPreview },
|
|
{ "docking-empty-background", ImGuiCol_DockingEmptyBg },
|
|
{ "plot-lines", ImGuiCol_PlotLines },
|
|
{ "plot-lines-hovered", ImGuiCol_PlotLinesHovered },
|
|
{ "plot-histogram", ImGuiCol_PlotHistogram },
|
|
{ "plot-histogram-hovered", ImGuiCol_PlotHistogramHovered },
|
|
{ "table-header-background", ImGuiCol_TableHeaderBg },
|
|
{ "table-border-strong", ImGuiCol_TableBorderStrong },
|
|
{ "table-border-light", ImGuiCol_TableBorderLight },
|
|
{ "table-row-background", ImGuiCol_TableRowBg },
|
|
{ "table-row-background-alt", ImGuiCol_TableRowBgAlt },
|
|
{ "text-selected-background", ImGuiCol_TextSelectedBg },
|
|
{ "drag-drop-target", ImGuiCol_DragDropTarget },
|
|
{ "nav-highlight", ImGuiCol_NavHighlight },
|
|
{ "nav-windowing-highlight", ImGuiCol_NavWindowingHighlight },
|
|
{ "nav-windowing-background", ImGuiCol_NavWindowingDimBg },
|
|
{ "modal-window-dim-background", ImGuiCol_ModalWindowDimBg }
|
|
};
|
|
|
|
ThemeManager::addThemeHandler("imgui", ImGuiColorMap,
|
|
[](u32 colorId) -> ImColor {
|
|
return ImGui::GetStyle().Colors[colorId];
|
|
},
|
|
[](u32 colorId, ImColor color) {
|
|
ImGui::GetStyle().Colors[colorId] = color;
|
|
}
|
|
);
|
|
}
|
|
|
|
{
|
|
const static ThemeManager::ColorMap ImPlotColorMap = {
|
|
{ "line", ImPlotCol_Line },
|
|
{ "fill", ImPlotCol_Fill },
|
|
{ "marker-outline", ImPlotCol_MarkerOutline },
|
|
{ "marker-fill", ImPlotCol_MarkerFill },
|
|
{ "error-bar", ImPlotCol_ErrorBar },
|
|
{ "frame-bg", ImPlotCol_FrameBg },
|
|
{ "plot-bg", ImPlotCol_PlotBg },
|
|
{ "plot-border", ImPlotCol_PlotBorder },
|
|
{ "legend-bg", ImPlotCol_LegendBg },
|
|
{ "legend-border", ImPlotCol_LegendBorder },
|
|
{ "legend-text", ImPlotCol_LegendText },
|
|
{ "title-text", ImPlotCol_TitleText },
|
|
{ "inlay-text", ImPlotCol_InlayText },
|
|
{ "axis-text", ImPlotCol_AxisText },
|
|
{ "axis-grid", ImPlotCol_AxisGrid },
|
|
{ "axis-tick", ImPlotCol_AxisTick },
|
|
{ "axis-bg", ImPlotCol_AxisBg },
|
|
{ "axis-bg-hovered", ImPlotCol_AxisBgHovered },
|
|
{ "axis-bg-active", ImPlotCol_AxisBgActive },
|
|
{ "selection", ImPlotCol_Selection },
|
|
{ "crosshairs", ImPlotCol_Crosshairs }
|
|
};
|
|
|
|
ThemeManager::addThemeHandler("implot", ImPlotColorMap,
|
|
[](u32 colorId) -> ImColor {
|
|
return ImPlot::GetStyle().Colors[colorId];
|
|
},
|
|
[](u32 colorId, ImColor color) {
|
|
ImPlot::GetStyle().Colors[colorId] = color;
|
|
}
|
|
);
|
|
}
|
|
|
|
{
|
|
const static ThemeManager::ColorMap ImNodesColorMap = {
|
|
{ "node-background", ImNodesCol_NodeBackground },
|
|
{ "node-background-hovered", ImNodesCol_NodeBackgroundHovered },
|
|
{ "node-background-selected", ImNodesCol_NodeBackgroundSelected },
|
|
{ "node-outline", ImNodesCol_NodeOutline },
|
|
{ "title-bar", ImNodesCol_TitleBar },
|
|
{ "title-bar-hovered", ImNodesCol_TitleBarHovered },
|
|
{ "title-bar-selected", ImNodesCol_TitleBarSelected },
|
|
{ "link", ImNodesCol_Link },
|
|
{ "link-hovered", ImNodesCol_LinkHovered },
|
|
{ "link-selected", ImNodesCol_LinkSelected },
|
|
{ "pin", ImNodesCol_Pin },
|
|
{ "pin-hovered", ImNodesCol_PinHovered },
|
|
{ "box-selector", ImNodesCol_BoxSelector },
|
|
{ "box-selector-outline", ImNodesCol_BoxSelectorOutline },
|
|
{ "grid-background", ImNodesCol_GridBackground },
|
|
{ "grid-line", ImNodesCol_GridLine },
|
|
{ "grid-line-primary", ImNodesCol_GridLinePrimary },
|
|
{ "mini-map-background", ImNodesCol_MiniMapBackground },
|
|
{ "mini-map-background-hovered", ImNodesCol_MiniMapBackgroundHovered },
|
|
{ "mini-map-outline", ImNodesCol_MiniMapOutline },
|
|
{ "mini-map-outline-hovered", ImNodesCol_MiniMapOutlineHovered },
|
|
{ "mini-map-node-background", ImNodesCol_MiniMapNodeBackground },
|
|
{ "mini-map-node-background-hovered", ImNodesCol_MiniMapNodeBackgroundHovered },
|
|
{ "mini-map-node-background-selected", ImNodesCol_MiniMapNodeBackgroundSelected },
|
|
{ "mini-map-node-outline", ImNodesCol_MiniMapNodeOutline },
|
|
{ "mini-map-link", ImNodesCol_MiniMapLink },
|
|
{ "mini-map-link-selected", ImNodesCol_MiniMapLinkSelected },
|
|
{ "mini-map-canvas", ImNodesCol_MiniMapCanvas },
|
|
{ "mini-map-canvas-outline", ImNodesCol_MiniMapCanvasOutline },
|
|
};
|
|
|
|
ThemeManager::addThemeHandler("imnodes", ImNodesColorMap,
|
|
[](u32 colorId) -> ImColor {
|
|
return ImNodes::GetStyle().Colors[colorId];
|
|
},
|
|
[](u32 colorId, ImColor color) {
|
|
ImNodes::GetStyle().Colors[colorId] = color;
|
|
}
|
|
);
|
|
}
|
|
|
|
{
|
|
const static ThemeManager::ColorMap ImHexColorMap = {
|
|
{ "desc-button", ImGuiCustomCol_DescButton },
|
|
{ "desc-button-hovered", ImGuiCustomCol_DescButtonHovered },
|
|
{ "desc-button-active", ImGuiCustomCol_DescButtonActive },
|
|
{ "toolbar-gray", ImGuiCustomCol_ToolbarGray },
|
|
{ "toolbar-red", ImGuiCustomCol_ToolbarRed },
|
|
{ "toolbar-yellow", ImGuiCustomCol_ToolbarYellow },
|
|
{ "toolbar-green", ImGuiCustomCol_ToolbarGreen },
|
|
{ "toolbar-blue", ImGuiCustomCol_ToolbarBlue },
|
|
{ "toolbar-purple", ImGuiCustomCol_ToolbarPurple },
|
|
{ "toolbar-brown", ImGuiCustomCol_ToolbarBrown },
|
|
{ "highlight", ImGuiCustomCol_Highlight },
|
|
{ "IEEE-tool-sign", ImGuiCustomCol_IEEEToolSign },
|
|
{ "IEEE-tool-exp", ImGuiCustomCol_IEEEToolExp },
|
|
{ "IEEE-tool-mantissa", ImGuiCustomCol_IEEEToolMantissa }
|
|
|
|
};
|
|
|
|
ThemeManager::addThemeHandler("imhex", ImHexColorMap,
|
|
[](u32 colorId) -> ImColor {
|
|
return static_cast<ImGui::ImHexCustomData *>(GImGui->IO.UserData)->Colors[colorId];
|
|
|
|
},
|
|
[](u32 colorId, ImColor color) {
|
|
static_cast<ImGui::ImHexCustomData *>(GImGui->IO.UserData)->Colors[colorId] = color;
|
|
}
|
|
);
|
|
}
|
|
|
|
{
|
|
const static ThemeManager::ColorMap TextEditorColorMap = {
|
|
{ "default", u32(TextEditor::PaletteIndex::Default) },
|
|
{ "keyword", u32(TextEditor::PaletteIndex::Keyword) },
|
|
{ "number", u32(TextEditor::PaletteIndex::Number) },
|
|
{ "string", u32(TextEditor::PaletteIndex::String) },
|
|
{ "char-literal", u32(TextEditor::PaletteIndex::CharLiteral) },
|
|
{ "punctuation", u32(TextEditor::PaletteIndex::Punctuation) },
|
|
{ "preprocessor", u32(TextEditor::PaletteIndex::Preprocessor) },
|
|
{ "identifier", u32(TextEditor::PaletteIndex::Identifier) },
|
|
{ "known-identifier", u32(TextEditor::PaletteIndex::KnownIdentifier) },
|
|
{ "preproc-identifier", u32(TextEditor::PaletteIndex::PreprocIdentifier) },
|
|
{ "comment", u32(TextEditor::PaletteIndex::Comment) },
|
|
{ "multi-line-comment", u32(TextEditor::PaletteIndex::MultiLineComment) },
|
|
{ "background", u32(TextEditor::PaletteIndex::Background) },
|
|
{ "cursor", u32(TextEditor::PaletteIndex::Cursor) },
|
|
{ "selection", u32(TextEditor::PaletteIndex::Selection) },
|
|
{ "error-marker", u32(TextEditor::PaletteIndex::ErrorMarker) },
|
|
{ "breakpoint", u32(TextEditor::PaletteIndex::Breakpoint) },
|
|
{ "line-number", u32(TextEditor::PaletteIndex::LineNumber) },
|
|
{ "current-line-fill", u32(TextEditor::PaletteIndex::CurrentLineFill) },
|
|
{ "current-line-fill-inactive", u32(TextEditor::PaletteIndex::CurrentLineFillInactive) },
|
|
{ "current-line-edge", u32(TextEditor::PaletteIndex::CurrentLineEdge) }
|
|
};
|
|
|
|
ThemeManager::addThemeHandler("text-editor", TextEditorColorMap,
|
|
[](u32 colorId) -> ImColor {
|
|
return TextEditor::GetPalette()[colorId];
|
|
},
|
|
[](u32 colorId, ImColor color) {
|
|
auto palette = TextEditor::GetPalette();
|
|
palette[colorId] = color;
|
|
TextEditor::SetPalette(palette);
|
|
}
|
|
);
|
|
}
|
|
});
|
|
}
|
|
|
|
void registerStyleHandlers() {
|
|
EventManager::subscribe<RequestInitThemeHandlers>([]() {
|
|
{
|
|
auto &style = ImGui::GetStyle();
|
|
const static ThemeManager::StyleMap ImGuiStyleMap = {
|
|
{ "alpha", { &style.Alpha, 0.1F, 1.0F, false } },
|
|
{ "disabled-alpha", { &style.DisabledAlpha, 0.0F, 1.0F, false } },
|
|
{ "window-padding", { &style.WindowPadding, 0.0F, 20.0F, true } },
|
|
{ "window-rounding", { &style.WindowRounding, 0.0F, 12.0F, true } },
|
|
{ "window-border-size", { &style.WindowBorderSize, 0.0F, 1.0F, true } },
|
|
{ "window-min-size", { &style.WindowMinSize, 0.0F, 1000.0F, true } },
|
|
{ "window-title-align", { &style.WindowTitleAlign, 0.0F, 1.0F , false } },
|
|
{ "child-rounding", { &style.ChildRounding, 0.0F, 12.0F, true } },
|
|
{ "child-border-size", { &style.ChildBorderSize, 0.0F, 1.0F , true } },
|
|
{ "popup-rounding", { &style.PopupRounding, 0.0F, 12.0F, true } },
|
|
{ "popup-border-size", { &style.PopupBorderSize, 0.0F, 1.0F, true } },
|
|
{ "frame-padding", { &style.FramePadding, 0.0F, 20.0F, true } },
|
|
{ "frame-rounding", { &style.FrameRounding, 0.0F, 12.0F, true } },
|
|
{ "frame-border-size", { &style.FrameBorderSize, 0.0F, 1.0F, true } },
|
|
{ "item-spacing", { &style.ItemSpacing, 0.0F, 20.0F, true } },
|
|
{ "item-inner-spacing", { &style.ItemInnerSpacing, 0.0F, 20.0F, true } },
|
|
{ "indent-spacing", { &style.IndentSpacing, 0.0F, 30.0F, true } },
|
|
{ "cell-padding", { &style.CellPadding, 0.0F, 20.0F, true } },
|
|
{ "scrollbar-size", { &style.ScrollbarSize, 0.0F, 20.0F, true } },
|
|
{ "scrollbar-rounding", { &style.ScrollbarRounding, 0.0F, 12.0F, true } },
|
|
{ "grab-min-size", { &style.GrabMinSize, 0.0F, 20.0F, true } },
|
|
{ "grab-rounding", { &style.GrabRounding, 0.0F, 12.0F, true } },
|
|
{ "tab-rounding", { &style.TabRounding, 0.0F, 12.0F, true } },
|
|
{ "button-text-align", { &style.ButtonTextAlign, 0.0F, 1.0F, false } },
|
|
{ "selectable-text-align", { &style.SelectableTextAlign, 0.0F, 1.0F, false } },
|
|
};
|
|
|
|
ThemeManager::addStyleHandler("imgui", ImGuiStyleMap);
|
|
}
|
|
|
|
{
|
|
auto &style = ImPlot::GetStyle();
|
|
const static ThemeManager::StyleMap ImPlotStyleMap = {
|
|
{ "line-weight", { &style.LineWeight, 0.0F, 5.0F, true } },
|
|
{ "marker-size", { &style.MarkerSize, 2.0F, 10.0F, true } },
|
|
{ "marker-weight", { &style.MarkerWeight, 0.0F, 5.0F, true } },
|
|
{ "fill-alpha", { &style.FillAlpha, 0.0F, 1.0F, false } },
|
|
{ "error-bar-size", { &style.ErrorBarSize, 0.0F, 10.0F, true } },
|
|
{ "error-bar-weight", { &style.ErrorBarWeight, 0.0F, 5.0F, true } },
|
|
{ "digital-bit-height", { &style.DigitalBitHeight, 0.0F, 20.0F, true } },
|
|
{ "digital-bit-gap", { &style.DigitalBitGap, 0.0F, 20.0F, true } },
|
|
{ "plot-border-size", { &style.PlotBorderSize, 0.0F, 2.0F, true } },
|
|
{ "minor-alpha", { &style.MinorAlpha, 0.0F, 1.0F, false } },
|
|
{ "major-tick-len", { &style.MajorTickLen, 0.0F, 20.0F, true } },
|
|
{ "minor-tick-len", { &style.MinorTickLen, 0.0F, 20.0F, true } },
|
|
{ "major-tick-size", { &style.MajorTickSize, 0.0F, 2.0F, true } },
|
|
{ "minor-tick-size", { &style.MinorTickSize, 0.0F, 2.0F, true } },
|
|
{ "major-grid-size", { &style.MajorGridSize, 0.0F, 2.0F, true } },
|
|
{ "minor-grid-size", { &style.MinorGridSize, 0.0F, 2.0F, true } },
|
|
{ "plot-padding", { &style.PlotPadding, 0.0F, 20.0F, true } },
|
|
{ "label-padding", { &style.LabelPadding, 0.0F, 20.0F, true } },
|
|
{ "legend-padding", { &style.LegendPadding, 0.0F, 20.0F, true } },
|
|
{ "legend-inner-padding", { &style.LegendInnerPadding, 0.0F, 10.0F, true } },
|
|
{ "legend-spacing", { &style.LegendSpacing, 0.0F, 5.0F, true } },
|
|
{ "mouse-pos-padding", { &style.MousePosPadding, 0.0F, 20.0F, true } },
|
|
{ "annotation-padding", { &style.AnnotationPadding, 0.0F, 5.0F, true } },
|
|
{ "fit-padding", { &style.FitPadding, 0.0F, 0.2F, true } },
|
|
{ "plot-default-size", { &style.PlotDefaultSize, 0.0F, 1000.0F, true } },
|
|
{ "plot-min-size", { &style.PlotMinSize, 0.0F, 300.0F, true } },
|
|
};
|
|
|
|
ThemeManager::addStyleHandler("implot", ImPlotStyleMap);
|
|
}
|
|
|
|
{
|
|
auto &style = ImNodes::GetStyle();
|
|
const static ThemeManager::StyleMap ImNodesStyleMap = {
|
|
{ "grid-spacing", { &style.GridSpacing, 0.0F, 100.0F, true } },
|
|
{ "node-corner-rounding", { &style.NodeCornerRounding, 0.0F, 12.0F, true } },
|
|
{ "node-padding", { &style.NodePadding, 0.0F, 20.0F, true } },
|
|
{ "node-border-thickness", { &style.NodeBorderThickness, 0.0F, 1.0F, true } },
|
|
{ "link-thickness", { &style.LinkThickness, 0.0F, 10.0F, true } },
|
|
{ "link-line-segments-per-length", { &style.LinkLineSegmentsPerLength, 0.0F, 2.0F, true } },
|
|
{ "link-hover-distance", { &style.LinkHoverDistance, 0.0F, 20.0F, true } },
|
|
{ "pin-circle-radius", { &style.PinCircleRadius, 0.0F, 20.0F, true } },
|
|
{ "pin-quad-side-length", { &style.PinQuadSideLength, 0.0F, 20.0F, true } },
|
|
{ "pin-triangle-side-length", { &style.PinTriangleSideLength, 0.0F, 20.0F, true } },
|
|
{ "pin-line-thickness", { &style.PinLineThickness, 0.0F, 5.0F, true } },
|
|
{ "pin-hover-radius", { &style.PinHoverRadius, 0.0F, 20.0F, true } },
|
|
{ "pin-offset", { &style.PinOffset, -10.0F, 10.0F, true } },
|
|
{ "mini-map-padding", { &style.MiniMapPadding, 0.0F, 20.0F, true } },
|
|
{ "mini-map-offset", { &style.MiniMapOffset, -10.0F, 10.0F, true } },
|
|
};
|
|
|
|
ThemeManager::addStyleHandler("imnodes", ImNodesStyleMap);
|
|
}
|
|
|
|
{
|
|
auto &style = ImGui::GetCustomStyle();
|
|
const static ThemeManager::StyleMap ImHexStyleMap = {
|
|
{ "window-blur", { &style.WindowBlur, 0.0F, 1.0F, true } },
|
|
};
|
|
|
|
ThemeManager::addStyleHandler("imhex", ImHexStyleMap);
|
|
}
|
|
});
|
|
}
|
|
|
|
void registerThemes() {
|
|
// Load built-in themes
|
|
for (const auto &theme : romfs::list("themes")) {
|
|
ThemeManager::addTheme(std::string(romfs::get(theme).string()));
|
|
}
|
|
|
|
// Load user themes
|
|
for (const auto &themeFolder : fs::getDefaultPaths(fs::ImHexPath::Themes)) {
|
|
for (const auto &theme : std::fs::directory_iterator(themeFolder)) {
|
|
if (theme.is_regular_file())
|
|
ThemeManager::addTheme(wolv::io::File(theme.path(), wolv::io::File::Mode::Read).readString());
|
|
}
|
|
}
|
|
}
|
|
|
|
} |