2023-07-09 18:56:12 -07:00
|
|
|
#include "theme.h"
|
|
|
|
#include "imgui.h"
|
|
|
|
#include "json/value.h"
|
|
|
|
#include <cmath>
|
|
|
|
#include <exception>
|
|
|
|
#include <numbers>
|
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
|
|
|
#include <json/json.h>
|
|
|
|
#include <filesystem>
|
|
|
|
|
|
|
|
using namespace std::filesystem;
|
|
|
|
using namespace std::numbers;
|
|
|
|
const char* Theme::prefPath = NULL;
|
2023-07-10 19:27:55 -07:00
|
|
|
path Theme::themeDir = path();
|
|
|
|
std::set<path> Theme::availableThemes = std::set<path>();
|
2023-07-11 10:18:51 -07:00
|
|
|
|
|
|
|
ImVec4 change_accent_color(ImVec4 in, float hue) {
|
|
|
|
if (in.x == in.y && in.y == in.z) {
|
|
|
|
return in;
|
|
|
|
}
|
|
|
|
ImVec4 hsv = in;
|
|
|
|
ImVec4 out = in;
|
|
|
|
ImGui::ColorConvertRGBtoHSV(in.x, in.y, in.z, hsv.x, hsv.y, hsv.z);
|
|
|
|
hsv.x = hue / 360.0f;
|
|
|
|
ImGui::ColorConvertHSVtoRGB(hsv.x, hsv.y, hsv.z, out.x, out.y, out.z);
|
|
|
|
return out;
|
|
|
|
}
|
2023-07-17 15:45:43 -07:00
|
|
|
bool Theme::ShowEditor(bool* open, Theme* &theme, ImGuiID dockid, int window_width, int window_height) {
|
|
|
|
static FileBrowser importDialog(false, ImGuiFileBrowserFlags_NoTitleBar|ImGuiFileBrowserFlags_NoMove|ImGuiFileBrowserFlags_NoResize);
|
|
|
|
static FileBrowser exportDialog(true, ImGuiFileBrowserFlags_NoTitleBar|ImGuiFileBrowserFlags_NoMove|ImGuiFileBrowserFlags_NoResize);
|
2023-07-10 19:27:55 -07:00
|
|
|
static bool loadOpen = false;
|
|
|
|
static bool saveAsOpen = false;
|
2023-07-17 15:45:43 -07:00
|
|
|
ImGui::SetNextWindowDockID(dockid);
|
2023-07-09 18:56:12 -07:00
|
|
|
ImGui::Begin("Theme Editor", open);
|
2023-07-10 19:27:55 -07:00
|
|
|
ImGuiStyle& style = theme->style;
|
2023-07-09 18:56:12 -07:00
|
|
|
ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f);
|
2023-07-10 19:27:55 -07:00
|
|
|
ImVec2 buttonSize = ImVec2((ImGui::GetWindowWidth() * 0.50f) - (ImGui::GetStyle().WindowPadding.x) - (ImGui::GetStyle().ItemSpacing.x * 0.5f), 0);
|
|
|
|
if (ImGui::Button("Create light", buttonSize)) {
|
2023-07-09 18:56:12 -07:00
|
|
|
delete theme;
|
|
|
|
theme = new Theme(false);
|
|
|
|
|
|
|
|
ImGui::PopItemWidth();
|
|
|
|
ImGui::End();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
2023-07-10 19:27:55 -07:00
|
|
|
if (ImGui::Button("Create dark", buttonSize)) {
|
2023-07-09 18:56:12 -07:00
|
|
|
delete theme;
|
|
|
|
theme = new Theme(true);
|
|
|
|
|
|
|
|
ImGui::PopItemWidth();
|
|
|
|
ImGui::End();
|
|
|
|
return true;
|
|
|
|
}
|
2023-07-10 19:27:55 -07:00
|
|
|
if (ImGui::Button("Import...", buttonSize)) {
|
2023-07-09 18:56:12 -07:00
|
|
|
importDialog.SetTitle("Import theme...");
|
2023-07-17 12:21:38 -07:00
|
|
|
importDialog.SetTypeFilters("Theme JSON files", { ".json"});
|
2023-07-09 18:56:12 -07:00
|
|
|
std::string userdir = std::getenv(
|
|
|
|
#ifdef _WIN32
|
|
|
|
"UserProfile"
|
|
|
|
#else
|
|
|
|
"HOME"
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
importDialog.SetPwd(userdir);
|
|
|
|
importDialog.Open();
|
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
2023-07-10 19:27:55 -07:00
|
|
|
if (ImGui::Button("Export...", buttonSize)) {
|
2023-07-09 18:56:12 -07:00
|
|
|
exportDialog.SetTitle("Export theme...");
|
2023-07-17 12:21:38 -07:00
|
|
|
exportDialog.SetTypeFilters("Theme JSON files", { ".json"});
|
2023-07-09 18:56:12 -07:00
|
|
|
std::string userdir = std::getenv(
|
|
|
|
#ifdef _WIN32
|
|
|
|
"UserProfile"
|
|
|
|
#else
|
|
|
|
"HOME"
|
|
|
|
#endif
|
|
|
|
);
|
|
|
|
exportDialog.SetPwd(userdir);
|
|
|
|
exportDialog.Open();
|
|
|
|
}
|
2023-07-17 15:45:43 -07:00
|
|
|
if (importDialog.IsOpened()) {
|
|
|
|
importDialog.SetWindowSize(window_width, window_height);
|
|
|
|
importDialog.SetWindowPos(0, 0);
|
|
|
|
}
|
|
|
|
if (exportDialog.IsOpened()) {
|
|
|
|
exportDialog.SetWindowSize(window_width, window_height);
|
|
|
|
exportDialog.SetWindowPos(0, 0);
|
|
|
|
}
|
2023-07-09 18:56:12 -07:00
|
|
|
importDialog.Display();
|
|
|
|
exportDialog.Display();
|
2023-07-10 19:27:55 -07:00
|
|
|
if (!theme->file_path.empty()) {
|
|
|
|
if (ImGui::Button("Revert", buttonSize)) {
|
|
|
|
string file_path_backup = theme->file_path;
|
2023-07-09 18:56:12 -07:00
|
|
|
delete theme;
|
|
|
|
theme = new Theme(file_path_backup);
|
|
|
|
ImGui::PopItemWidth();
|
|
|
|
ImGui::End();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
2023-07-10 19:27:55 -07:00
|
|
|
if (ImGui::Button("Save", buttonSize)) {
|
|
|
|
theme->Save(theme->file_path);
|
2023-07-09 18:56:12 -07:00
|
|
|
}
|
|
|
|
}
|
2023-07-10 19:27:55 -07:00
|
|
|
if (ImGui::Button("Load...", buttonSize)) {
|
2023-07-09 18:56:12 -07:00
|
|
|
loadOpen = true;
|
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
2023-07-10 19:27:55 -07:00
|
|
|
if (ImGui::Button("Save as...", buttonSize)) {
|
2023-07-09 18:56:12 -07:00
|
|
|
saveAsOpen = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Simplified Settings (expose floating-pointer border sizes as boolean representing 0.0f or 1.0f)
|
|
|
|
if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f"))
|
|
|
|
style.GrabRounding = style.FrameRounding; // Make GrabRounding always the same value as FrameRounding
|
|
|
|
{ bool border = (style.WindowBorderSize > 0.0f); if (ImGui::Checkbox("WindowBorder", &border)) { style.WindowBorderSize = border ? 1.0f : 0.0f; } }
|
|
|
|
ImGui::SameLine();
|
|
|
|
{ bool border = (style.FrameBorderSize > 0.0f); if (ImGui::Checkbox("FrameBorder", &border)) { style.FrameBorderSize = border ? 1.0f : 0.0f; } }
|
|
|
|
ImGui::SameLine();
|
|
|
|
{ bool border = (style.PopupBorderSize > 0.0f); if (ImGui::Checkbox("PopupBorder", &border)) { style.PopupBorderSize = border ? 1.0f : 0.0f; } }
|
|
|
|
|
|
|
|
ImGui::Separator();
|
|
|
|
|
|
|
|
if (ImGui::BeginTabBar("##tabs", ImGuiTabBarFlags_None))
|
|
|
|
{
|
|
|
|
if (ImGui::BeginTabItem("Sizes"))
|
|
|
|
{
|
|
|
|
|
|
|
|
ImGui::SeparatorText("Borders");
|
|
|
|
ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f, 1.0f, "%.0f");
|
|
|
|
ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f, "%.0f");
|
|
|
|
ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f, "%.0f");
|
|
|
|
ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f");
|
|
|
|
ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f");
|
|
|
|
|
|
|
|
ImGui::SeparatorText("Rounding");
|
|
|
|
ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 12.0f, "%.0f");
|
|
|
|
ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 12.0f, "%.0f");
|
|
|
|
ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f");
|
|
|
|
ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 12.0f, "%.0f");
|
|
|
|
ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f");
|
|
|
|
ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f, "%.0f");
|
|
|
|
ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f, "%.0f");
|
|
|
|
|
|
|
|
ImGui::EndTabItem();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ImGui::BeginTabItem("Colors"))
|
|
|
|
{
|
|
|
|
|
|
|
|
static ImGuiTextFilter filter;
|
|
|
|
filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
|
|
|
|
|
|
|
|
static ImGuiColorEditFlags alpha_flags = 0;
|
|
|
|
if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_None)) { alpha_flags = ImGuiColorEditFlags_None; } ImGui::SameLine();
|
|
|
|
if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_AlphaPreview)) { alpha_flags = ImGuiColorEditFlags_AlphaPreview; } ImGui::SameLine();
|
|
|
|
if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) { alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf; }
|
|
|
|
|
|
|
|
ImGui::BeginChild("##colors", ImVec2(0, 0), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened);
|
|
|
|
ImGui::PushItemWidth(-160);
|
|
|
|
for (int i = 0; i < ImGuiCol_COUNT; i++)
|
|
|
|
{
|
|
|
|
const char* name = ImGui::GetStyleColorName(i);
|
|
|
|
if (!filter.PassFilter(name))
|
|
|
|
continue;
|
|
|
|
ImGui::PushID(i);
|
2023-07-10 19:27:55 -07:00
|
|
|
bool hueEnabled = theme->HueEnabledColors.contains(i);
|
2023-07-11 10:18:51 -07:00
|
|
|
if (ImGui::Checkbox("Accent", &hueEnabled)) {
|
2023-07-09 18:56:12 -07:00
|
|
|
if (hueEnabled) {
|
2023-07-10 19:27:55 -07:00
|
|
|
theme->HueEnabledColors.insert(i);
|
2023-07-09 18:56:12 -07:00
|
|
|
} else {
|
2023-07-10 19:27:55 -07:00
|
|
|
theme->HueEnabledColors.erase(i);
|
2023-07-09 18:56:12 -07:00
|
|
|
}
|
|
|
|
}
|
2023-07-11 10:18:51 -07:00
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::ColorEdit4("##color", (float*)&style.Colors[i], ImGuiColorEditFlags_AlphaBar | alpha_flags | ImGuiColorEditFlags_DisplayHSV);
|
|
|
|
ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
|
|
|
|
ImGui::TextUnformatted(name);
|
2023-07-09 18:56:12 -07:00
|
|
|
ImGui::PopID();
|
|
|
|
}
|
|
|
|
ImGui::PopItemWidth();
|
|
|
|
ImGui::EndChild();
|
|
|
|
|
|
|
|
ImGui::EndTabItem();
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::EndTabBar();
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::PopItemWidth();
|
|
|
|
ImGui::End();
|
|
|
|
if (importDialog.HasSelected()) {
|
|
|
|
path selected_path = importDialog.GetSelected();
|
|
|
|
path filename = selected_path.filename();
|
2023-07-10 19:27:55 -07:00
|
|
|
copy_file(selected_path, theme->themeDir / filename);
|
2023-07-17 13:23:02 -07:00
|
|
|
Theme::updateAvailableThemes();
|
2023-07-17 12:55:13 -07:00
|
|
|
importDialog.ClearSelected();
|
2023-07-09 18:56:12 -07:00
|
|
|
}
|
|
|
|
if (exportDialog.HasSelected()) {
|
2023-07-17 12:55:13 -07:00
|
|
|
path selected_path = exportDialog.GetSelected();
|
2023-07-10 19:27:55 -07:00
|
|
|
theme->Save(selected_path);
|
2023-07-17 12:55:13 -07:00
|
|
|
exportDialog.ClearSelected();
|
2023-07-09 18:56:12 -07:00
|
|
|
}
|
|
|
|
if (loadOpen) {
|
|
|
|
ImGui::OpenPopup("Load...");
|
2023-07-17 15:55:19 -07:00
|
|
|
ImGui::SetNextWindowPos(ImVec2(0, 0));
|
|
|
|
ImGui::SetNextWindowSize(ImVec2(window_width, window_height));
|
|
|
|
if (ImGui::BeginPopupModal("Load...", nullptr, ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize)) {
|
|
|
|
static path selectedThemePath;
|
|
|
|
static char filter[1024] = {0};
|
|
|
|
ImGui::Text("Filter:"); ImGui::SameLine();
|
|
|
|
ImGui::SetNextItemWidth(ImGui::GetWindowWidth() - ImGui::GetCursorPosX() - ImGui::GetStyle().WindowPadding.x);
|
|
|
|
ImGui::InputText("##FilterInput", filter, 1024);
|
|
|
|
ImGui::Text("Available themes...");
|
|
|
|
if (ImGui::BeginListBox("##Themes", ImVec2(ImGui::GetWindowWidth() - (ImGui::GetStyle().WindowPadding.x * 2.0f), -ImGui::GetTextLineHeightWithSpacing() - ImGui::GetStyle().WindowPadding.y))) {
|
|
|
|
for (auto themePath : Theme::availableThemes) {
|
|
|
|
if (themePath.stem().string().starts_with(filter)) {
|
|
|
|
const bool is_selected = themePath == selectedThemePath;
|
|
|
|
if (ImGui::Selectable(themePath.stem().generic_string().c_str(), is_selected)) {
|
|
|
|
selectedThemePath = themePath;
|
|
|
|
}
|
|
|
|
if (is_selected) {
|
|
|
|
ImGui::SetItemDefaultFocus();
|
|
|
|
}
|
2023-07-09 18:56:12 -07:00
|
|
|
}
|
|
|
|
}
|
2023-07-17 15:55:19 -07:00
|
|
|
ImGui::EndListBox();
|
2023-07-09 18:56:12 -07:00
|
|
|
}
|
2023-07-17 15:55:19 -07:00
|
|
|
if (ImGui::Button("Load")) {
|
|
|
|
if (!selectedThemePath.empty()) {
|
|
|
|
filter[0] = '\0';
|
|
|
|
loadOpen = false;
|
|
|
|
delete theme;
|
|
|
|
theme = new Theme(selectedThemePath);
|
|
|
|
selectedThemePath = path();
|
|
|
|
ImGui::EndPopup();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button("Cancel")) {
|
|
|
|
selectedThemePath = path();
|
2023-07-09 18:56:12 -07:00
|
|
|
filter[0] = '\0';
|
|
|
|
loadOpen = false;
|
|
|
|
}
|
2023-07-17 15:55:19 -07:00
|
|
|
ImGui::EndPopup();
|
2023-07-09 18:56:12 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (saveAsOpen) {
|
|
|
|
ImGui::OpenPopup("Save as...");
|
2023-07-17 15:55:19 -07:00
|
|
|
ImGui::SetNextWindowPos(ImVec2(0, 0));
|
|
|
|
ImGui::SetNextWindowSize(ImVec2(window_width, window_height));
|
|
|
|
if (ImGui::BeginPopupModal("Save as...", nullptr, ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize)) {
|
|
|
|
static char selectedThemeName[1024] = {0};
|
|
|
|
static char filter[1024] = {0};
|
|
|
|
ImGui::Text("Filter:"); ImGui::SameLine();
|
|
|
|
ImGui::SetNextItemWidth(ImGui::GetWindowWidth() - ImGui::GetCursorPosX() - ImGui::GetStyle().WindowPadding.x);
|
|
|
|
ImGui::InputText("##FilterInput", filter, 1024);
|
|
|
|
ImGui::Text("Available themes...");
|
|
|
|
if (ImGui::BeginListBox("##Themes", ImVec2(ImGui::GetWindowWidth() - (ImGui::GetStyle().WindowPadding.x * 2.0f), -ImGui::GetFrameHeightWithSpacing() - ImGui::GetTextLineHeightWithSpacing() - ImGui::GetStyle().WindowPadding.y))) {
|
|
|
|
for (auto themePath : Theme::availableThemes) {
|
|
|
|
if (themePath.stem().string().starts_with(filter)) {
|
|
|
|
const bool is_selected = strcmp(themePath.stem().generic_string().c_str(), selectedThemeName) == 0;
|
|
|
|
if (ImGui::Selectable(themePath.stem().generic_string().c_str(), is_selected)) {
|
|
|
|
strncpy(selectedThemeName, themePath.stem().generic_string().c_str(), 1024);
|
|
|
|
}
|
|
|
|
if (is_selected) {
|
|
|
|
ImGui::SetItemDefaultFocus();
|
|
|
|
}
|
2023-07-09 18:56:12 -07:00
|
|
|
}
|
|
|
|
}
|
2023-07-17 15:55:19 -07:00
|
|
|
ImGui::EndListBox();
|
2023-07-09 18:56:12 -07:00
|
|
|
}
|
2023-07-17 15:55:19 -07:00
|
|
|
ImGui::SetNextItemWidth(ImGui::GetWindowWidth() - (ImGui::GetStyle().WindowPadding.x * 2.0f));
|
|
|
|
ImGui::InputText("Theme name: ", selectedThemeName, 1024);
|
|
|
|
if (ImGui::Button("Save")) {
|
|
|
|
path selectedThemePath(selectedThemeName);
|
|
|
|
if (!selectedThemePath.empty() && !selectedThemePath.is_absolute()) {
|
|
|
|
selectedThemeName[0] = '\0'; // This empties the string by taking advantage of C strings.
|
|
|
|
filter[0] = '\0';
|
|
|
|
saveAsOpen = false;
|
|
|
|
theme->Save(Theme::themeDir / selectedThemePath.replace_extension(".json"));
|
|
|
|
theme->file_path = selectedThemePath.generic_string();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
|
|
if (ImGui::Button("Cancel")) {
|
|
|
|
selectedThemeName[0] = '\0'; // Same as above
|
2023-07-09 18:56:12 -07:00
|
|
|
filter[0] = '\0';
|
|
|
|
saveAsOpen = false;
|
|
|
|
}
|
2023-07-17 15:55:19 -07:00
|
|
|
ImGui::EndPopup();
|
2023-07-09 18:56:12 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
void Theme::Apply(float hue) {
|
|
|
|
ImGuiStyle& actual_style = ImGui::GetStyle();
|
|
|
|
actual_style = style;
|
|
|
|
for (int i = 0; i < ImGuiCol_COUNT; i++)
|
|
|
|
{
|
|
|
|
if (HueEnabledColors.contains(i)) {
|
|
|
|
actual_style.Colors[i] = change_accent_color(style.Colors[i], hue);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
|
|
{
|
|
|
|
actual_style.WindowRounding = 0.0f;
|
|
|
|
actual_style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void Theme::Save(string path) {
|
2023-07-17 12:55:13 -07:00
|
|
|
printf("Saving theme to %s...\n", path.c_str());
|
2023-07-09 18:56:12 -07:00
|
|
|
{
|
|
|
|
Json::Value config;
|
|
|
|
std::ofstream stream;
|
|
|
|
stream.open(path);
|
|
|
|
{
|
|
|
|
Json::Value rounding;
|
|
|
|
rounding["Frame"] = style.FrameRounding;
|
|
|
|
rounding["Window"] = style.WindowRounding;
|
|
|
|
rounding["Child"] = style.ChildRounding;
|
|
|
|
rounding["Popup"] = style.PopupRounding;
|
|
|
|
rounding["Scrollbar"] = style.ScrollbarRounding;
|
|
|
|
rounding["Grab"] = style.GrabRounding;
|
|
|
|
rounding["Tab"] = style.TabRounding;
|
|
|
|
config["rounding"] = rounding;
|
|
|
|
}
|
|
|
|
{
|
|
|
|
Json::Value borders;
|
|
|
|
borders["Frame"] = style.FrameBorderSize;
|
|
|
|
borders["Window"] = style.WindowBorderSize;
|
|
|
|
borders["Child"] = style.ChildBorderSize;
|
|
|
|
borders["Popup"] = style.PopupBorderSize;
|
|
|
|
borders["Tab"] = style.TabBorderSize;
|
|
|
|
config["borders"] = borders;
|
|
|
|
}
|
|
|
|
{
|
|
|
|
Json::Value colors;
|
|
|
|
for (int i = 0; i < ImGuiCol_COUNT; i++)
|
|
|
|
{
|
|
|
|
const char* name = ImGui::GetStyleColorName(i);
|
|
|
|
ImVec4 color = style.Colors[i];
|
|
|
|
Json::Value colorValue;
|
|
|
|
colorValue["r"] = color.x;
|
|
|
|
colorValue["g"] = color.y;
|
|
|
|
colorValue["b"] = color.z;
|
|
|
|
colorValue["a"] = color.w;
|
|
|
|
colorValue["ConvertToAccent"] = HueEnabledColors.contains(i);
|
|
|
|
colors[name] = colorValue;
|
|
|
|
}
|
|
|
|
config["colors"] = colors;
|
|
|
|
}
|
|
|
|
stream << config;
|
|
|
|
stream.close();
|
|
|
|
}
|
|
|
|
updateAvailableThemes();
|
|
|
|
}
|
2023-07-16 19:59:23 -07:00
|
|
|
void Theme::Save(path path) {
|
2023-07-17 12:55:13 -07:00
|
|
|
Save((string)path.string());
|
2023-07-16 19:59:23 -07:00
|
|
|
}
|
2023-07-09 18:56:12 -07:00
|
|
|
void Theme::updateAvailableThemes() {
|
2023-07-10 19:27:55 -07:00
|
|
|
themeDir = path(prefPath) / path("themes");
|
|
|
|
create_directories(themeDir);
|
2023-07-09 18:56:12 -07:00
|
|
|
availableThemes.clear();
|
|
|
|
for (auto const& dir_entry : directory_iterator(themeDir)) {
|
|
|
|
if (dir_entry.is_regular_file()) {
|
|
|
|
if (dir_entry.path().extension().string() == ".json") {
|
|
|
|
availableThemes.insert(dir_entry.path());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Theme::Theme() {
|
|
|
|
if (prefPath == NULL) {
|
|
|
|
throw std::exception();
|
|
|
|
}
|
|
|
|
updateAvailableThemes();
|
|
|
|
}
|
|
|
|
|
|
|
|
Theme::Theme(bool dark) : Theme() {
|
|
|
|
if (dark) {
|
|
|
|
ImGui::StyleColorsDark(&style);
|
|
|
|
} else {
|
|
|
|
ImGui::StyleColorsLight(&style);
|
|
|
|
style.FrameBorderSize = 1;
|
|
|
|
}
|
|
|
|
for (int i = 0; i < ImGuiCol_COUNT; i++)
|
|
|
|
{
|
2023-07-11 10:18:51 -07:00
|
|
|
ImVec4 color = style.Colors[i];
|
|
|
|
if (color.x != color.y || color.y != color.z) {
|
|
|
|
HueEnabledColors.insert(i);
|
|
|
|
}
|
2023-07-09 18:56:12 -07:00
|
|
|
}
|
|
|
|
style.FrameRounding = 12;
|
|
|
|
style.GrabRounding = 12;
|
|
|
|
style.WindowRounding = 12;
|
|
|
|
}
|
|
|
|
Theme::Theme(string path) : Theme() {
|
|
|
|
Json::Value config;
|
|
|
|
std::ifstream stream;
|
|
|
|
stream.open(path);
|
|
|
|
if (stream.is_open()) {
|
|
|
|
stream >> config;
|
|
|
|
if (config.isMember("rounding")) {
|
|
|
|
Json::Value rounding = config["rounding"];
|
|
|
|
style.FrameRounding = rounding["Frame"].asFloat();
|
|
|
|
style.WindowRounding = rounding["Window"].asFloat();
|
|
|
|
style.ChildRounding = rounding["Child"].asFloat();
|
|
|
|
style.PopupRounding = rounding["Popup"].asFloat();
|
|
|
|
style.ScrollbarRounding = rounding["Scrollbar"].asFloat();
|
|
|
|
style.GrabRounding = rounding["Grab"].asFloat();
|
|
|
|
style.TabRounding = rounding["Tab"].asFloat();
|
|
|
|
}
|
|
|
|
if (config.isMember("borders")) {
|
|
|
|
Json::Value borders = config["borders"];
|
|
|
|
style.FrameBorderSize = borders["Frame"].asFloat();
|
|
|
|
style.WindowBorderSize = borders["Window"].asFloat();
|
|
|
|
style.ChildBorderSize = borders["Child"].asFloat();
|
|
|
|
style.PopupBorderSize = borders["Popup"].asFloat();
|
|
|
|
style.TabBorderSize = borders["Tab"].asFloat();
|
|
|
|
}
|
|
|
|
if (config.isMember("colors")) {
|
|
|
|
Json::Value colors = config["colors"];
|
|
|
|
for (int i = 0; i < ImGuiCol_COUNT; i++)
|
|
|
|
{
|
|
|
|
const char* name = ImGui::GetStyleColorName(i);
|
|
|
|
if (colors.isMember(name)) {
|
|
|
|
Json::Value colorValue = colors[name];
|
|
|
|
ImVec4 color = ImVec4(colorValue["r"].asFloat(), colorValue["g"].asFloat(), colorValue["b"].asFloat(), colorValue["a"].asFloat());
|
|
|
|
bool hueShifted = colorValue["ConvertToAccent"].asBool();
|
|
|
|
style.Colors[i] = color;
|
|
|
|
if (hueShifted) {
|
|
|
|
HueEnabledColors.insert(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
stream.close();
|
|
|
|
}
|
|
|
|
file_path = path;
|
2023-07-16 19:59:23 -07:00
|
|
|
}
|
|
|
|
Theme::Theme(path path) : Theme(path.string()) {
|
|
|
|
|
2023-07-09 18:56:12 -07:00
|
|
|
}
|