Make wxAuiGenericTabArt text readable on dark background

Select the appropriate text colour depending on the background to ensure
that it remains readable even when using themes/modes using dark
background colours -- which wasn't at all the case before.

Closes #18601.
This commit is contained in:
Paul Kulchenko 2019-12-04 19:26:45 +01:00 committed by Vadim Zeitlin
parent 462e7b7732
commit 8cb9272458
2 changed files with 39 additions and 33 deletions

View File

@ -57,14 +57,6 @@
#include <math.h>
// -- wxAuiDefaultDockArt class implementation --
// wxAuiDefaultDockArt is an art provider class which does all of the drawing for
// wxAuiManager. This allows the library caller to customize the dock art
// (probably by deriving from this class), or to completely replace all drawing
// with custom dock art (probably by writing a new stand-alone class derived
// from the wxAuiDockArt base class). The active dock art class can be set via
// wxAuiManager::SetDockArt()
wxColor wxAuiLightContrastColour(const wxColour& c)
{
int amount = 120;
@ -77,6 +69,26 @@ wxColor wxAuiLightContrastColour(const wxColour& c)
return c.ChangeLightness(amount);
}
inline float wxAuiGetSRGB(float r) {
return r <= 0.03928 ? r/12.92 : pow((r+0.055)/1.055, 2.4);
}
float wxAuiGetRelativeLuminance(const wxColour& c)
{
// based on https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
return 0.2126 * wxAuiGetSRGB(c.Red()/255.0)
+ 0.7152 * wxAuiGetSRGB(c.Green()/255.0)
+ 0.0722 * wxAuiGetSRGB(c.Blue()/255.0);
}
float wxAuiGetColourContrast(const wxColour& c1, const wxColour& c2)
{
// based on https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast7.html
float L1 = wxAuiGetRelativeLuminance(c1);
float L2 = wxAuiGetRelativeLuminance(c2);
return L1 > L2 ? (L1 + 0.05) / (L2 + 0.05) : (L2 + 0.05) / (L1 + 0.05);
}
// wxAuiBitmapFromBits() is a utility function that creates a
// masked bitmap from raw bits (XBM format)
wxBitmap wxAuiBitmapFromBits(const unsigned char bits[], int w, int h,
@ -174,6 +186,14 @@ wxString wxAuiChopText(wxDC& dc, const wxString& text, int max_size)
return ret;
}
// -- wxAuiDefaultDockArt class implementation --
// wxAuiDefaultDockArt is an art provider class which does all of the drawing for
// wxAuiManager. This allows the library caller to customize the dock art
// (probably by deriving from this class), or to completely replace all drawing
// with custom dock art (probably by writing a new stand-alone class derived
// from the wxAuiDockArt base class). The active dock art class can be set via
// wxAuiManager::SetDockArt()
wxAuiDefaultDockArt::wxAuiDefaultDockArt()
{
UpdateColoursFromSystem();

View File

@ -74,6 +74,7 @@ wxBitmap wxAuiBitmapFromBits(const unsigned char bits[], int w, int h,
// This function is defined in dockart.cpp.
void wxAuiScaleBitmap(wxBitmap& bmp, double scale);
float wxAuiGetColourContrast(const wxColour& c1, const wxColour& c2);
wxString wxAuiChopText(wxDC& dc, const wxString& text, int max_size);
@ -267,14 +268,6 @@ void wxAuiGenericTabArt::DrawBackground(wxDC& dc,
// draw background
int topLightness = 90;
int bottomLightness = 170;
if ((m_baseColour.Red() < 75)
&& (m_baseColour.Green() < 75)
&& (m_baseColour.Blue() < 75))
{
//dark mode, we cannot go very light
topLightness = 90;
bottomLightness = 110;
}
wxColor top_color = m_baseColour.ChangeLightness(topLightness);
wxColor bottom_color = m_baseColour.ChangeLightness(bottomLightness);
@ -428,7 +421,10 @@ void wxAuiGenericTabArt::DrawTab(wxDC& dc,
int drawn_tab_yoff = border_points[1].y;
int drawn_tab_height = border_points[0].y - border_points[1].y;
bool isdark = (m_baseColour.Red() < 75)
&& (m_baseColour.Green() < 75)
&& (m_baseColour.Blue() < 75);
wxColor back_color = m_baseColour;
if (page.active)
{
// draw active tab
@ -441,13 +437,12 @@ void wxAuiGenericTabArt::DrawTab(wxDC& dc,
// this white helps fill out the gradient at the top of the tab
wxColor gradient = *wxWHITE;
if ((m_baseColour.Red() < 75)
&& (m_baseColour.Green() < 75)
&& (m_baseColour.Blue() < 75))
if (isdark)
{
//dark mode, we go darker
gradient = m_activeColour.ChangeLightness(70);
}
back_color = gradient;
dc.SetPen(wxPen(gradient));
dc.SetBrush(wxBrush(gradient));
@ -488,9 +483,7 @@ void wxAuiGenericTabArt::DrawTab(wxDC& dc,
// -- draw top gradient fill for glossy look
wxColor top_color = m_baseColour;
wxColor bottom_color = top_color.ChangeLightness(160);
if ((m_baseColour.Red() < 75)
&& (m_baseColour.Green() < 75)
&& (m_baseColour.Blue() < 75))
if (isdark)
{
//dark mode, we go darker
top_color = m_activeColour.ChangeLightness(70);
@ -585,16 +578,9 @@ void wxAuiGenericTabArt::DrawTab(wxDC& dc,
tab_width - (text_offset-tab_x) - close_button_width);
// draw tab text
#if defined( __WXMAC__ )
if (page.active)
{
dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_CAPTIONTEXT));
}
else
{
dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_INACTIVECAPTIONTEXT));
}
#endif
wxColor font_color = wxAuiGetColourContrast(*wxWHITE, back_color)
> wxAuiGetColourContrast(*wxBLACK, back_color) ? *wxWHITE : *wxBLACK;
dc.SetTextForeground(font_color);
dc.DrawText(draw_text,
text_offset,
drawn_tab_yoff + (drawn_tab_height)/2 - (texty/2) - 1);