Merge pull request #371 from lunaticwhat/a

Implement Interface customization using ImGui::ShowStyleEditor
This commit is contained in:
Taiga 2022-08-08 09:19:30 -07:00 committed by GitHub
commit 2f51c2917a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 150 additions and 47 deletions

View File

@ -431,6 +431,9 @@ namespace cheat
if (settings.f_NotificationsShow) if (settings.f_NotificationsShow)
DrawNotifications(); DrawNotifications();
if (settings.f_ShowStyleEditor)
ImGui::ShowStyleEditor();
if (settings.f_MenuKey.value().IsReleased() && !ImGui::IsAnyItemActive()) if (settings.f_MenuKey.value().IsReleased() && !ImGui::IsAnyItemActive())
ToggleMenuShow(); ToggleMenuShow();
} }

View File

@ -1,45 +1,98 @@
#include <pch.h> #include <pch.h>
#include "Settings.h" #include "Settings.h"
#include <cheat-base/render/gui-util.h>
#include <cheat-base/render/renderer.h>
#include <cheat-base/cheat/CheatManagerBase.h> #include <cheat-base/cheat/CheatManagerBase.h>
#include <cheat-base/render/renderer.h>
#include <cheat-base/render/gui-util.h>
#include <misc/cpp/imgui_stdlib.h>
#include <cheat-base/util.h>
namespace cheat::feature #include "shlwapi.h"
#pragma comment(lib, "shlwapi.lib")
namespace cheat::feature
{ {
Settings::Settings() : Feature(), Settings::Settings() : Feature(),
NF(f_MenuKey, "Show Cheat Menu Key", "General", Hotkey(VK_F1)), NF(f_MenuKey, "Show Cheat Menu Key", "General", Hotkey(VK_F1)),
NF(f_HotkeysEnabled, "Hotkeys Enabled", "General", true), NF(f_HotkeysEnabled, "Hotkeys Enabled", "General", true),
NF(f_FontSize, "Font size", "General", 16.0f),
NF(f_StatusMove, "Move Status Window", "General::StatusWindow", true), NF(f_StatusMove, "Move Status Window", "General::StatusWindow", true),
NF(f_StatusShow, "Show Status Window", "General::StatusWindow", true), NF(f_StatusShow, "Show Status Window", "General::StatusWindow", true),
NF(f_InfoMove, "Move Info Window", "General::InfoWindow", true), NF(f_InfoMove, "Move Info Window", "General::InfoWindow", true),
NF(f_InfoShow, "Show Info Window", "General::InfoWindow", true), NF(f_InfoShow, "Show Info Window", "General::InfoWindow", true),
NF(f_FpsMove, "Move FPS Indicator", "General::FPS", false), NF(f_FpsMove, "Move FPS Indicator", "General::FPS", false),
NF(f_FpsShow, "Show FPS Indicator", "General::FPS", true), NF(f_FpsShow, "Show FPS Indicator", "General::FPS", true),
NF(f_NotificationsShow, "Show Notifications", "General::Notify", true), NF(f_NotificationsShow, "Show Notifications", "General::Notify", true),
NF(f_NotificationsDelay, "Notifications Delay", "General::Notify", 500), NF(f_NotificationsDelay, "Notifications Delay", "General::Notify", 500),
NF(f_FileLogging, "File Logging", "General::Logging", false), NF(f_FileLogging, "File Logging", "General::Logging", false),
NF(f_ConsoleLogging, "Console Logging", "General::Logging", true), NF(f_ConsoleLogging, "Console Logging", "General::Logging", true),
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_ShowStyleEditor, "Show Colors Customization", "General", false),
NFS(f_DefaultTheme, "Theme", "General::Colors", "Default"),
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);
const FeatureGUIInfo& Settings::GetGUIInfo() const }
{
static const FeatureGUIInfo info{ "", "Settings", false }; bool inited = false;
return info; 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
{
static const FeatureGUIInfo info{ "", "Settings", false };
return info;
}
void Settings::Colors_Export(std::string name)
{
ImGuiStyle& style = ImGui::GetStyle();
auto colors = style.Colors;
nlohmann::json json;
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 };
std::ofstream file(themesDir / (name + ".json"));
file << std::setw(4) << json << std::endl;
}
void Settings::Colors_Import(std::string name)
{
ImGuiStyle& style = ImGui::GetStyle();
auto colors = style.Colors;
nlohmann::json json;
std::ifstream file(themesDir / (name + ".json"));
file >> json;
for (int i = 0; i < ImGuiCol_COUNT; i++)
{
auto color = json[ImGui::GetStyleColorName((ImGuiCol)i)];
colors[i].x = color[0];
colors[i].y = color[1];
colors[i].z = color[2];
colors[i].w = color[3];
}
}
void Settings::DrawMain() void Settings::DrawMain()
{ {
@ -50,12 +103,7 @@ namespace cheat::feature
"Key to toggle main menu visibility. Cannot be empty.\n"\ "Key to toggle main menu visibility. Cannot be empty.\n"\
"If you forget this key, you can see or set it in your config file."); "If you forget this key, you can see or set it in your config file.");
ConfigWidget(f_HotkeysEnabled, "Enable hotkeys."); ConfigWidget(f_HotkeysEnabled, "Enable hotkeys.");
if (ConfigWidget(f_FontSize, 1, 8, 64, "Font size for cheat interface.")) }
{
f_FontSize = std::clamp(f_FontSize.value(), 8, 64);
renderer::SetGlobalFontSize(static_cast<float>(f_FontSize));
}
}
ImGui::EndGroupPanel(); ImGui::EndGroupPanel();
ImGui::BeginGroupPanel("Logging"); ImGui::BeginGroupPanel("Logging");
@ -101,7 +149,7 @@ namespace cheat::feature
ImGui::BeginGroupPanel("Show Notifications"); ImGui::BeginGroupPanel("Show Notifications");
{ {
ConfigWidget(f_NotificationsShow, "Notifications on the bottom-right corner of the window will be displayed."); ConfigWidget(f_NotificationsShow, "Notifications on the bottom-right corner of the window will be displayed.");
ConfigWidget(f_NotificationsDelay, 1,1,10000, "Delay in milliseconds between notifications."); ConfigWidget(f_NotificationsDelay, 1, 1, 10000, "Delay in milliseconds between notifications.");
} }
ImGui::EndGroupPanel(); ImGui::EndGroupPanel();
@ -109,7 +157,7 @@ namespace cheat::feature
{ {
ConfigWidget("Enabled", ConfigWidget("Enabled",
f_FastExitEnable, f_FastExitEnable,
"Enable Fast Exit.\n" "Enable Fast Exit.\n"
); );
if (!f_FastExitEnable) if (!f_FastExitEnable)
ImGui::BeginDisabled(); ImGui::BeginDisabled();
@ -121,13 +169,54 @@ namespace cheat::feature
ImGui::EndDisabled(); ImGui::EndDisabled();
} }
ImGui::EndGroupPanel(); ImGui::EndGroupPanel();
ImGui::BeginGroupPanel("Interface Customization");
{
if (ConfigWidget(f_FontSize, 1, 8, 64, "Adjust interface font size."))
{
f_FontSize = std::clamp(f_FontSize.value(), 8, 64);
renderer::SetGlobalFontSize(static_cast<float>(f_FontSize));
}
ImGui::Spacing();
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();
if (std::filesystem::exists(themesDir / (nameBuffer_ + ".json")))
{
if (this->f_DefaultTheme.value() != nameBuffer_)
{
if (ImGui::Button("Set as default"))
{
f_DefaultTheme = nameBuffer_;
}
ImGui::SameLine();
if (ImGui::Button("Load"))
{
Colors_Import(nameBuffer_);
}
}
}
else
{
ImGui::Text("Color does not exist.");
}
}
ImGui::EndGroupPanel();
} }
Settings& Settings::GetInstance() Settings& Settings::GetInstance()
{ {
static Settings instance; static Settings instance;
return instance; return instance;
} }
void Settings::OnExitKeyPressed() void Settings::OnExitKeyPressed()
{ {
@ -137,4 +226,3 @@ namespace cheat::feature
ExitProcess(0); ExitProcess(0);
} }
} }

View File

@ -2,25 +2,24 @@
#include <cheat-base/cheat/Feature.h> #include <cheat-base/cheat/Feature.h>
#include <cheat-base/config/config.h> #include <cheat-base/config/config.h>
namespace cheat::feature namespace cheat::feature
{ {
class Settings : public Feature class Settings : public Feature
{ {
public: public:
config::Field<Hotkey> f_MenuKey; config::Field<Hotkey> f_MenuKey;
config::Field<bool> f_HotkeysEnabled; config::Field<bool> f_HotkeysEnabled;
config::Field<int> f_FontSize;
config::Field<bool> f_StatusMove; config::Field<bool> f_StatusMove;
config::Field<bool> f_StatusShow; config::Field<bool> f_StatusShow;
config::Field<bool> f_InfoMove; config::Field<bool> f_InfoMove;
config::Field<bool> f_InfoShow; config::Field<bool> f_InfoShow;
config::Field<bool> f_FpsShow; config::Field<bool> f_FpsShow;
config::Field<bool> f_FpsMove; config::Field<bool> f_FpsMove;
config::Field<bool> f_NotificationsShow; config::Field<bool> f_NotificationsShow;
config::Field<int> f_NotificationsDelay; config::Field<int> f_NotificationsDelay;
@ -30,11 +29,20 @@ namespace cheat::feature
config::Field<bool> f_FastExitEnable; config::Field<bool> f_FastExitEnable;
config::Field<Hotkey> f_HotkeyExit; config::Field<Hotkey> f_HotkeyExit;
config::Field<int> f_FontSize;
config::Field<bool> f_ShowStyleEditor;
std::filesystem::path themesDir;
config::Field<std::string> f_DefaultTheme;
static Settings& GetInstance(); static Settings& GetInstance();
const FeatureGUIInfo& GetGUIInfo() const override; const FeatureGUIInfo& GetGUIInfo() const override;
void DrawMain() override; void DrawMain() override;
void Init();
void Colors_Export(std::string name);
void Colors_Import(std::string name);
private: private:
void OnExitKeyPressed(); void OnExitKeyPressed();

View File

@ -12,6 +12,7 @@
#include <cheat-base/render/backend/dx12-hook.h> #include <cheat-base/render/backend/dx12-hook.h>
#include <cheat-base/ResourceLoader.h> #include <cheat-base/ResourceLoader.h>
#include <cheat-base/cheat/misc/Settings.h>
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
@ -33,14 +34,14 @@ namespace renderer
static constexpr int _fontsCount = _fontSizeMax / _fontSizeStep; static constexpr int _fontsCount = _fontSizeMax / _fontSizeStep;
static std::array<ImFont*, _fontsCount> _fonts; static std::array<ImFont*, _fontsCount> _fonts;
static Data _customFontData {}; static Data _customFontData{};
static WNDPROC OriginalWndProcHandler; static WNDPROC OriginalWndProcHandler;
static ID3D11RenderTargetView* mainRenderTargetView; static ID3D11RenderTargetView* mainRenderTargetView;
static void OnRenderDX11(ID3D11DeviceContext* pContext); static void OnRenderDX11(ID3D11DeviceContext* pContext);
static void OnInitializeDX11(HWND window, ID3D11Device* pDevice, ID3D11DeviceContext* pContext, IDXGISwapChain* pChain); static void OnInitializeDX11(HWND window, ID3D11Device* pDevice, ID3D11DeviceContext* pContext, IDXGISwapChain* pChain);
static void OnPreRenderDX12(); static void OnPreRenderDX12();
static void OnPostRenderDX12(ID3D12GraphicsCommandList* commandList); static void OnPostRenderDX12(ID3D12GraphicsCommandList* commandList);
static void OnInitializeDX12(HWND window, ID3D12Device* pDevice, UINT buffersCounts, ID3D12DescriptorHeap* pDescriptorHeapImGuiRender); static void OnInitializeDX12(HWND window, ID3D12Device* pDevice, UINT buffersCounts, ID3D12DescriptorHeap* pDescriptorHeapImGuiRender);
@ -106,7 +107,7 @@ namespace renderer
return io.FontDefault; return io.FontDefault;
} }
int fontSizeInt = static_cast<int>(fontSize); int fontSizeInt = static_cast<int>(fontSize);
int fontIndex = fontSizeInt / _fontSizeStep + int fontIndex = fontSizeInt / _fontSizeStep +
(fontSizeInt % _fontSizeStep > (_fontSizeStep / 2) ? 1 : 0) - 1; (fontSizeInt % _fontSizeStep > (_fontSizeStep / 2) ? 1 : 0) - 1;
fontIndex = std::clamp(fontIndex, 0, _fontsCount - 1); fontIndex = std::clamp(fontIndex, 0, _fontsCount - 1);
return _fonts[fontIndex]; return _fonts[fontIndex];
@ -122,7 +123,7 @@ namespace renderer
int fontSizeInt = static_cast<int>(fontSize); int fontSizeInt = static_cast<int>(fontSize);
int fontIndex = fontSizeInt / _fontSizeStep; int fontIndex = fontSizeInt / _fontSizeStep;
int fontAligned = fontIndex * _fontSizeStep + int fontAligned = fontIndex * _fontSizeStep +
((fontSizeInt % _fontSizeStep) > _fontSizeStep / 2 ? _fontSizeStep : 0); ((fontSizeInt % _fontSizeStep) > _fontSizeStep / 2 ? _fontSizeStep : 0);
fontAligned = std::clamp(fontAligned, _fontSizeStep, _fontSizeMax); fontAligned = std::clamp(fontAligned, _fontSizeStep, _fontSizeMax);
@ -138,7 +139,7 @@ namespace renderer
{ {
return _globalFontSize; return _globalFontSize;
} }
static void LoadCustomFont() static void LoadCustomFont()
{ {
if (_customFontData.data == nullptr) if (_customFontData.data == nullptr)
@ -195,7 +196,7 @@ namespace renderer
reinterpret_cast<LONG_PTR>(hWndProc))); reinterpret_cast<LONG_PTR>(hWndProc)));
ImGui_ImplWin32_Init(window); ImGui_ImplWin32_Init(window);
ImGui_ImplDX12_Init(pDevice, buffersCounts, DXGI_FORMAT_R8G8B8A8_UNORM, ImGui_ImplDX12_Init(pDevice, buffersCounts, DXGI_FORMAT_R8G8B8A8_UNORM,
pDescriptorHeapImGuiRender, pDescriptorHeapImGuiRender,
pDescriptorHeapImGuiRender->GetCPUDescriptorHandleForHeapStart(), pDescriptorHeapImGuiRender->GetCPUDescriptorHandleForHeapStart(),
pDescriptorHeapImGuiRender->GetGPUDescriptorHandleForHeapStart()); pDescriptorHeapImGuiRender->GetGPUDescriptorHandleForHeapStart());
@ -253,6 +254,9 @@ 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)