Skip to content

Commit

Permalink
🚧 WIP Loading and Dumping ImGui Styles as 'Theme' JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
effs committed Dec 19, 2022
1 parent 8012bc9 commit f641a9d
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 3 deletions.
9 changes: 9 additions & 0 deletions src/Paths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ const std::filesystem::path& Paths::Fonts() const
return m_fonts;
}

const std::filesystem::path& Paths::Theme() const
{
return m_theme;
}

const std::filesystem::path& Paths::TweakDB() const
{
return m_tweakdb;
Expand Down Expand Up @@ -80,5 +85,9 @@ Paths::Paths()

m_fonts = m_cetRoot / L"fonts";

m_theme = m_cetRoot / L"theme.json";
if (exists(m_theme) && !file_size(m_theme))
std::filesystem::remove(m_theme);

m_tweakdb = m_cetRoot / L"tweakdb";
}
2 changes: 2 additions & 0 deletions src/Paths.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ struct Paths
const std::filesystem::path& ModsRoot() const;
const std::filesystem::path& R6CacheModdedRoot() const;
const std::filesystem::path& Fonts() const;
const std::filesystem::path& Theme() const;
const std::filesystem::path& TweakDB() const;

private:
Expand All @@ -28,5 +29,6 @@ struct Paths
std::filesystem::path m_modsRoot{};
std::filesystem::path m_r6CacheModdedRoot{};
std::filesystem::path m_fonts{};
std::filesystem::path m_theme{};
std::filesystem::path m_tweakdb{};
};
114 changes: 111 additions & 3 deletions src/d3d12/D3D12_Functions.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#include <stdafx.h>
#include "../stdafx.h"

#include "D3D12.h"
#include "Options.h"
#include "Utils.h"

#include <CET.h>
#include <sol/sol.hpp>
#include <imgui_impl/dx12.h>
#include <imgui_impl/win32.h>
#include <window/window.h>
Expand Down Expand Up @@ -403,6 +404,77 @@ void D3D12::ReloadFonts()
io.Fonts->AddFontFromFileTTF(UTF16ToUTF8(customFontPath.native()).c_str(), config.SizePixels, &config, cpGlyphRanges);
}

bool StyleFromThemeJson(ImGuiStyle& aOutTheme, const nlohmann::json& aThemeJson)
{
auto schemaVersion = aThemeJson.value("cetThemeSchemaVersion", "");

if (schemaVersion != "1.0.0") {
Log::Error("Theme file schema version {} is not supported, using defaults!", schemaVersion);
return false;
}

Log::Info("Theme file loaded, using it to override defaults: {}", aThemeJson.dump(4));

auto styleParameters = aThemeJson.value("style", nlohmann::json::object());

aOutTheme.Alpha = styleParameters.value("Alpha", aOutTheme.Alpha);
aOutTheme.AntiAliasedLines = styleParameters.value("AntiAliasedLines", aOutTheme.AntiAliasedLines);
aOutTheme.AntiAliasedFill = styleParameters.value("AntiAliasedFill", aOutTheme.AntiAliasedFill);
auto windowPadding = styleParameters.value("WindowPadding", nlohmann::json::array({aOutTheme.WindowPadding.x, aOutTheme.WindowPadding.y}));
aOutTheme.WindowPadding = ImVec2(windowPadding[0], windowPadding[1]);

return true;
}

bool StyleToThemeJson(nlohmann::json& aOutJson, const ImGuiStyle& aStyle)
{
aOutJson = nlohmann::json {
{"cetThemeSchemaVersion", "1.0.0"},
{"cetThemeName", "<final merged theme in effect>"},
{"style",
{
{"Alpha", aStyle.Alpha},
{"AntiAliasedLines", aStyle.AntiAliasedLines},
{"AntiAliasedFill", aStyle.AntiAliasedFill},
{"DisplayWindowPadding", {aStyle.DisplayWindowPadding.x, aStyle.DisplayWindowPadding.y}},
{"DisplaySafeAreaPadding", {aStyle.DisplaySafeAreaPadding.x, aStyle.DisplaySafeAreaPadding.y}},
{"FramePadding", {aStyle.FramePadding.x, aStyle.FramePadding.y}},
{"FrameRounding", aStyle.FrameRounding},
{"FrameBorderSize", aStyle.FrameBorderSize},
{"WindowTitleAlign", {aStyle.WindowTitleAlign.x, aStyle.WindowTitleAlign.y}},
{"WindowPadding", {aStyle.WindowPadding.x, aStyle.WindowPadding.y}},
{"WindowRounding", aStyle.WindowRounding},
{"WindowBorderSize", aStyle.WindowBorderSize},
{"WindowMinSize", {aStyle.WindowMinSize.x, aStyle.WindowMinSize.y}},
{"ChildBorderSize", aStyle.ChildBorderSize},
{"ChildRounding", aStyle.ChildRounding},
{"PopupRounding", aStyle.PopupRounding},
{"PopupBorderSize", aStyle.PopupBorderSize},
{"TabRounding", aStyle.TabRounding},
{"TabBorderSize", aStyle.TabBorderSize},
{"TabMinWidthForCloseButton", aStyle.TabMinWidthForCloseButton},
{"ColumnsMinSpacing", aStyle.ColumnsMinSpacing},
{"CellPadding", {aStyle.CellPadding.x, aStyle.CellPadding.y}},
{"ItemSpacing", {aStyle.ItemSpacing.x, aStyle.ItemSpacing.y}},
{"ItemInnerSpacing", {aStyle.ItemInnerSpacing.x, aStyle.ItemInnerSpacing.y}},
{"TouchExtraPadding", {aStyle.TouchExtraPadding.x, aStyle.TouchExtraPadding.y}},
{"ScrollbarSize", aStyle.ScrollbarSize},
{"ScrollbarRounding", aStyle.ScrollbarRounding},
{"GrabRounding", aStyle.GrabRounding},
{"GrabMinSize", aStyle.GrabMinSize},
{"ColorButtonPosition", aStyle.ColorButtonPosition},
{"IndentSpacing", aStyle.IndentSpacing},
{"ButtonTextAlign", {aStyle.ButtonTextAlign.x, aStyle.ButtonTextAlign.y}},
{"SelectableTextAlign", {aStyle.SelectableTextAlign.x, aStyle.SelectableTextAlign.y}},
{"MouseCursorScale", aStyle.MouseCursorScale},
{"CurveTessellationTol", aStyle.CurveTessellationTol},
}
}
};

return true;
}

bool D3D12::InitializeImGui(size_t aBuffersCounts)
{
std::lock_guard _(m_imguiLock);
Expand All @@ -413,13 +485,16 @@ bool D3D12::InitializeImGui(size_t aBuffersCounts)

if (ImGui::GetCurrentContext() == nullptr)
{
Log::Info("Setting up the ImGui Theme...");

// do this once, do not repeat context creation!
IMGUI_CHECKVERSION();
ImGui::CreateContext();

// TODO - make this configurable eventually and overridable by mods for themselves easily
// setup CET default style
// ImGui defaults
ImGui::StyleColorsDark(&m_styleReference);

// CET defaults
m_styleReference.WindowRounding = 6.0f;
m_styleReference.WindowTitleAlign.x = 0.5f;
m_styleReference.ChildRounding = 6.0f;
Expand All @@ -428,6 +503,39 @@ bool D3D12::InitializeImGui(size_t aBuffersCounts)
m_styleReference.ScrollbarRounding = 12.0f;
m_styleReference.GrabRounding = 12.0f;
m_styleReference.TabRounding = 6.0f;

const auto cThemeJsonPath = GetAbsolutePath(m_paths.Theme(), "", false);

// Which we will try to override...
if (!cThemeJsonPath.empty())
{
std::ifstream themeJsonFile(cThemeJsonPath);
if(!themeJsonFile)
{
Log::Info("No theme file found, using default CET theme!");
}
else
{
const nlohmann::json cThemeJson = nlohmann::json::parse(themeJsonFile, nullptr, false, true);

if (cThemeJson.is_discarded())
{
Log::Error("Theme file found but invalid! Falling back to defaults.");
}
else
{
StyleFromThemeJson(m_styleReference, cThemeJson);
}
}

themeJsonFile.close();
}

nlohmann::json effectiveThemeJson;
StyleToThemeJson(effectiveThemeJson, m_styleReference);

Log::Info("ImGui style in effect: {}", effectiveThemeJson.dump(4));
Log::Info("Global UI scale factor: {}x", scaleFromReference);
}

ImGui::GetStyle() = m_styleReference;
Expand Down

0 comments on commit f641a9d

Please sign in to comment.