Make subtitle color configurable, and prepare for more configurable colors specific to Looper
Some checks failed
Build / build-gentoo (push) Successful in 1m52s
Build / download-system-deps (push) Successful in 5m28s
Build / get-source-code (push) Successful in 16m4s
Build / build-deb (push) Failing after 6m59s
Build / build-appimage (push) Successful in 6m19s
Build / build-android (push) Failing after 3m19s
Build / build-windows (push) Failing after 7m13s

This commit is contained in:
Zachary Hall 2025-01-15 13:52:50 -08:00
parent 3bb33cb3bf
commit a41c63d059
3 changed files with 69 additions and 15 deletions

View file

@ -488,8 +488,7 @@ void RendererBackend::EndMainMenuBar() {
menubar_end = ImGui::GetCursorPosX();
ImVec2 size = ImGui::GetWindowSize();
if (subtitle != "") {
ImVec4 text_color = ImGui::GetStyleColorVec4(ImGuiCol_Text);
text_color.w *= 0.5;
ImVec4 text_color = Theme::GetColor(LooperCol_Subtitle);
ImGui::PushStyleColor(ImGuiCol_Text, text_color);
ImGui::TextUnformatted(subtitle.c_str());
ImGui::PopStyleColor();

View file

@ -20,6 +20,7 @@ const char* Theme::prefPath = NULL;
path Theme::themeDir = path();
std::set<path> Theme::availableThemes = std::set<path>();
std::map<path, ThemeStrings> Theme::themeStrings = std::map<path, ThemeStrings>();
Theme *Theme::cur_theme = nullptr;
ImVec4 change_accent_color(ImVec4 in, float hue) {
if (in.x == in.y && in.y == in.z) {
@ -185,9 +186,11 @@ bool Theme::ShowEditor(bool* open, Theme* &theme, ImGuiID dockid, int window_wid
ImGui::BeginChild("##colors", ImVec2(0, 0), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened);
ImGui::PushItemWidth(-160);
for (int i = 0; i < ImGuiCol_COUNT; i++)
for (int i = 0; i < (int)ImGuiCol_COUNT + (int)LooperCol_COUNT; i++)
{
const char* name = ImGui::GetStyleColorName(i);
const char* name;
if (i < ImGuiCol_COUNT) name = ImGui::GetStyleColorName(i);
else name = theme->GetStyleColorName(i-ImGuiCol_COUNT);
if (!filter.PassFilter(name))
continue;
ImGui::PushID(i);
@ -197,7 +200,7 @@ bool Theme::ShowEditor(bool* open, Theme* &theme, ImGuiID dockid, int window_wid
ImGui::Checkbox(_TR_CTX("Theme Editor | Colors | (Any color) | recoloring checkbox | Saturation", "S: "), &colorizer.Saturation); ImGui::SameLine();
ImGui::Checkbox(_TR_CTX("Theme Editor | Colors | (Any color) | recoloring checkbox | Value", "V: "), &colorizer.Value); ImGui::SameLine();
ImGui::Checkbox(_TR_CTX("Theme Editor | Colors | (Any color) | recoloring checkbox | Alpha (opacity)", "A: "), &colorizer.Alpha); ImGui::SameLine();
ImGui::ColorEdit4("##color", (float*)&style.Colors[i], ImGuiColorEditFlags_AlphaBar | alpha_flags | ImGuiColorEditFlags_DisplayHSV);
ImGui::ColorEdit4("##color", (float*)&(i < ImGuiCol_COUNT ? style.Colors[i] : theme->Colors[i-ImGuiCol_COUNT]), ImGuiColorEditFlags_AlphaBar | alpha_flags | ImGuiColorEditFlags_DisplayHSV);
ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
ImGui::TextUnformatted(name);
ImGui::PopID();
@ -373,6 +376,7 @@ void Theme::Apply(ImVec4 accent, float scale) {
actual_style.WindowMinSize.y = MAX(actual_style.WindowMinSize.y, 1.0);
actual_style.CurveTessellationTol = MAX(actual_style.CurveTessellationTol, 0.1);
actual_style.CircleTessellationMaxError = MAX(actual_style.CircleTessellationMaxError, 0.1);
cur_theme = this;
}
void Theme::Save(string path) {
INFO.writefln("Saving theme to %s...", path.c_str());
@ -440,11 +444,18 @@ void Theme::Save(string path) {
}
{
toml::table colors;
for (int i = 0; i < ImGuiCol_COUNT; i++)
for (int i = 0; i < (int)ImGuiCol_COUNT + (int)LooperCol_COUNT; i++)
{
const char* name = ImGui::GetStyleColorName(i);
ImVec4 color = style.Colors[i];
toml::table colorValue;
const char *name;
ImVec4 color;
toml::table colorValue;
if (i >= ImGuiCol_COUNT) {
name = GetStyleColorName(i - ImGuiCol_COUNT);
color = this->Colors[i - ImGuiCol_COUNT];
} else {
name = ImGui::GetStyleColorName(i);
color = style.Colors[i];
}
colorValue.insert("r", color.x);
colorValue.insert("g", color.y);
colorValue.insert("b", color.z);
@ -465,6 +476,20 @@ void Theme::Save(string path) {
}
updateAvailableThemes();
}
ImVec4 Theme::GetColor(int color) {
if (cur_theme == nullptr) {
return ImVec4(255, 0, 255, 0);
} else {
return cur_theme->Colors[color];
}
}
const char *Theme::GetStyleColorName(int color) {
switch (color) {
case LooperCol_Subtitle: return "Subtitle";
}
ERROR.writefln("Invalid looper-specific color ID: %d\n", color);
return "";
}
void Theme::Save(path path) {
Save((string)path.string());
}
@ -535,9 +560,16 @@ Theme::Theme(bool dark) : Theme() {
ImGui::StyleColorsLight(&style);
style.FrameBorderSize = 1;
}
for (int i = 0; i < ImGuiCol_COUNT; i++)
this->Colors[LooperCol_Subtitle] = style.Colors[ImGuiCol_Text];
this->Colors[LooperCol_Subtitle].w *= 0.5;
for (int i = 0; i < (int)ImGuiCol_COUNT + (int)LooperCol_COUNT; i++)
{
ImVec4 color = style.Colors[i];
ImVec4 color;
if (i < ImGuiCol_COUNT) {
color = style.Colors[i];
} else {
color = this->Colors[i-ImGuiCol_COUNT];
}
auto colorizer = AccentColorizer();
if (color.x != color.y || color.y != color.z) {
colorizer.Hue = true;
@ -762,14 +794,27 @@ Theme::Theme(string path) : Theme() {
}
if (config.contains("colors")) {
toml::table colors = *config["colors"].as_table();
for (int i = 0; i < ImGuiCol_COUNT; i++)
for (int i = 0; i < (int)ImGuiCol_COUNT + (int)LooperCol_COUNT; i++)
{
const char* name = ImGui::GetStyleColorName(i);
const char* name;
if (i < ImGuiCol_COUNT) name = ImGui::GetStyleColorName(i);
else name = GetStyleColorName(i-ImGuiCol_COUNT);
if (colors.contains(name)) {
toml::table colorValue = *colors[name].as_table();
ImVec4 color = ImVec4((float)**colorValue["r"].as_floating_point(), (float)**colorValue["g"].as_floating_point(), (float)**colorValue["b"].as_floating_point(), (float)**colorValue["a"].as_floating_point());
AccentColorizers[i] = AccentColorizer(*colorValue["accent"].as_table());
style.Colors[i] = color;
if (i < ImGuiCol_COUNT) style.Colors[i] = color;
else this->Colors[i-ImGuiCol_COUNT] = color;
} else {
WARNING.writefln("Missing color upon load: %s\nThis may have a sensible default, but be sure to check the theme colors!", name);
if (i >= ImGuiCol_COUNT) {
switch (i-ImGuiCol_COUNT) {
case LooperCol_Subtitle: {
this->Colors[LooperCol_Subtitle] = style.Colors[ImGuiCol_Text];
this->Colors[LooperCol_Subtitle].w *= 0.5;
} break;
}
}
}
}
}

View file

@ -17,6 +17,12 @@ struct ThemeStrings {
ThemeStrings();
ThemeStrings(toml::table config);
};
enum LooperCol {
LooperCol_Subtitle,
// LooperCol_Title,
// LooperCol_WindowBorder,
LooperCol_COUNT
};
struct AccentColorizer {
/// @brief Whether or not to change the hue.
@ -51,7 +57,11 @@ class Theme {
static const char* prefPath;
static const int MinSchemaVersion = 0;
static const int MaxSchemaVersion = 1;
static Theme *cur_theme;
ImVec4 Colors[LooperCol_COUNT];
string file_path;
static ImVec4 GetColor(int color);
const char *GetStyleColorName(int color);
std::map<string, ThemeStrings> strings;
std::map<int, AccentColorizer> AccentColorizers;
ThemeStrings GetStrings();
@ -63,4 +73,4 @@ class Theme {
Theme(bool dark);
Theme(string path);
Theme(path path);
};
};