Fix static box and check/radio buttons text colour in dark mode

The labels of these controls were unreadable because they used the same
text colour as in normal, light mode even after enabling dark mode
support for them, so fix this by explicitly setting the default (for
dark mode, i.e. light) text colour for them.

Add a new "setForeground" field to MSWDarkModeSupport struct to allow
doing this easily and in a single place in wxControl code, so that it
could be customized, or even skipped, if these controls support for the
dark mode is improved, in the future.
This commit is contained in:
Vadim Zeitlin 2022-12-14 18:18:13 +00:00
parent 881e21663a
commit 2e45ddc2d2
8 changed files with 47 additions and 0 deletions

View file

@ -62,6 +62,8 @@ public:
protected:
virtual wxSize DoGetBestClientSize() const override;
virtual bool MSWGetDarkModeSupport(MSWDarkModeSupport& support) const override;
virtual void DoSet3StateValue(wxCheckBoxState value) override;
virtual wxCheckBoxState DoGet3StateValue() const override;

View file

@ -134,6 +134,10 @@ protected:
// The theme IDs to use. If neither this field nor the theme name is
// set, no theme is applied to the window.
const wchar_t* themeId = nullptr;
// For some controls we need to set the foreground explicitly, even if
// they have some support for the dark theme.
bool setForeground = false;
};
// Called after creating the control to enable dark mode support if needed.

View file

@ -58,6 +58,8 @@ protected:
virtual wxBorder GetDefaultBorder() const override { return wxBORDER_NONE; }
virtual wxSize DoGetBestSize() const override;
virtual bool MSWGetDarkModeSupport(MSWDarkModeSupport& support) const override;
// Implement wxMSWOwnerDrawnButtonBase methods.
virtual int MSWGetButtonStyle() const override;
virtual void MSWOnButtonResetOwnerDrawn() override;

View file

@ -79,6 +79,8 @@ public:
protected:
virtual wxWindowList GetCompositeWindowParts() const override;
virtual bool MSWGetDarkModeSupport(MSWDarkModeSupport& support) const override;
// return the region with all the windows inside this static box excluded
virtual WXHRGN MSWGetRegionWithoutChildren();

View file

@ -88,6 +88,18 @@ WXDWORD wxCheckBox::MSWGetStyle(long style, WXDWORD *exstyle) const
return msStyle;
}
bool wxCheckBox::MSWGetDarkModeSupport(MSWDarkModeSupport& support) const
{
// Just as radio buttons, check boxes have some dark theme support, but we
// still need to change their foreground manually to make it readable in
// dark mode.
wxCheckBoxBase::MSWGetDarkModeSupport(support);
support.setForeground = true;
return true;
}
// ----------------------------------------------------------------------------
// wxCheckBox geometry
// ----------------------------------------------------------------------------

View file

@ -143,6 +143,9 @@ bool wxControl::MSWCreateControl(const wxChar *classname,
{
wxMSWDarkMode::AllowForWindow(m_hWnd, support.themeName, support.themeId);
if ( support.setForeground )
SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOXTEXT));
if ( const int msgTT = MSWGetToolTipMessage() )
{
const HWND hwndTT = (HWND)::SendMessage(GetHwnd(), msgTT, 0, 0);

View file

@ -75,6 +75,19 @@ bool wxRadioButton::Create(wxWindow *parent,
return true;
}
bool wxRadioButton::MSWGetDarkModeSupport(MSWDarkModeSupport& support) const
{
// Weirdly enough, even though radio buttons support dark theme (they
// notably change the way they draw the focus rectangle if we set it), they
// still use the default black foreground colour in it, making their text
// unreadable, so we need to change it manually.
wxRadioButtonBase::MSWGetDarkModeSupport(support);
support.setForeground = true;
return true;
}
// ----------------------------------------------------------------------------
// wxRadioButton functions
// ----------------------------------------------------------------------------

View file

@ -95,6 +95,15 @@ bool wxStaticBox::Create(wxWindow *parent,
return true;
}
bool wxStaticBox::MSWGetDarkModeSupport(MSWDarkModeSupport& support) const
{
// Static boxes don't seem to have any dark mode support, so just set the
// foreground colour contrasting with the dark background for them.
support.setForeground = true;
return true;
}
bool wxStaticBox::ShouldUseCustomPaint() const
{
// When not using double buffering, we paint the box ourselves by default