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")
|
if (app_config->get("stealth_mode") == "false")
|
||||||
hms_query = new HMSQuery();
|
hms_query = new HMSQuery();
|
||||||
|
|
||||||
m_show_gcode_window = app_config->get_bool("show_gcode_window");
|
m_show_gcode_window = app_config->get_bool("show_gcode_window");
|
||||||
if (m_networking_need_update) {
|
if (m_networking_need_update) {
|
||||||
//updating networking
|
//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_modified = is_dark_mode ? wxColour("#F1754E") : wxColour("#F1754E");
|
||||||
m_color_label_sys = is_dark_mode ? wxColour("#B2B3B5") : wxColour("#363636");
|
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_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_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);
|
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() )
|
/*if (m_is_dark_mode != dark_mode() )
|
||||||
m_is_dark_mode = dark_mode();*/
|
m_is_dark_mode = dark_mode();*/
|
||||||
|
|
||||||
|
|
||||||
if (m_is_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);
|
window->SetBackgroundColour(bg_col);
|
||||||
}
|
}
|
||||||
|
|
||||||
original_col = window->GetForegroundColour();
|
orig_col = window->GetForegroundColour();
|
||||||
auto fg_col = StateColor::darkModeColorFor(original_col);
|
auto fg_col = StateColor::darkModeColorFor(orig_col);
|
||||||
|
auto fg_l = StateColor::GetLightness(fg_col);
|
||||||
|
|
||||||
if (fg_col != original_col) {
|
auto color_difference = StateColor::GetColorDifference(bg_col, fg_col);
|
||||||
window->SetForegroundColour(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 {
|
else {
|
||||||
auto original_col = window->GetBackgroundColour();
|
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);
|
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) {
|
if (msg_dlg.ShowModal() == wxOK) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// request login
|
// request login
|
||||||
|
|
|
@ -1533,7 +1533,6 @@ void UnsavedChangesDialog::update_list()
|
||||||
text_left->SetFont(::Label::Head_13);
|
text_left->SetFont(::Label::Head_13);
|
||||||
text_left->Wrap(-1);
|
text_left->Wrap(-1);
|
||||||
text_left->SetForegroundColour(GREY700);
|
text_left->SetForegroundColour(GREY700);
|
||||||
text_left->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT));
|
|
||||||
|
|
||||||
sizer_left_v->Add(text_left, 0, wxLEFT, 37);
|
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->SetFont(::Label::Body_13);
|
||||||
text_left->Wrap(-1);
|
text_left->Wrap(-1);
|
||||||
text_left->SetForegroundColour(GREY700);
|
text_left->SetForegroundColour(GREY700);
|
||||||
text_left->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_INFOTEXT));
|
|
||||||
|
|
||||||
sizer_left_v->Add(text_left, 0, wxLEFT, 51 );
|
sizer_left_v->Add(text_left, 0, wxLEFT, 51 );
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "StateColor.hpp"
|
#include "StateColor.hpp"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
static bool gDarkMode = false;
|
static bool gDarkMode = false;
|
||||||
|
|
||||||
|
@ -41,7 +42,136 @@ static std::map<wxColour, wxColour> gDarkColors{
|
||||||
//{"#F0F0F0", "#4C4C54"},
|
//{"#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;
|
return gDarkColors;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ class StateColor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum State {
|
enum State {
|
||||||
Normal = 0,
|
Normal = 0,
|
||||||
Enabled = 1,
|
Enabled = 1,
|
||||||
Checked = 2,
|
Checked = 2,
|
||||||
Focused = 4,
|
Focused = 4,
|
||||||
|
@ -23,6 +23,13 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
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 void SetDarkMode(bool dark);
|
||||||
|
|
||||||
static std::map<wxColour, wxColour> const & GetDarkMap();
|
static std::map<wxColour, wxColour> const & GetDarkMap();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue