mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-08-17 08:53:06 +08:00
Merge branch 'ribbon-colours'
Fix white pressed-button text becoming illegible in dark ribbon themes. See #26741.
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/private/colour.h
|
||||
// Purpose: Private colour-related helper functions.
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2026-07-29 (extracted src/aui/tabart.cpp)
|
||||
// Copyright: (c) 2026 wxWidgets team
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_PRIVATE_COLOUR_H_
|
||||
#define _WX_PRIVATE_COLOUR_H_
|
||||
|
||||
#include "wx/colour.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
// Helpers used only in this file itself.
|
||||
namespace wxPrivate
|
||||
{
|
||||
|
||||
inline float wxGetSRGB(float r)
|
||||
{
|
||||
return r <= 0.04045f ? r / 12.92f : std::pow((r + 0.055f) / 1.055f, 2.4f);
|
||||
}
|
||||
|
||||
inline float wxGetRelativeLuminance(const wxColour& c)
|
||||
{
|
||||
// See https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
|
||||
return
|
||||
0.2126f * wxGetSRGB(c.Red() / 255.0f) +
|
||||
0.7152f * wxGetSRGB(c.Green() / 255.0f) +
|
||||
0.0722f * wxGetSRGB(c.Blue() / 255.0f);
|
||||
}
|
||||
|
||||
inline float wxComputeContrast(const wxColour& c1, const wxColour& c2)
|
||||
{
|
||||
// See https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio
|
||||
float L1 = wxGetRelativeLuminance(c1);
|
||||
float L2 = wxGetRelativeLuminance(c2);
|
||||
return L1 > L2 ? (L1 + 0.05f) / (L2 + 0.05f) : (L2 + 0.05f) / (L1 + 0.05f);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// Return the colour if it has sufficient contrast ratio (4.5 recommended)
|
||||
// with the background or return either white or black if it doesn't.
|
||||
// (see https://www.w3.org/TR/WCAG21/#contrast-minimum)
|
||||
inline wxColour
|
||||
wxGetContrastingFgColour(const wxColour& fg, const wxColour& bg)
|
||||
{
|
||||
using namespace wxPrivate;
|
||||
|
||||
// No need to change the colour if it has sufficient contrast.
|
||||
if ( wxComputeContrast(fg, bg) >= 4.5f )
|
||||
return fg;
|
||||
|
||||
// Otherwise pick the colour that provides better contrast.
|
||||
return wxComputeContrast(*wxWHITE, bg) > wxComputeContrast(*wxBLACK, bg)
|
||||
? *wxWHITE
|
||||
: *wxBLACK;
|
||||
}
|
||||
|
||||
// Version of the above modifying the foregorund colour in place.
|
||||
inline void
|
||||
wxEnsureSufficientContrast(wxColour* fg, const wxColour& bg)
|
||||
{
|
||||
*fg = wxGetContrastingFgColour(*fg, bg);
|
||||
}
|
||||
|
||||
#endif // _WX_PRIVATE_COLOUR_H_
|
||||
@@ -644,6 +644,9 @@ protected:
|
||||
void DrawDropdownArrow(wxDC& dc, int x, int y, const wxColour& colour);
|
||||
void DrawGalleryBackgroundCommon(wxDC& dc, wxRibbonGallery* wnd,
|
||||
const wxRect& rect);
|
||||
// Picks the button bar label colour appropriate for the given
|
||||
// wxRIBBON_BUTTONBAR_BUTTON_* state flags.
|
||||
wxColour GetButtonBarLabelColour(long state) const;
|
||||
virtual void DrawGalleryButton(wxDC& dc, wxRect rect,
|
||||
wxRibbonGalleryButtonState state, wxBitmapBundle* bundles, wxWindow* wnd);
|
||||
void DrawButtonBarButtonForeground(
|
||||
@@ -674,6 +677,7 @@ protected:
|
||||
|
||||
wxColour m_button_bar_label_colour;
|
||||
wxColour m_button_bar_label_disabled_colour;
|
||||
wxColour m_button_bar_active_label_colour;
|
||||
wxColour m_tab_label_colour;
|
||||
wxColour m_tab_active_label_colour;
|
||||
wxColour m_tab_hover_label_colour;
|
||||
|
||||
+1
-23
@@ -48,8 +48,7 @@
|
||||
#endif
|
||||
|
||||
#include "wx/private/aui.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "wx/private/colour.h"
|
||||
|
||||
wxColor wxAuiLightContrastColour(const wxColour& c)
|
||||
{
|
||||
@@ -63,27 +62,6 @@ wxColor wxAuiLightContrastColour(const wxColour& c)
|
||||
return c.ChangeLightness(amount);
|
||||
}
|
||||
|
||||
inline float wxAuiGetSRGB(float r) {
|
||||
return r <= 0.03928f ? r / 12.92f : std::pow((r + 0.055f) / 1.055f, 2.4f);
|
||||
}
|
||||
|
||||
float wxAuiGetRelativeLuminance(const wxColour& c)
|
||||
{
|
||||
// based on https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
|
||||
return
|
||||
0.2126f * wxAuiGetSRGB(c.Red() / 255.0f) +
|
||||
0.7152f * wxAuiGetSRGB(c.Green() / 255.0f) +
|
||||
0.0722f * wxAuiGetSRGB(c.Blue() / 255.0f);
|
||||
}
|
||||
|
||||
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.05f) / (L2 + 0.05f) : (L2 + 0.05f) / (L1 + 0.05f);
|
||||
}
|
||||
|
||||
#ifdef wxHAS_SVG
|
||||
wxBitmapBundle wxAuiCreateBitmap(const char* svgData, int w, int h,
|
||||
const wxColour& color)
|
||||
|
||||
+3
-19
@@ -36,31 +36,15 @@
|
||||
#endif
|
||||
|
||||
#include "wx/private/aui.h"
|
||||
#include "wx/private/colour.h"
|
||||
|
||||
// -- GUI helper classes and functions --
|
||||
|
||||
// these functions live in dockart.cpp -- they'll eventually
|
||||
// be moved to a new utility cpp file
|
||||
|
||||
float wxAuiGetColourContrast(const wxColour& c1, const wxColour& c2);
|
||||
|
||||
wxString wxAuiChopText(wxDC& dc, const wxString& text, int max_size);
|
||||
|
||||
// Check if the given colour has sufficient contrast ratio (4.5 recommended)
|
||||
// with the background and replace it with either white or black if it doesn't.
|
||||
// (based on https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast7.html)
|
||||
static void
|
||||
wxAuiEnsureSufficientContrast(wxColour* fg, const wxColour& bg)
|
||||
{
|
||||
// No need to change the colour if it has sufficient contrast.
|
||||
if ( wxAuiGetColourContrast(*fg, bg) >= 4.5f )
|
||||
return;
|
||||
|
||||
// Otherwise pick the colour that provides better contrast.
|
||||
*fg = wxAuiGetColourContrast(*wxWHITE, bg)
|
||||
> wxAuiGetColourContrast(*wxBLACK, bg) ? *wxWHITE : *wxBLACK;
|
||||
}
|
||||
|
||||
// Create a "disabled" version of the given colour by adjusting its lightness
|
||||
// in the direction depending on the theme.
|
||||
static wxColour wxAuiDimColour(wxColour colour, int delta = 30)
|
||||
@@ -1263,7 +1247,7 @@ int wxAuiGenericTabArt::DrawPageTab(
|
||||
// draw tab text
|
||||
wxColor font_color = wxSystemSettings::GetColour(
|
||||
page.active ? wxSYS_COLOUR_CAPTIONTEXT : wxSYS_COLOUR_INACTIVECAPTIONTEXT);
|
||||
wxAuiEnsureSufficientContrast(&font_color, back_color);
|
||||
wxEnsureSufficientContrast(&font_color, back_color);
|
||||
dc.SetTextForeground(font_color);
|
||||
dc.DrawText(draw_text,
|
||||
text_offset,
|
||||
@@ -1617,7 +1601,7 @@ void wxAuiSimpleTabArt::DrawTab(wxDC& dc,
|
||||
wxColor back_color = dc.GetBrush().GetColour();
|
||||
wxColor font_color = wxSystemSettings::GetColour(
|
||||
page.active ? wxSYS_COLOUR_CAPTIONTEXT : wxSYS_COLOUR_INACTIVECAPTIONTEXT);
|
||||
wxAuiEnsureSufficientContrast(&font_color, back_color);
|
||||
wxEnsureSufficientContrast(&font_color, back_color);
|
||||
dc.SetTextForeground(font_color);
|
||||
|
||||
const auto textY = tab_y + (tab_height - texty) / 2 + 1;
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "wx/osx/private.h"
|
||||
#endif
|
||||
|
||||
#include "wx/private/colour.h"
|
||||
|
||||
wxRibbonAUIArtProvider::wxRibbonAUIArtProvider()
|
||||
: wxRibbonMSWArtProvider(false)
|
||||
{
|
||||
@@ -287,6 +289,8 @@ void wxRibbonAUIArtProvider::SetColourScheme(
|
||||
m_button_bar_hover_background_brush = LikeSecondary(1.7f);
|
||||
m_button_bar_active_background_brush = LikeSecondary(1.4f);
|
||||
m_button_bar_label_colour = m_tab_label_colour;
|
||||
m_button_bar_active_label_colour = wxGetContrastingFgColour(
|
||||
m_button_bar_label_colour, m_button_bar_active_background_brush.GetColour());
|
||||
#ifdef __WXOSX__
|
||||
m_button_bar_label_disabled_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_INACTIVECAPTIONTEXT);
|
||||
#else
|
||||
@@ -1145,9 +1149,7 @@ void wxRibbonAUIArtProvider::DrawButtonBarButton(
|
||||
}
|
||||
|
||||
dc.SetFont(m_button_bar_label_font);
|
||||
dc.SetTextForeground(state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED
|
||||
? m_button_bar_label_disabled_colour
|
||||
: m_button_bar_label_colour);
|
||||
dc.SetTextForeground(GetButtonBarLabelColour(state));
|
||||
DrawButtonBarButtonForeground(dc, rect, kind, state, label, bitmap_large,
|
||||
bitmap_small);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
|
||||
#if wxUSE_RIBBON
|
||||
|
||||
#include "wx/ribbon/art.h"
|
||||
|
||||
+20
-7
@@ -26,6 +26,8 @@
|
||||
#include "wx/msw/private.h"
|
||||
#endif
|
||||
|
||||
#include "wx/private/colour.h"
|
||||
|
||||
static const char* const gallery_up_xpm[] = {
|
||||
"5 5 2 1",
|
||||
" c None",
|
||||
@@ -293,6 +295,12 @@ void wxRibbonMSWArtProvider::SetColourScheme(
|
||||
m_button_bar_active_background_colour = LikeSecondary(-9.9f, 0.14f, -0.14f);
|
||||
m_button_bar_active_background_gradient_colour = LikeSecondary(-8.7f, 0.17f, -0.03f);
|
||||
|
||||
// The active/pressed background can end up much lighter (or darker)
|
||||
// than the normal button label colour was chosen for, so pick a label
|
||||
// colour that stays legible against it specifically.
|
||||
m_button_bar_active_label_colour = wxGetContrastingFgColour(
|
||||
m_button_bar_label_colour, m_button_bar_active_background_colour);
|
||||
|
||||
m_toolbar_border_pen = LikePrimary(1.4f, -0.21f, -0.16f);
|
||||
SetColour(wxRIBBON_ART_TOOLBAR_FACE_COLOUR, LikePrimary(1.4f, -0.17f, -0.22f));
|
||||
m_tool_background_top_colour = LikePrimary(-1.9f, -0.07f, 0.06f);
|
||||
@@ -366,6 +374,7 @@ void wxRibbonMSWArtProvider::CloneTo(wxRibbonMSWArtProvider* copy) const
|
||||
|
||||
copy->m_button_bar_label_colour = m_button_bar_label_colour;
|
||||
copy->m_button_bar_label_disabled_colour = m_button_bar_label_disabled_colour;
|
||||
copy->m_button_bar_active_label_colour = m_button_bar_active_label_colour;
|
||||
copy->m_tab_label_colour = m_tab_label_colour;
|
||||
copy->m_tab_active_label_colour = m_tab_active_label_colour;
|
||||
copy->m_tab_hover_label_colour = m_tab_hover_label_colour;
|
||||
@@ -2305,6 +2314,15 @@ void wxRibbonMSWArtProvider::DrawPartialPageBackground(
|
||||
dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
|
||||
wxColour wxRibbonMSWArtProvider::GetButtonBarLabelColour(long state) const
|
||||
{
|
||||
if(state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED)
|
||||
return m_button_bar_label_disabled_colour;
|
||||
if(state & wxRIBBON_BUTTONBAR_BUTTON_ACTIVE_MASK)
|
||||
return m_button_bar_active_label_colour;
|
||||
return m_button_bar_label_colour;
|
||||
}
|
||||
|
||||
void wxRibbonMSWArtProvider::DrawButtonBarButton(
|
||||
wxDC& dc,
|
||||
wxWindow* WXUNUSED(wnd),
|
||||
@@ -2425,9 +2443,7 @@ void wxRibbonMSWArtProvider::DrawButtonBarButton(
|
||||
}
|
||||
|
||||
dc.SetFont(m_button_bar_label_font);
|
||||
dc.SetTextForeground(state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED
|
||||
? m_button_bar_label_disabled_colour
|
||||
: m_button_bar_label_colour);
|
||||
dc.SetTextForeground(GetButtonBarLabelColour(state));
|
||||
DrawButtonBarButtonForeground(dc, rect, kind, state, label, bitmap_large,
|
||||
bitmap_small);
|
||||
}
|
||||
@@ -2441,10 +2457,7 @@ void wxRibbonMSWArtProvider::DrawButtonBarButtonForeground(
|
||||
const wxBitmap& bitmap_large,
|
||||
const wxBitmap& bitmap_small)
|
||||
{
|
||||
const wxColour
|
||||
arrowColour(state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED
|
||||
? m_button_bar_label_disabled_colour
|
||||
: m_button_bar_label_colour);
|
||||
const wxColour arrowColour(GetButtonBarLabelColour(state));
|
||||
|
||||
switch(state & wxRIBBON_BUTTONBAR_BUTTON_SIZE_MASK)
|
||||
{
|
||||
|
||||
@@ -782,9 +782,7 @@ void wxRibbonMSWFlatArtProvider::DrawButtonBarButton(
|
||||
}
|
||||
|
||||
dc.SetFont(m_button_bar_label_font);
|
||||
dc.SetTextForeground(state & wxRIBBON_BUTTONBAR_BUTTON_DISABLED
|
||||
? m_button_bar_label_disabled_colour
|
||||
: m_button_bar_label_colour);
|
||||
dc.SetTextForeground(GetButtonBarLabelColour(state));
|
||||
DrawButtonBarButtonForeground(dc, rect, kind, state, label, bitmap_large,
|
||||
bitmap_small);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user