Allow customizing menu bar menus colours in MSW dark mode

This allows to customize the hard-coded colours used for drawing the
menu bar too.
This commit is contained in:
Vadim Zeitlin 2023-02-19 23:20:19 +00:00
parent d051ff0215
commit 76fffafcd0
3 changed files with 82 additions and 12 deletions

View file

@ -12,6 +12,15 @@
#include "wx/settings.h"
// Constants used with wxDarkModeSettings::GetMenuColour().
enum class wxMenuColour
{
StandardFg,
StandardBg,
DisabledFg,
HotBg
};
// ----------------------------------------------------------------------------
// wxDarkModeSettings: allows to customize some of dark mode settings
// ----------------------------------------------------------------------------
@ -25,6 +34,10 @@ public:
// Get the colour to use for the given system colour when dark mode is on.
virtual wxColour GetColour(wxSystemColour index);
// Menu items don't use any of the standard colours, but are defined by
// this function.
virtual wxColour GetMenuColour(wxMenuColour which);
// Get the pen to use for drawing wxStaticBox border in dark mode.
//
// Returning an invalid pen indicates that the default border drawn by the

View file

@ -7,6 +7,26 @@
// Licence: wxWindows Licence
/////////////////////////////////////////////////////////////////////////////
/**
Constants used with wxDarkModeSettings::GetMenuColour().
@since 3.3.0
*/
enum class wxMenuColour
{
/// Text colour used for the normal items in dark mode.
StandardFg,
/// Standard menu background colour.
StandardBg,
/// Foreground colour for the disabled items.
DisabledFg,
/// Background colour used for the item over which mouse is hovering.
HotBg
};
/**
Allows to customize some of the settings used in MSW dark mode.
@ -57,9 +77,26 @@ public:
used in dark mode. As the rest of dark mode support, their exact values
are not documented and are subject to change in the future Windows or
wxWidgets versions.
@see GetMenuColour()
*/
virtual wxColour GetColour(wxSystemColour index);
/**
Get the colour to use for the menu bar in the given state.
Currently the colours used by the menus in the menu bar in dark mode
don't correspond to any of wxSystemColour values and this separate
function is used for customizing them instead of GetColour().
Note that the colours returned by this function only affect the top
level menus, the colours of the menu items inside them can be
customized in the usual way using wxOwnerDrawn::SetTextColour().
The returned colour must be valid.
*/
virtual wxColour GetMenuColour(wxMenuColour which);
/**
Get the pen to use for drawing wxStaticBox border in dark mode.

View file

@ -330,6 +330,27 @@ wxColour wxDarkModeSettings::GetColour(wxSystemColour index)
return wxColour();
}
wxColour wxDarkModeSettings::GetMenuColour(wxMenuColour which)
{
switch ( which )
{
case wxMenuColour::StandardFg:
return wxColour(0xffffff);
case wxMenuColour::StandardBg:
return wxColour(0x6d6d6d);
case wxMenuColour::DisabledFg:
return wxColour(0x414141);
case wxMenuColour::HotBg:
return wxColour(0x2b2b2b);
}
wxFAIL_MSG( "unreachable" );
return wxColour();
}
wxPen wxDarkModeSettings::GetBorderPen()
{
// Use a darker pen than the default white one by default. There doesn't
@ -510,14 +531,15 @@ struct MenuBarDrawMenuItem
MenuBarMenuItem mbmi;
};
constexpr COLORREF COL_STANDARD = 0xffffff;
constexpr COLORREF COL_DISABLED = 0x6d6d6d;
constexpr COLORREF COL_MENU_HOT = 0x414141;
wxColour GetMenuColour(wxMenuColour which)
{
return wxDarkModeModule::GetSettings().GetMenuColour(which);
}
HBRUSH GetMenuBrush()
HBRUSH GetMenuBrush(wxMenuColour which = wxMenuColour::StandardBg)
{
wxBrush* const brush =
wxTheBrushList->FindOrCreateBrush(GetColour(wxSYS_COLOUR_MENU));
wxTheBrushList->FindOrCreateBrush(GetMenuColour(which));
return brush ? GetHbrushOf(*brush) : 0;
}
@ -621,9 +643,11 @@ HandleMenuMessage(WXLRESULT* result,
HBRUSH hbr = 0;
int partState = 0;
wxMenuColour colText = wxMenuColour::StandardFg;
if ( itemState & ODS_INACTIVE )
{
partState = MBI_DISABLED;
colText = wxMenuColour::DisabledFg;
}
else if ( (itemState & ODS_GRAYED) && (itemState & ODS_HOTLIGHT) )
{
@ -632,15 +656,13 @@ HandleMenuMessage(WXLRESULT* result,
else if ( itemState & ODS_GRAYED )
{
partState = MBI_DISABLED;
colText = wxMenuColour::DisabledFg;
}
else if ( itemState & (ODS_HOTLIGHT | ODS_SELECTED) )
{
partState = MBI_HOT;
auto* const
brush = wxTheBrushList->FindOrCreateBrush(COL_MENU_HOT);
if ( brush )
hbr = GetHbrushOf(*brush);
hbr = GetMenuBrush(wxMenuColour::HotBg);
}
else
{
@ -660,9 +682,7 @@ HandleMenuMessage(WXLRESULT* result,
DTTOPTS textOpts;
textOpts.dwSize = sizeof(textOpts);
textOpts.dwFlags = DTT_TEXTCOLOR;
textOpts.crText = itemState & (ODS_INACTIVE | ODS_GRAYED)
? COL_DISABLED
: COL_STANDARD;
textOpts.crText = wxColourToRGB(GetMenuColour(colText));
DWORD drawTextFlags = DT_CENTER | DT_SINGLELINE | DT_VCENTER;
if ( itemState & ODS_NOACCEL)