mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-08 07:27:41 -06:00
Fix Dark Mode issues on Linux(via LAB) (#5044)
* GUI_App.cpp: trailing whitespace cleanup Signed-off-by: Jamin W. Collins <jamin.collins@gmail.com> * StateColor.hpp: trailing whitespace cleanup Signed-off-by: Jamin W. Collins <jamin.collins@gmail.com> * implementing LAB color routines Signed-off-by: Jamin W. Collins <jamin.collins@gmail.com> * Fixes 3667: light/dark fixes for Unsaved Changes dialog Signed-off-by: Jamin W. Collins <jamin.collins@gmail.com> * Fixes: 3675 - set dark mode colors for tabs Signed-off-by: Jamin W. Collins <jamin.collins@gmail.com> * GUI_App: use LAB for fallback and sanity checks Signed-off-by: Jamin W. Collins <jamin.collins@gmail.com> --------- Signed-off-by: Jamin W. Collins <jamin.collins@gmail.com> Co-authored-by: SoftFever <softfeverever@gmail.com>
This commit is contained in:
parent
d163cea8f8
commit
315eee3493
4 changed files with 166 additions and 15 deletions
|
@ -959,7 +959,7 @@ void GUI_App::post_init()
|
|||
|
||||
if (app_config->get("stealth_mode") == "false")
|
||||
hms_query = new HMSQuery();
|
||||
|
||||
|
||||
m_show_gcode_window = app_config->get_bool("show_gcode_window");
|
||||
if (m_networking_need_update) {
|
||||
//updating networking
|
||||
|
@ -2807,7 +2807,7 @@ void GUI_App::init_label_colours()
|
|||
m_color_label_modified = is_dark_mode ? wxColour("#F1754E") : wxColour("#F1754E");
|
||||
m_color_label_sys = is_dark_mode ? wxColour("#B2B3B5") : wxColour("#363636");
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) || defined(__linux__) || defined(__APPLE__)
|
||||
m_color_label_default = is_dark_mode ? wxColour(250, 250, 250) : m_color_label_sys; // wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
|
||||
m_color_highlight_label_default = is_dark_mode ? wxColour(230, 230, 230): wxSystemSettings::GetColour(/*wxSYS_COLOUR_HIGHLIGHTTEXT*/wxSYS_COLOUR_WINDOWTEXT);
|
||||
m_color_highlight_default = is_dark_mode ? wxColour(78, 78, 78) : wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT);
|
||||
|
@ -2920,22 +2920,38 @@ void GUI_App::UpdateDarkUI(wxWindow* window, bool highlited/* = false*/, bool ju
|
|||
|
||||
/*if (m_is_dark_mode != dark_mode() )
|
||||
m_is_dark_mode = dark_mode();*/
|
||||
|
||||
|
||||
if (m_is_dark_mode) {
|
||||
auto original_col = window->GetBackgroundColour();
|
||||
auto bg_col = StateColor::darkModeColorFor(original_col);
|
||||
|
||||
if (bg_col != original_col) {
|
||||
auto orig_col = window->GetBackgroundColour();
|
||||
auto bg_col = StateColor::darkModeColorFor(orig_col);
|
||||
// there are cases where the background color of an item is bright, specifically:
|
||||
// * the background color of a button: #009688 -- 73
|
||||
if (bg_col != orig_col) {
|
||||
window->SetBackgroundColour(bg_col);
|
||||
}
|
||||
|
||||
original_col = window->GetForegroundColour();
|
||||
auto fg_col = StateColor::darkModeColorFor(original_col);
|
||||
orig_col = window->GetForegroundColour();
|
||||
auto fg_col = StateColor::darkModeColorFor(orig_col);
|
||||
auto fg_l = StateColor::GetLightness(fg_col);
|
||||
|
||||
if (fg_col != original_col) {
|
||||
window->SetForegroundColour(fg_col);
|
||||
auto color_difference = StateColor::GetColorDifference(bg_col, fg_col);
|
||||
|
||||
// fallback and sanity check with LAB
|
||||
// color difference of less than 2 or 3 is not normally visible, and even less than 30-40 doesn't stand out
|
||||
if (color_difference < 10) {
|
||||
fg_col = StateColor::SetLightness(fg_col, 90);
|
||||
}
|
||||
// some of the stock colors have a lightness of ~49
|
||||
if (fg_l < 45) {
|
||||
fg_col = StateColor::SetLightness(fg_col, 70);
|
||||
}
|
||||
// at this point it shouldn't be possible that fg_col is the same as bg_col, but let's be safe
|
||||
if (fg_col == bg_col) {
|
||||
fg_col = StateColor::SetLightness(fg_col, 70);
|
||||
}
|
||||
|
||||
window->SetForegroundColour(fg_col);
|
||||
}
|
||||
else {
|
||||
auto original_col = window->GetBackgroundColour();
|
||||
|
@ -3891,7 +3907,7 @@ void GUI_App::on_http_error(wxCommandEvent &evt)
|
|||
MessageDialog msg_dlg(nullptr, _L("The version of Orca Slicer is too low and needs to be updated to the latest version before it can be used normally"), "", wxAPPLY | wxOK);
|
||||
if (msg_dlg.ShowModal() == wxOK) {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// request login
|
||||
|
|
|
@ -1533,7 +1533,6 @@ void UnsavedChangesDialog::update_list()
|
|||
text_left->SetFont(::Label::Head_13);
|
||||
text_left->Wrap(-1);
|
||||
text_left->SetForegroundColour(GREY700);
|
||||
text_left->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT));
|
||||
|
||||
sizer_left_v->Add(text_left, 0, wxLEFT, 37);
|
||||
|
||||
|
@ -1562,7 +1561,6 @@ void UnsavedChangesDialog::update_list()
|
|||
text_left->SetFont(::Label::Body_13);
|
||||
text_left->Wrap(-1);
|
||||
text_left->SetForegroundColour(GREY700);
|
||||
text_left->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT));
|
||||
|
||||
sizer_left_v->Add(text_left, 0, wxLEFT, 51 );
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "StateColor.hpp"
|
||||
#include <cmath>
|
||||
|
||||
static bool gDarkMode = false;
|
||||
|
||||
|
@ -41,7 +42,136 @@ static std::map<wxColour, wxColour> gDarkColors{
|
|||
//{"#F0F0F0", "#4C4C54"},
|
||||
};
|
||||
|
||||
std::map<wxColour, wxColour> const & StateColor::GetDarkMap()
|
||||
std::tuple<double, double, double> StateColor::GetLAB(const wxColour& color) {
|
||||
// Convert color to RGB color space
|
||||
double r = color.Red() / 255.0;
|
||||
double g = color.Green() / 255.0;
|
||||
double b = color.Blue() / 255.0;
|
||||
|
||||
// Convert to XYZ color space
|
||||
double x = 0.412453*r + 0.357580*g + 0.180423*b;
|
||||
double y = 0.212671*r + 0.715160*g + 0.072169*b;
|
||||
double z = 0.019334*r + 0.119193*g + 0.950227*b;
|
||||
|
||||
// Normalize XYZ values
|
||||
double x_n = x / 0.950456;
|
||||
double y_n = y / 1.0;
|
||||
double z_n = z / 1.088754;
|
||||
|
||||
// Convert to LAB color space
|
||||
double epsilon = 0.008856;
|
||||
double kappa = 903.3;
|
||||
double fx = (x_n > epsilon) ? cbrt(x_n) : (kappa*x_n + 16.0) / 116.0;
|
||||
double fy = (y_n > epsilon) ? cbrt(y_n) : (kappa*y_n + 16.0) / 116.0;
|
||||
double fz = (z_n > epsilon) ? cbrt(z_n) : (kappa*z_n + 16.0) / 116.0;
|
||||
|
||||
double l = 116.0 * fy - 16.0;
|
||||
double a = 500.0 * (fx - fy);
|
||||
double b_lab = 200.0 * (fy - fz);
|
||||
|
||||
return std::tuple<double, double, double>(l, a, b_lab);
|
||||
}
|
||||
|
||||
double StateColor::LAB_Delta_E(const wxColour& color1, const wxColour& color2) {
|
||||
auto [l1, a1, b1] = GetLAB(color1);
|
||||
auto [l2, a2, b2] = GetLAB(color2);
|
||||
return sqrt((l1 - l2) * (l1 - l2) + (a1 - a2) * (a1 - a2) + (b1 - b2) * (b1 - b2));
|
||||
}
|
||||
|
||||
double StateColor::GetColorDifference(const wxColour& color1, const wxColour& color2) {
|
||||
return LAB_Delta_E(color1, color2);
|
||||
}
|
||||
|
||||
double StateColor::GetLightness(const wxColour& color) {
|
||||
auto [l, a, b_lab] = GetLAB(color);
|
||||
return l;
|
||||
}
|
||||
|
||||
// Function to lighten or darken a wxColour using LAB color space
|
||||
wxColour StateColor::SetLightness(const wxColour& color, double lightness) {
|
||||
auto [l, a, b_lab] = GetLAB(color);
|
||||
|
||||
// Clamp lightness value
|
||||
l = std::max(0.0, std::min(100.0, lightness));
|
||||
|
||||
// Convert back to XYZ color space
|
||||
double fy_3 = (l + 16.0) / 116.0;
|
||||
double fx_3 = a / 500.0 + fy_3;
|
||||
double fz_3 = fy_3 - b_lab / 200.0;
|
||||
|
||||
double epsilon = 0.008856;
|
||||
double kappa = 903.3;
|
||||
double x_3 = (fx_3 > epsilon) ? fx_3 * fx_3 * fx_3 : (116.0 * fx_3 - 16.0) / kappa;
|
||||
double y_3 = (l > kappa*epsilon) ? fy_3 * fy_3 * fy_3 : l / kappa;
|
||||
double z_3 = (fz_3 > epsilon) ? fz_3 * fz_3 * fz_3 : (116.0 * fz_3 - 16.0) / kappa;
|
||||
|
||||
// Denormalize XYZ values
|
||||
double x = x_3 * 0.950456;
|
||||
double y = y_3 * 1.0;
|
||||
double z = z_3 * 1.088754;
|
||||
|
||||
// Convert XYZ to RGB
|
||||
double r_new = 3.240479*x - 1.537150*y - 0.498535*z;
|
||||
double g_new = -0.969256*x + 1.875992*y + 0.041556*z;
|
||||
double b_new = 0.055648*x - 0.204043*y + 1.057311*z;
|
||||
|
||||
// Clamp RGB values
|
||||
r_new = std::max(0.0, std::min(1.0, r_new));
|
||||
g_new = std::max(0.0, std::min(1.0, g_new));
|
||||
b_new = std::max(0.0, std::min(1.0, b_new));
|
||||
|
||||
// Convert back to wxColour
|
||||
int r_int = static_cast<int>(r_new * 255);
|
||||
int g_int = static_cast<int>(g_new * 255);
|
||||
int b_int = static_cast<int>(b_new * 255);
|
||||
|
||||
return wxColour(r_int, g_int, b_int);
|
||||
}
|
||||
|
||||
wxColour StateColor::LightenDarkenColor(const wxColour& color, int amount) {
|
||||
auto [l, a, b_lab] = GetLAB(color);
|
||||
|
||||
// Modify lightness
|
||||
l += amount;
|
||||
|
||||
// Clamp lightness value
|
||||
l = std::max(0.0, std::min(100.0, l));
|
||||
|
||||
// Convert back to XYZ color space
|
||||
double fy_3 = (l + 16.0) / 116.0;
|
||||
double fx_3 = a / 500.0 + fy_3;
|
||||
double fz_3 = fy_3 - b_lab / 200.0;
|
||||
|
||||
double epsilon = 0.008856;
|
||||
double kappa = 903.3;
|
||||
double x_3 = (fx_3 > epsilon) ? fx_3 * fx_3 * fx_3 : (116.0 * fx_3 - 16.0) / kappa;
|
||||
double y_3 = (l > kappa*epsilon) ? fy_3 * fy_3 * fy_3 : l / kappa;
|
||||
double z_3 = (fz_3 > epsilon) ? fz_3 * fz_3 * fz_3 : (116.0 * fz_3 - 16.0) / kappa;
|
||||
|
||||
// Denormalize XYZ values
|
||||
double x = x_3 * 0.950456;
|
||||
double y = y_3 * 1.0;
|
||||
double z = z_3 * 1.088754;
|
||||
|
||||
// Convert XYZ to RGB
|
||||
double r_new = 3.240479*x - 1.537150*y - 0.498535*z;
|
||||
double g_new = -0.969256*x + 1.875992*y + 0.041556*z;
|
||||
double b_new = 0.055648*x - 0.204043*y + 1.057311*z;
|
||||
|
||||
// Clamp RGB values
|
||||
r_new = std::max(0.0, std::min(1.0, r_new));
|
||||
g_new = std::max(0.0, std::min(1.0, g_new));
|
||||
b_new = std::max(0.0, std::min(1.0, b_new));
|
||||
|
||||
// Convert back to wxColour
|
||||
int r_int = static_cast<int>(r_new * 255);
|
||||
int g_int = static_cast<int>(g_new * 255);
|
||||
int b_int = static_cast<int>(b_new * 255);
|
||||
|
||||
return wxColour(r_int, g_int, b_int);
|
||||
}
|
||||
|
||||
std::map<wxColour, wxColour> const & StateColor::GetDarkMap()
|
||||
{
|
||||
return gDarkColors;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ class StateColor
|
|||
{
|
||||
public:
|
||||
enum State {
|
||||
Normal = 0,
|
||||
Normal = 0,
|
||||
Enabled = 1,
|
||||
Checked = 2,
|
||||
Focused = 4,
|
||||
|
@ -23,6 +23,13 @@ public:
|
|||
};
|
||||
|
||||
public:
|
||||
static std::tuple<double, double, double> GetLAB(const wxColour& color);
|
||||
static double GetLightness(const wxColour& color);
|
||||
static wxColour SetLightness(const wxColour& color, double lightness);
|
||||
static wxColour LightenDarkenColor(const wxColour& color, int amount);
|
||||
static double GetColorDifference(const wxColour& c1, const wxColour& c2);
|
||||
static double LAB_Delta_E(const wxColour& c1, const wxColour& c2);
|
||||
|
||||
static void SetDarkMode(bool dark);
|
||||
|
||||
static std::map<wxColour, wxColour> const & GetDarkMap();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue