diff --git a/term/imguial_term.cpp b/term/imguial_term.cpp index 67b5adb..b761a50 100644 --- a/term/imguial_term.cpp +++ b/term/imguial_term.cpp @@ -304,7 +304,95 @@ void ImGuiAl::Log::error(char const* const format, va_list args) { vprintf(format, args); } -int ImGuiAl::Log::draw(ImVec2 const& size) { +// Utilities to find colors that contrast well with the background (WindowBg color) +namespace AutomatiColors +{ + enum class LogColorClass { Debug_Blue, Info_Green, Warning_Yellow, Error_Red }; + + enum class LogColorState { Button, ButtonHovered, Text }; + + float logColorClassHue(LogColorClass c, LogColorState state) + { + constexpr float hBlue = 130.f / 255.f, hGreen = 94.f / 255.f, + hRed = 0.f, hYellow = 42.f / 255.f; + constexpr float hBlueHovered = 117. / 255.f, hGreenHovered = 56.f / 255.f, + hRedHovered = 228.f / 255.f, hYellowHovered = 36.f / 255.f; + if (state == LogColorState::ButtonHovered) + { + if (c == LogColorClass::Info_Green) + return hGreenHovered; + else if (c == LogColorClass::Warning_Yellow) + return hYellowHovered; + else if (c == LogColorClass::Error_Red) + return hRedHovered; + else + return hBlueHovered; + } + else + { + if (c == LogColorClass::Info_Green) + return hGreen; + else if (c == LogColorClass::Warning_Yellow) + return hYellow; + else if (c == LogColorClass::Error_Red) + return hRed; + else + return hBlue; + } + } + + ImU32 makeColor(LogColorClass logColorClass, LogColorState logColorState, float windowBgHsv_Value) + { + float wantedHue = logColorClassHue(logColorClass, logColorState); + + float adaptedValue = 1.f; + if (windowBgHsv_Value < 0.8f) + adaptedValue = 0.9f; + else + adaptedValue = 0.6f; + + float resultHsv[3] = { wantedHue, 1.f, adaptedValue }; + + float resultRgb[3]; + ImGui::ColorConvertHSVtoRGB(resultHsv[0], resultHsv[1], resultHsv[2], resultRgb[0], resultRgb[1], resultRgb[2]); + + ImVec4 r { resultRgb[0], resultRgb[1], resultRgb[2], 1.f }; + return ImGui::GetColorU32(r); + } +} // namespace AutomatiColors + +void ImGuiAl::Log::setColorsAutoFromWindowBg() +{ + ImVec4 windowBgColor = ImGui::GetStyle().Colors[ImGuiCol_WindowBg]; + float windowBgHsv[3]; + ImGui::ColorConvertRGBtoHSV(windowBgColor.x, windowBgColor.y, windowBgColor.z, windowBgHsv[0], windowBgHsv[1], windowBgHsv[2]); + float windowBgHsv_Value = windowBgHsv[2]; + + using namespace AutomatiColors; + + _debugButtonColor = makeColor(LogColorClass::Debug_Blue, LogColorState::Button, windowBgHsv_Value); + _debugButtonHoveredColor = makeColor(LogColorClass::Debug_Blue, LogColorState::ButtonHovered, windowBgHsv_Value); + _debugTextColor = makeColor(LogColorClass::Debug_Blue, LogColorState::Text, windowBgHsv_Value); + + _infoButtonColor = makeColor(LogColorClass::Info_Green, LogColorState::Button, windowBgHsv_Value); + _infoButtonHoveredColor = makeColor(LogColorClass::Info_Green, LogColorState::ButtonHovered, windowBgHsv_Value); + _infoTextColor = makeColor(LogColorClass::Info_Green, LogColorState::Text, windowBgHsv_Value); + + _warningButtonColor = makeColor(LogColorClass::Warning_Yellow, LogColorState::Button, windowBgHsv_Value); + _warningButtonHoveredColor = makeColor(LogColorClass::Warning_Yellow, LogColorState::ButtonHovered, windowBgHsv_Value); + _warningTextColor = makeColor(LogColorClass::Warning_Yellow, LogColorState::Text, windowBgHsv_Value); + + _errorButtonColor = makeColor(LogColorClass::Error_Red, LogColorState::Button, windowBgHsv_Value); + _errorButtonHoveredColor = makeColor(LogColorClass::Error_Red, LogColorState::ButtonHovered, windowBgHsv_Value); + _errorTextColor = makeColor(LogColorClass::Error_Red, LogColorState::Text, windowBgHsv_Value); +} + + +int ImGuiAl::Log::draw(ImVec2 const& size) +{ + if (_useAutomaticColors) + setColorsAutoFromWindowBg(); + int action = 0; for (unsigned i = 0; _actions != nullptr && _actions[i] != nullptr; i++) { @@ -318,6 +406,8 @@ int ImGuiAl::Log::draw(ImVec2 const& size) { } if ((_filterHeaderLabel != nullptr && ImGui::CollapsingHeader(_filterHeaderLabel))) { + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.2f, 0.2f, 0.2f, 1.f)); + ImGui::PushStyleColor(ImGuiCol_Button, _debugButtonColor); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, _debugButtonHoveredColor); ImGui::PushStyleColor(ImGuiCol_ButtonActive, _debugTextColor); @@ -341,7 +431,7 @@ int ImGuiAl::Log::draw(ImVec2 const& size) { _level = Level::Info; scrollToBottom(); } - + ImGui::PopStyleColor(); ImGui::SameLine(); ImGui::PushStyleColor(ImGuiCol_Button, _warningButtonColor); diff --git a/term/imguial_term.h b/term/imguial_term.h index ba0dbba..9371f41 100644 --- a/term/imguial_term.h +++ b/term/imguial_term.h @@ -143,6 +143,7 @@ namespace ImGuiAl { void setFilterLabel(char const* const label); void setFilterHeaderLabel(char const* const label); void setActions(char const* actions[]); + void setColorsAutoFromWindowBg(); protected: ImU32 _debugTextColor; @@ -160,6 +161,7 @@ namespace ImGuiAl { ImU32 _errorTextColor; ImU32 _errorButtonColor; ImU32 _errorButtonHoveredColor; + bool _useAutomaticColors = true; char const* _debugLabel; char const* _infoLabel;