Merge pull request #656 from harlanx/use_theme_styles

Include styles in exported themes
This commit is contained in:
Joaquin 2022-09-12 01:56:19 -06:00 committed by GitHub
commit dfb5fb5d1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 412 additions and 154 deletions

View File

@ -303,9 +303,9 @@ namespace cheat
feature->DrawStatus(); feature->DrawStatus();
ImU32 row_bg_color = ImGui::GetColorU32( //ImU32 row_bg_color = ImGui::GetColorU32(
ImVec4(0.2f + row * 0.1f, 0.1f + row * 0.05f, 0.1f + row * 0.03f, 0.85f)); // ImVec4(0.2f + row * 0.1f, 0.1f + row * 0.05f, 0.1f + row * 0.03f, 0.85f));
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, row_bg_color); //ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, row_bg_color);
row++; row++;
} }
} }
@ -332,9 +332,9 @@ namespace cheat
if (!showAny && !settings.f_StatusMove) if (!showAny && !settings.f_StatusMove)
return; return;
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.04f, 0.05f, 0.05f, 0.90f)); //ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.04f, 0.05f, 0.05f, 0.90f));
ImGui::Begin("Info window", nullptr, flags); ImGui::Begin("Info window", nullptr, flags);
ImGui::PopStyleColor(); //ImGui::PopStyleColor();
if (!showAny) if (!showAny)
{ {

View File

@ -34,29 +34,14 @@ namespace cheat::feature
NF(f_FastExitEnable, "Fast Exit", "General::FastExit", false), NF(f_FastExitEnable, "Fast Exit", "General::FastExit", false),
NF(f_HotkeyExit, "Hotkeys", "General::FastExit", Hotkey(VK_F12)), NF(f_HotkeyExit, "Hotkeys", "General::FastExit", Hotkey(VK_F12)),
NF(f_FontSize, "Font Size", "General", 16.0f), NF(f_FontSize, "Font Size", "General::Theme", 16.0f),
NF(f_ShowStyleEditor, "Show Colors Customization", "General", false), NF(f_ShowStyleEditor, "Show Colors Customization", "General::Theme", false),
NFS(f_DefaultTheme, "Theme", "General::Colors", "Default"), NFS(f_DefaultTheme, "Theme", "General::Theme", ""),
themesDir(util::GetCurrentPath() / "themes") themesDir(util::GetCurrentPath() / "themes")
{ {
renderer::SetGlobalFontSize(static_cast<float>(f_FontSize)); renderer::SetGlobalFontSize(static_cast<float>(f_FontSize));
f_HotkeyExit.value().PressedEvent += MY_METHOD_HANDLER(Settings::OnExitKeyPressed); f_HotkeyExit.value().PressedEvent += MY_METHOD_HANDLER(Settings::OnExitKeyPressed);
if (!std::filesystem::exists(themesDir))
std::filesystem::create_directory(themesDir);
}
bool inited = false;
void Settings::Init() {
if (this->f_DefaultTheme.value() != "Default" && !inited)
{
LOG_INFO("Loading theme: %s", themesDir / (f_DefaultTheme.value() + ".json").c_str());
if (!std::filesystem::exists(themesDir / (f_DefaultTheme.value() + ".json")))
f_DefaultTheme = "Default";
else Colors_Import(f_DefaultTheme.value());
inited = true;
}
} }
const FeatureGUIInfo& Settings::GetGUIInfo() const const FeatureGUIInfo& Settings::GetGUIInfo() const
@ -65,35 +50,347 @@ namespace cheat::feature
return info; return info;
} }
void Settings::Colors_Export(std::string name) ImVec4 HexToColor(std::string hexString)
{
int r, g, b, a;
sscanf_s(hexString.c_str(), "%02x%02x%02x%02x", &r, &g, &b, &a);
ImVec4 color{ (float(r) / 255), (float(g) / 255), (float(b) / 255), (float(a) / 255) };
return color;
}
std::string ColorToHex(ImVec4& color)
{
char hex[16];
snprintf(hex, sizeof(hex), "%02x%02x%02x%02x",
static_cast<int>(ceil(color.x * 255)),
static_cast<int>(ceil(color.y * 255)),
static_cast<int>(ceil(color.z * 255)),
static_cast<int>(ceil(color.w * 255))
);
for (int i = 0; i < 16; i++)
hex[i] = toupper(hex[i]);
return hex;
}
static void DefaultTheme()
{
auto& styles = ImGui::GetStyle();
// Colors
auto colors = styles.Colors;
colors[ImGuiCol_Border] = HexToColor("26383FFF");
colors[ImGuiCol_BorderShadow] = HexToColor("33333300");
colors[ImGuiCol_Button] = HexToColor("23303DFF");
colors[ImGuiCol_ButtonActive] = HexToColor("474968FF");
colors[ImGuiCol_ButtonHovered] = HexToColor("444C70FF");
colors[ImGuiCol_CheckMark] = HexToColor("A5BCDBFF");
colors[ImGuiCol_ChildBg] = HexToColor("1E262BFF");
colors[ImGuiCol_DockingEmptyBg] = HexToColor("333333FF");
colors[ImGuiCol_DockingPreview] = HexToColor("4296F9B2");
colors[ImGuiCol_DragDropTarget] = HexToColor("FFFF00E5");
colors[ImGuiCol_FrameBg] = HexToColor("2D3F44FF");
colors[ImGuiCol_FrameBgActive] = HexToColor("30383DFF");
colors[ImGuiCol_FrameBgHovered] = HexToColor("26303DFF");
colors[ImGuiCol_Header] = HexToColor("0000003D");
colors[ImGuiCol_HeaderActive] = HexToColor("0070EAFF");
colors[ImGuiCol_HeaderHovered] = HexToColor("1E2833CC");
colors[ImGuiCol_MenuBarBg] = HexToColor("1E232DFF");
colors[ImGuiCol_ModalWindowDimBg] = HexToColor("CCCCCC59");
colors[ImGuiCol_NavHighlight] = HexToColor("4296F9FF");
colors[ImGuiCol_NavWindowingDimBg] = HexToColor("CCCCCC33");
colors[ImGuiCol_NavWindowingHighlight] = HexToColor("FFFFFFB2");
colors[ImGuiCol_PlotHistogram] = HexToColor("E5B200FF");
colors[ImGuiCol_PlotHistogramHovered] = HexToColor("FF9900FF");
colors[ImGuiCol_PlotLines] = HexToColor("9B9B9BFF");
colors[ImGuiCol_PlotLinesHovered] = HexToColor("FF6D59FF");
colors[ImGuiCol_PopupBg] = HexToColor("14161CEF");
colors[ImGuiCol_ResizeGrip] = HexToColor("A3C9F93F");
colors[ImGuiCol_ResizeGripActive] = HexToColor("6D8CB2F2");
colors[ImGuiCol_ResizeGripHovered] = HexToColor("A5BFDDAA");
colors[ImGuiCol_ScrollbarBg] = HexToColor("1C1C1C63");
colors[ImGuiCol_ScrollbarGrab] = HexToColor("875E5EFF");
colors[ImGuiCol_ScrollbarGrabActive] = HexToColor("8E1919FF");
colors[ImGuiCol_ScrollbarGrabHovered] = HexToColor("7C3A3AFF");
colors[ImGuiCol_Separator] = HexToColor("333F49FF");
colors[ImGuiCol_SeparatorActive] = HexToColor("6B91BFFF");
colors[ImGuiCol_SeparatorHovered] = HexToColor("4F7299C6");
colors[ImGuiCol_SliderGrab] = HexToColor("5977ADFF");
colors[ImGuiCol_SliderGrabActive] = HexToColor("ADCCFFFF");
colors[ImGuiCol_Tab] = HexToColor("1C262BFF");
colors[ImGuiCol_TabActive] = HexToColor("333F49FF");
colors[ImGuiCol_TabHovered] = HexToColor("969696CC");
colors[ImGuiCol_TabUnfocused] = HexToColor("1C262BFF");
colors[ImGuiCol_TabUnfocusedActive] = HexToColor("1C262BFF");
colors[ImGuiCol_TableBorderLight] = HexToColor("3A3A3FFF");
colors[ImGuiCol_TableBorderStrong] = HexToColor("4F4F59FF");
colors[ImGuiCol_TableHeaderBg] = HexToColor("303033FF");
colors[ImGuiCol_TableRowBg] = HexToColor("333F49FF");
colors[ImGuiCol_TableRowBgAlt] = HexToColor("1C262BFF");
colors[ImGuiCol_Text] = HexToColor("F2F4F9FF");
colors[ImGuiCol_TextDisabled] = HexToColor("2B353DFF");
colors[ImGuiCol_TextSelectedBg] = HexToColor("4296F959");
colors[ImGuiCol_TitleBg] = HexToColor("232D38A5");
colors[ImGuiCol_TitleBgActive] = HexToColor("212830FF");
colors[ImGuiCol_TitleBgCollapsed] = HexToColor("26262682");
colors[ImGuiCol_WindowBg] = HexToColor("1E2623FF");
//Styles
styles.Alpha = 1.0;
styles.AntiAliasedFill = true;
styles.AntiAliasedLines = true;
styles.AntiAliasedLinesUseTex = true;
styles.ButtonTextAlign = ImVec2(0.5, 0.5);
styles.CellPadding = ImVec2(4.0, 2.0);
styles.ChildBorderSize = 1.0;
styles.ChildRounding = 5.0;
styles.CircleTessellationMaxError = 0.30000001192092896;
styles.ColorButtonPosition = 1;
styles.ColumnsMinSpacing = 6.0;
styles.CurveTessellationTol = 1.25;
styles.DisabledAlpha = 0.6000000238418579;
styles.DisplaySafeAreaPadding = ImVec2(3.0, 3.0);
styles.DisplayWindowPadding = ImVec2(19.0, 19.0);
styles.FrameBorderSize = 0.0;
styles.FramePadding = ImVec2(4.0, 3.0);
styles.FrameRounding = 4.0;
styles.GrabMinSize = 10.0;
styles.GrabRounding = 4.0;
styles.IndentSpacing = 21.0;
styles.ItemInnerSpacing = ImVec2(4.0, 4.0);
styles.ItemSpacing = ImVec2(8.0, 4.0);
styles.LogSliderDeadzone = 4.0;
styles.MouseCursorScale = 1.0;
styles.PopupBorderSize = 1.0;
styles.PopupRounding = 0.0;
styles.ScrollbarRounding = 9.0;
styles.ScrollbarSize = 14.0;
styles.SelectableTextAlign = ImVec2(0.0, 0.0);
styles.TabBorderSize = 0.0;
styles.TabMinWidthForCloseButton = 0.0;
styles.TabRounding = 4.0;
styles.TouchExtraPadding = ImVec2(0.0, 0.0);
styles.WindowBorderSize = 1.0;
styles.WindowMenuButtonPosition = 0;
styles.WindowMinSize = ImVec2(32.0, 32.0);
styles.WindowPadding = ImVec2(8.0, 8.0);
styles.WindowRounding = 0.0;
styles.WindowTitleAlign = ImVec2(0.0, 0.5);
}
bool hasLoaded = false;
void Settings::Init() {
if (hasLoaded)
return;
if (!std::filesystem::exists(themesDir))
std::filesystem::create_directory(themesDir);
else
{
m_Themes.clear();
for (const auto& file : std::filesystem::directory_iterator(themesDir))
if (std::filesystem::path(file).extension() == ".json")
ThemeImport(file);
}
if (m_Themes.count(f_DefaultTheme.value()) > 0)
ApplyTheme(f_DefaultTheme.value());
else
DefaultTheme();
hasLoaded = true;
}
bool IsThemeOldFormat(nlohmann::json data)
{
if (data.count("Colors") > 0 && data.count("Styles") > 0)
return false;
return true;
}
void Settings::ThemeImport(std::filesystem::directory_entry file)
{
nlohmann::json data;
std::ifstream fs(file.path());
fs >> data;
Theme theme;
auto themeName = std::filesystem::path(file).stem().string();
bool isOldFormat = IsThemeOldFormat(data);
if (isOldFormat)
{
for (auto& [colorName, colorValue] : data.items())
{
ImVec4 color{};
color.x = colorValue[0].get<float>();
color.y = colorValue[1].get<float>();
color.z = colorValue[2].get<float>();
color.w = colorValue[3].get<float>();
theme.colors.insert({ colorName, color });
}
}
else
{
for (auto& [colorName, colorValue] : data["Colors"].items())
theme.colors.insert({ colorName, HexToColor(colorValue) });
for (auto& [styleName, styleValue] : data["Styles"].items())
{
if(styleValue.is_array())
theme.styles.insert({ styleName, ImVec2(styleValue.at(0), styleValue.at(1)) });
else if (styleValue.is_number_integer())
theme.styles.insert({ styleName, styleValue.get<int>() });
else if(styleValue.is_boolean())
theme.styles.insert({ styleName, styleValue.get<bool>() });
else
theme.styles.insert({ styleName, styleValue.get<float>() });
}
}
m_Themes.insert({ themeName, theme });
// Convert old format to new format
if(isOldFormat)
ThemeExport(themeName, true);
}
nlohmann::json GetCurrentStyles(ImGuiStyle& style)
{
nlohmann::json stylesData;
stylesData["Alpha"] = style.Alpha;
stylesData["DisabledAlpha"] = style.DisabledAlpha;
stylesData["WindowPadding"] = { style.WindowPadding.x, style.WindowPadding.y };
stylesData["WindowRounding"] = style.WindowRounding;
stylesData["WindowBorderSize"] = style.WindowBorderSize;
stylesData["WindowMinSize"] = { style.WindowMinSize.x, style.WindowMinSize.y };
stylesData["WindowTitleAlign"] = { style.WindowTitleAlign.x, style.WindowTitleAlign.y };
stylesData["WindowMenuButtonPosition"] = style.WindowMenuButtonPosition;
stylesData["ChildRounding"] = style.ChildRounding;
stylesData["ChildBorderSize"] = style.ChildBorderSize;
stylesData["PopupRounding"] = style.PopupRounding;
stylesData["PopupBorderSize"] = style.PopupBorderSize;
stylesData["FramePadding"] = { style.FramePadding.x, style.FramePadding.y };
stylesData["FrameRounding"] = style.FrameRounding;
stylesData["FrameBorderSize"] = style.FrameBorderSize;
stylesData["ItemSpacing"] = { style.ItemSpacing.x, style.ItemSpacing.y };
stylesData["ItemInnerSpacing"] = { style.ItemInnerSpacing.x,style.ItemInnerSpacing.y };
stylesData["CellPadding"] = { style.CellPadding.x, style.CellPadding.y };
stylesData["TouchExtraPadding"] = { style.TouchExtraPadding.x, style.TouchExtraPadding.y };
stylesData["IndentSpacing"] = style.IndentSpacing;
stylesData["ColumnsMinSpacing"] = style.ColumnsMinSpacing;
stylesData["ScrollbarSize"] = style.ScrollbarSize;
stylesData["ScrollbarRounding"] = style.ScrollbarRounding;
stylesData["GrabMinSize"] = style.GrabMinSize;
stylesData["GrabRounding"] = style.GrabRounding;
stylesData["LogSliderDeadzone"] = style.LogSliderDeadzone;
stylesData["TabRounding"] = style.TabRounding;
stylesData["TabBorderSize"] = style.TabBorderSize;
stylesData["TabMinWidthForCloseButton"] = style.TabMinWidthForCloseButton;
stylesData["ColorButtonPosition"] = style.ColorButtonPosition;
stylesData["ButtonTextAlign"] = { style.ButtonTextAlign.x, style.ButtonTextAlign.y };
stylesData["SelectableTextAlign"] = { style.SelectableTextAlign.x, style.SelectableTextAlign.y };
stylesData["DisplayWindowPadding"] = { style.DisplayWindowPadding.x, style.DisplayWindowPadding.y };
stylesData["DisplaySafeAreaPadding"] = { style.DisplaySafeAreaPadding.x, style.DisplaySafeAreaPadding.y };
stylesData["MouseCursorScale"] = style.MouseCursorScale;
stylesData["AntiAliasedLines"] = style.AntiAliasedLines;
stylesData["AntiAliasedLinesUseTex"] = style.AntiAliasedLinesUseTex;
stylesData["AntiAliasedFill"] = style.AntiAliasedFill;
stylesData["CurveTessellationTol"] = style.CurveTessellationTol;
stylesData["CircleTessellationMaxError"] = style.CircleTessellationMaxError;
return stylesData;
}
void Settings::ThemeExport(std::string name, bool replace)
{ {
ImGuiStyle& style = ImGui::GetStyle(); ImGuiStyle& style = ImGui::GetStyle();
auto colors = style.Colors; nlohmann::json data;
if (replace)
for (auto& [colorName, colorValue] : m_Themes[name].colors)
data["Colors"][colorName] = ColorToHex(colorValue);
nlohmann::json json; else {
auto colors = style.Colors;
for (int i = 0; i < ImGuiCol_COUNT; i++) for (int i = 0; i < ImGuiCol_COUNT; i++)
json[ImGui::GetStyleColorName((ImGuiCol)i)] = { colors[i].x, colors[i].y, colors[i].z, colors[i].w }; {
auto colorName = ImGui::GetStyleColorName((ImGuiCol)i);
data["Colors"][colorName] = ColorToHex(colors[i]);
}
}
data["Styles"] = GetCurrentStyles(style);
std::ofstream file(themesDir / (name + ".json")); std::ofstream file(themesDir / (name + ".json"));
file << std::setw(4) << json << std::endl; file << std::setw(4) << data << std::endl;
} }
void Settings::Colors_Import(std::string name) void Settings::ApplyTheme(std::string name)
{ {
ImGuiStyle& style = ImGui::GetStyle(); ImGuiStyle& style = ImGui::GetStyle();
auto colors = style.Colors; auto colors = style.Colors;
nlohmann::json json; auto& theme = m_Themes[name];
std::ifstream file(themesDir / (name + ".json"));
file >> json; // Applying Colors
if (!theme.colors.empty()) {
for (int i = 0; i < ImGuiCol_COUNT; i++) for (int i = 0; i < ImGuiCol_COUNT; i++)
{ {
auto color = json[ImGui::GetStyleColorName((ImGuiCol)i)]; auto& themeColor = theme.colors[ImGui::GetStyleColorName((ImGuiCol)i)];
colors[i].x = color[0]; colors[i].x = themeColor.x;
colors[i].y = color[1]; colors[i].y = themeColor.y;
colors[i].z = color[2]; colors[i].z = themeColor.z;
colors[i].w = color[3]; colors[i].w = themeColor.w;
} }
} }
if (!theme.styles.empty())
{
// Applying Styles
style.Alpha = std::any_cast<float>(theme.styles["Alpha"]);
style.DisabledAlpha = std::any_cast<float>(theme.styles["DisabledAlpha"]);
style.WindowPadding = std::any_cast<ImVec2>(theme.styles["WindowPadding"]);
style.WindowRounding = std::any_cast<float>(theme.styles["WindowRounding"]);
style.WindowBorderSize = std::any_cast<float>(theme.styles["WindowBorderSize"]);
style.WindowMinSize = std::any_cast<ImVec2>(theme.styles["WindowMinSize"]);
style.WindowTitleAlign = std::any_cast<ImVec2>(theme.styles["WindowTitleAlign"]);
style.WindowMenuButtonPosition = ImGuiDir(std::any_cast<int>(theme.styles["WindowMenuButtonPosition"]));
style.ChildRounding = std::any_cast<float>(theme.styles["ChildRounding"]);
style.ChildBorderSize = std::any_cast<float>(theme.styles["ChildBorderSize"]);
style.PopupRounding = std::any_cast<float>(theme.styles["PopupRounding"]);
style.PopupBorderSize = std::any_cast<float>(theme.styles["PopupBorderSize"]);
style.FramePadding = std::any_cast<ImVec2>(theme.styles["FramePadding"]);
style.FrameRounding = std::any_cast<float>(theme.styles["FrameRounding"]);
style.FrameBorderSize = std::any_cast<float>(theme.styles["FrameBorderSize"]);
style.ItemSpacing = std::any_cast<ImVec2>(theme.styles["ItemSpacing"]);
style.ItemInnerSpacing = std::any_cast<ImVec2>(theme.styles["ItemInnerSpacing"]);
style.CellPadding = std::any_cast<ImVec2>(theme.styles["CellPadding"]);
style.TouchExtraPadding = std::any_cast<ImVec2>(theme.styles["TouchExtraPadding"]);
style.IndentSpacing = std::any_cast<float>(theme.styles["IndentSpacing"]);
style.ColumnsMinSpacing = std::any_cast<float>(theme.styles["ColumnsMinSpacing"]);
style.ScrollbarSize = std::any_cast<float>(theme.styles["ScrollbarSize"]);
style.ScrollbarRounding = std::any_cast<float>(theme.styles["ScrollbarRounding"]);
style.GrabMinSize = std::any_cast<float>(theme.styles["GrabMinSize"]);
style.GrabRounding = std::any_cast<float>(theme.styles["GrabRounding"]);
style.LogSliderDeadzone = std::any_cast<float>(theme.styles["LogSliderDeadzone"]);
style.TabRounding = std::any_cast<float>(theme.styles["TabRounding"]);
style.TabBorderSize = std::any_cast<float>(theme.styles["TabBorderSize"]);
style.TabMinWidthForCloseButton = std::any_cast<float>(theme.styles["TabMinWidthForCloseButton"]);
style.ColorButtonPosition = ImGuiDir(std::any_cast<int>(theme.styles["ColorButtonPosition"]));
style.ButtonTextAlign = std::any_cast<ImVec2>(theme.styles["ButtonTextAlign"]);
style.SelectableTextAlign = std::any_cast<ImVec2>(theme.styles["SelectableTextAlign"]);
style.DisplayWindowPadding = std::any_cast<ImVec2>(theme.styles["DisplayWindowPadding"]);
style.DisplaySafeAreaPadding = std::any_cast<ImVec2>(theme.styles["DisplaySafeAreaPadding"]);
style.MouseCursorScale = std::any_cast<float>(theme.styles["MouseCursorScale"]);
style.AntiAliasedLines = std::any_cast<bool>(theme.styles["AntiAliasedLines"]);
style.AntiAliasedLinesUseTex = std::any_cast<bool>(theme.styles["AntiAliasedLinesUseTex"]);
style.AntiAliasedFill = std::any_cast<bool>(theme.styles["AntiAliasedFill"]);
style.CurveTessellationTol = std::any_cast<float>(theme.styles["CurveTessellationTol"]);
style.CircleTessellationMaxError = std::any_cast<float>(theme.styles["CircleTessellationMaxError"]);
}
LOG_INFO("Theme applied: %s", name.c_str());
}
void Settings::DrawMain() void Settings::DrawMain()
{ {
@ -172,41 +469,54 @@ namespace cheat::feature
ImGui::BeginGroupPanel("Interface Customization"); ImGui::BeginGroupPanel("Interface Customization");
{ {
if (ConfigWidget(f_FontSize, 1, 8, 64, "Adjust interface font size.")) ImGui::SetNextItemWidth(200);
if (ImGui::BeginCombo("Themes", f_DefaultTheme.value().c_str()))
{ {
f_FontSize = std::clamp(f_FontSize.value(), 8, 64); for (auto& [themeName, themeData] : m_Themes)
renderer::SetGlobalFontSize(static_cast<float>(f_FontSize)); {
bool isSelected = f_DefaultTheme.value() == themeName;
if (ImGui::Selectable(themeName.c_str(), isSelected))
{
ApplyTheme(themeName);
f_DefaultTheme = themeName;
} }
if (isSelected)
ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
ImGui::SameLine();
if (ImGui::Button("Delete Theme"))
{
std::filesystem::remove(themesDir / (f_DefaultTheme.value() + ".json"));
LOG_INFO("Deleted theme %s", f_DefaultTheme.value().c_str());
f_DefaultTheme = "";
hasLoaded = false;
Init();
}
static std::string themeNameBuffer_;
ImGui::InputText("Theme Name", &themeNameBuffer_);
if (ConfigWidget(f_FontSize, 1, 8, 64, "Adjust interface font size."))
renderer::SetGlobalFontSize(static_cast<float>(f_FontSize));
ImGui::Spacing(); ImGui::Spacing();
ConfigWidget(f_ShowStyleEditor, "Show colors customization window."); ConfigWidget(f_ShowStyleEditor, "Show colors customization window.");
ImGui::Spacing();
ImGui::Text("Save Customized Color");
static std::string nameBuffer_;
ImGui::InputText("Color Name", &nameBuffer_);
if (ImGui::Button("Save"))
Colors_Export(nameBuffer_);
ImGui::SameLine(); ImGui::SameLine();
bool alreadyExist = m_Themes.count(themeNameBuffer_) > 0;
if (ImGui::Button(alreadyExist ? "Replace Theme" : "Save Theme"))
{
if (themeNameBuffer_.empty())
return;
if (std::filesystem::exists(themesDir / (nameBuffer_ + ".json"))) ThemeExport(themeNameBuffer_);
{ hasLoaded = false;
if (this->f_DefaultTheme.value() != nameBuffer_) f_DefaultTheme = themeNameBuffer_;
{ Init();
if (ImGui::Button("Set as default")) themeNameBuffer_.clear();
{
f_DefaultTheme = nameBuffer_;
}
ImGui::SameLine();
if (ImGui::Button("Load"))
{
Colors_Import(nameBuffer_);
}
}
}
else
{
ImGui::Text("Color does not exist.");
} }
} }
ImGui::EndGroupPanel(); ImGui::EndGroupPanel();

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <cheat-base/cheat/Feature.h> #include <cheat-base/cheat/Feature.h>
#include <cheat-base/config/config.h> #include <cheat-base/config/config.h>
#include <cheat-base/util.h>
namespace cheat::feature namespace cheat::feature
{ {
@ -40,10 +41,16 @@ namespace cheat::feature
const FeatureGUIInfo& GetGUIInfo() const override; const FeatureGUIInfo& GetGUIInfo() const override;
void DrawMain() override; void DrawMain() override;
void Init(); void Init();
void Colors_Export(std::string name);
void Colors_Import(std::string name);
private: private:
struct Theme{
std::map<std::string, ImVec4> colors;
std::map<std::string, std::any> styles;
};
std::map<std::string, Theme> m_Themes;
void ThemeImport(std::filesystem::directory_entry file);
void ThemeExport(std::string name, bool replace = false);
void ApplyTheme(std::string name);
void OnExitKeyPressed(); void OnExitKeyPressed();
Settings(); Settings();

View File

@ -157,7 +157,12 @@ namespace renderer
_isCustomFontLoaded = true; _isCustomFontLoaded = true;
} }
static void SetupImGuiStyle(); static void LoadImGuiStyles()
{
auto& themes = cheat::feature::Settings::GetInstance();
themes.Init();
}
static LRESULT CALLBACK hWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK hWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnPreRenderDX12() void OnPreRenderDX12()
@ -189,7 +194,7 @@ namespace renderer
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
LoadCustomFont(); LoadCustomFont();
SetupImGuiStyle(); LoadImGuiStyles();
//Set OriginalWndProcHandler to the Address of the Original WndProc function //Set OriginalWndProcHandler to the Address of the Original WndProc function
OriginalWndProcHandler = reinterpret_cast<WNDPROC>(SetWindowLongPtr(window, GWLP_WNDPROC, OriginalWndProcHandler = reinterpret_cast<WNDPROC>(SetWindowLongPtr(window, GWLP_WNDPROC,
@ -221,7 +226,7 @@ namespace renderer
io.IniFilename = imguiPath.c_str(); io.IniFilename = imguiPath.c_str();
LoadCustomFont(); LoadCustomFont();
SetupImGuiStyle(); LoadImGuiStyles();
//Set OriginalWndProcHandler to the Address of the Original WndProc function //Set OriginalWndProcHandler to the Address of the Original WndProc function
OriginalWndProcHandler = reinterpret_cast<WNDPROC>(SetWindowLongPtr(window, GWLP_WNDPROC, OriginalWndProcHandler = reinterpret_cast<WNDPROC>(SetWindowLongPtr(window, GWLP_WNDPROC,
@ -254,9 +259,6 @@ namespace renderer
pContext->OMSetRenderTargets(1, &mainRenderTargetView, nullptr); pContext->OMSetRenderTargets(1, &mainRenderTargetView, nullptr);
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
auto& themes = cheat::feature::Settings::GetInstance();
themes.Init();
} }
static LRESULT CALLBACK hWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) static LRESULT CALLBACK hWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
@ -306,66 +308,4 @@ namespace renderer
return CallWindowProc(OriginalWndProcHandler, hWnd, uMsg, wParam, lParam); return CallWindowProc(OriginalWndProcHandler, hWnd, uMsg, wParam, lParam);
} }
static void SetupImGuiStyle()
{
ImGui::GetStyle().FrameRounding = 4.0f;
ImGui::GetStyle().GrabRounding = 4.0f;
ImVec4* colors = ImGui::GetStyle().Colors;
colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.17f, 0.21f, 0.24f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.12f, 0.15f, 0.14f, 1.00f);
colors[ImGuiCol_ChildBg] = ImVec4(0.12f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.09f, 0.11f, 0.94f);
colors[ImGuiCol_Border] = ImVec4(0.15f, 0.22f, 0.25f, 1.00f);
colors[ImGuiCol_BorderShadow] = ImVec4(0.20f, 0.20f, 0.20f, 0.00f);
colors[ImGuiCol_FrameBg] = ImVec4(0.18f, 0.25f, 0.27f, 1.00f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.15f, 0.19f, 0.24f, 1.00f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.19f, 0.22f, 0.24f, 1.00f);
colors[ImGuiCol_TitleBg] = ImVec4(0.14f, 0.18f, 0.22f, 0.65f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.13f, 0.16f, 0.19f, 1.00f);
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.15f, 0.15f, 0.15f, 0.51f);
colors[ImGuiCol_MenuBarBg] = ImVec4(0.12f, 0.14f, 0.18f, 1.00f);
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.11f, 0.11f, 0.11f, 0.39f);
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.53f, 0.37f, 0.37f, 1.00f);
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.49f, 0.23f, 0.23f, 1.00f);
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.56f, 0.10f, 0.10f, 1.00f);
colors[ImGuiCol_CheckMark] = ImVec4(0.65f, 0.74f, 0.86f, 1.00f);
colors[ImGuiCol_SliderGrab] = ImVec4(0.35f, 0.47f, 0.68f, 1.00f);
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.68f, 0.80f, 1.00f, 1.00f);
colors[ImGuiCol_Button] = ImVec4(0.14f, 0.19f, 0.24f, 1.00f);
colors[ImGuiCol_ButtonHovered] = ImVec4(0.27f, 0.30f, 0.44f, 1.00f);
colors[ImGuiCol_ButtonActive] = ImVec4(0.28f, 0.29f, 0.41f, 1.00f);
colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f);
colors[ImGuiCol_HeaderHovered] = ImVec4(0.12f, 0.16f, 0.20f, 0.80f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.00f, 0.44f, 0.92f, 1.00f);
colors[ImGuiCol_Separator] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.31f, 0.45f, 0.60f, 0.78f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.42f, 0.57f, 0.75f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.64f, 0.79f, 0.98f, 0.25f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.65f, 0.75f, 0.87f, 0.67f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.43f, 0.55f, 0.70f, 0.95f);
colors[ImGuiCol_Tab] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_TabHovered] = ImVec4(0.59f, 0.59f, 0.59f, 0.80f);
colors[ImGuiCol_TabActive] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_TabUnfocused] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
colors[ImGuiCol_TableHeaderBg] = ImVec4(0.19f, 0.19f, 0.20f, 1.00f);
colors[ImGuiCol_TableBorderStrong] = ImVec4(0.31f, 0.31f, 0.35f, 1.00f);
colors[ImGuiCol_TableBorderLight] = ImVec4(0.23f, 0.23f, 0.25f, 1.00f);
colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f);
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);
}
} }

View File

@ -17,7 +17,6 @@
namespace util namespace util
{ {
std::string GetLastErrorAsString(DWORD errorId /*= 0*/) std::string GetLastErrorAsString(DWORD errorId /*= 0*/)
{ {
//Get the error message ID, if any. //Get the error message ID, if any.

View File

@ -317,10 +317,12 @@ namespace cheat::feature
"3. You can now press Next or Previous Hotkey to Teleport through the Checklist\n" "3. You can now press Next or Previous Hotkey to Teleport through the Checklist\n"
"Initially it will teleport the player to the selection made\n" "Initially it will teleport the player to the selection made\n"
"Note: Double click or click the arrow to open teleport details"); "Note: Double click or click the arrow to open teleport details");
ConfigWidget("Enable Interpolation", f_Interpolate, "Enable interpolation between teleports when using keybinds."); ImGui::SameLine(); ImGui::SetNextItemWidth(300.0f); ConfigWidget("Enable Interpolation", f_Interpolate, "Enable interpolation between teleports when using keybinds.");
ImGui::SetNextItemWidth(300.0f);
ConfigWidget("Interpolation Speed", f_Speed, 0.1f, 0.1f, 99.0f, ConfigWidget("Interpolation Speed", f_Speed, 0.1f, 0.1f, 99.0f,
"Interpolation speed.\n recommended setting below or equal to 0.1."); "Interpolation speed.\n recommended setting below or equal to 0.1.");
ConfigWidget("Auto Teleport", f_Auto, "Enable automatic forward teleporation between teleports"); ImGui::SameLine(); ImGui::SetNextItemWidth(300.0f); ConfigWidget("Auto Teleport", f_Auto, "Enable automatic forward teleporation between teleports");
ImGui::SetNextItemWidth(300.0f);
ConfigWidget("Delay Time (s)", f_DelayTime, 1, 0, 60, "Delay (in s) between teleport.\n" ConfigWidget("Delay Time (s)", f_DelayTime, 1, 0, 60, "Delay (in s) between teleport.\n"
"Note: This is not fully tested detection-wise.\nNot recommended with low values."); "Note: This is not fully tested detection-wise.\nNot recommended with low values.");
@ -448,7 +450,7 @@ namespace cheat::feature
} }
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Text, selected ? IM_COL32(40, 90, 175, 255) : ImGui::ColorConvertFloat4ToU32(ImGui::GetStyle().Colors[ImGuiCol_Text])); ImGui::PushStyleColor(ImGuiCol_Text, selected ? ImGui::GetColorU32(ImGuiCol_CheckMark) : ImGui::GetColorU32(ImGuiCol_Text));
ImGui::Text("%s", name.c_str()); ImGui::Text("%s", name.c_str());
ImGui::PopStyleColor(); ImGui::PopStyleColor();
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())