Merge branch 'dark-mode-collapse-button'
Improve collapse button appearance in dark mode. See #23098.
This commit is contained in:
commit
0016bdc308
3 changed files with 92 additions and 30 deletions
|
|
@ -39,7 +39,12 @@ wxColour GetColour(wxSystemColour index);
|
|||
// Return the background brush to be used by default in dark mode.
|
||||
HBRUSH GetBackgroundBrush();
|
||||
|
||||
// If dark mode is active, paint the given window using inverted colours.
|
||||
// Invert the colours of the given bitmap trying to keep it readable.
|
||||
wxBitmap InvertBitmap(const wxBitmap& bmp);
|
||||
|
||||
// If dark mode is active, paint the given window using inverted colours by
|
||||
// drawing it normally and then applying InvertBitmap() to it.
|
||||
//
|
||||
// Otherwise just return false without doing anything.
|
||||
//
|
||||
// This can only be called from WM_PAINT handler for a native control and
|
||||
|
|
|
|||
|
|
@ -353,6 +353,35 @@ HBRUSH GetBackgroundBrush()
|
|||
return brush ? GetHbrushOf(*brush) : 0;
|
||||
}
|
||||
|
||||
wxBitmap InvertBitmap(const wxBitmap& bmp)
|
||||
{
|
||||
#if wxUSE_IMAGE
|
||||
wxImage image = bmp.ConvertToImage();
|
||||
|
||||
unsigned char *data = image.GetData();
|
||||
const int len = image.GetWidth()*image.GetHeight();
|
||||
for ( int i = 0; i < len; ++i, data += 3 )
|
||||
{
|
||||
wxImage::RGBValue rgb(data[0], data[1], data[2]);
|
||||
wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
|
||||
|
||||
// There is no really good way to convert normal colours to dark mode,
|
||||
// but try to do a bit better than just inverting the value because
|
||||
// this results in colours which are much too dark.
|
||||
hsv.value = sqrt(1.0 - hsv.value*hsv.value);
|
||||
|
||||
rgb = wxImage::HSVtoRGB(hsv);
|
||||
data[0] = rgb.red;
|
||||
data[1] = rgb.green;
|
||||
data[2] = rgb.blue;
|
||||
}
|
||||
|
||||
return wxBitmap(image);
|
||||
#else // !wxUSE_IMAGE
|
||||
return wxBitmap();
|
||||
#endif // wxUSE_IMAGE/!wxUSE_IMAGE
|
||||
}
|
||||
|
||||
bool PaintIfNecessary(HWND hwnd, WXWNDPROC defWndProc)
|
||||
{
|
||||
#if wxUSE_IMAGE
|
||||
|
|
@ -378,28 +407,9 @@ bool PaintIfNecessary(HWND hwnd, WXWNDPROC defWndProc)
|
|||
::DefWindowProc(hwnd, WM_PAINT, wparam, 0);
|
||||
}
|
||||
|
||||
wxImage image = bmp.ConvertToImage();
|
||||
|
||||
unsigned char *data = image.GetData();
|
||||
for ( int i = 0; i < size.x*size.y; ++i, data += 3 )
|
||||
{
|
||||
wxImage::RGBValue rgb(data[0], data[1], data[2]);
|
||||
wxImage::HSVValue hsv = wxImage::RGBtoHSV(rgb);
|
||||
|
||||
// There is no really good way to convert normal colours to dark mode,
|
||||
// but try to do a bit better than just inverting the value because
|
||||
// this results in colours which are much too dark.
|
||||
hsv.value = sqrt(1.0 - hsv.value*hsv.value);
|
||||
|
||||
rgb = wxImage::HSVtoRGB(hsv);
|
||||
data[0] = rgb.red;
|
||||
data[1] = rgb.green;
|
||||
data[2] = rgb.blue;
|
||||
}
|
||||
|
||||
PAINTSTRUCT ps;
|
||||
wxDCTemp dc(::BeginPaint(hwnd, &ps), size);
|
||||
dc.DrawBitmap(wxBitmap(image), 0, 0);
|
||||
dc.DrawBitmap(InvertBitmap(bmp), 0, 0);
|
||||
::EndPaint(hwnd, &ps);
|
||||
|
||||
return true;
|
||||
|
|
@ -649,6 +659,11 @@ HBRUSH GetBackgroundBrush()
|
|||
return 0;
|
||||
}
|
||||
|
||||
wxBitmap InvertBitmap(const wxBitmap& WXUNUSED(bmp))
|
||||
{
|
||||
return wxBitmap();
|
||||
}
|
||||
|
||||
bool PaintIfNecessary(HWND WXUNUSED(hwnd), WXWNDPROC WXUNUSED(defWndProc))
|
||||
{
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "wx/window.h"
|
||||
#include "wx/control.h" // for wxControl::Ellipsize()
|
||||
#include "wx/dc.h"
|
||||
#include "wx/dcmemory.h"
|
||||
#include "wx/settings.h"
|
||||
#endif //WX_PRECOMP
|
||||
|
||||
|
|
@ -38,6 +39,8 @@
|
|||
#include "wx/msw/wrapcctl.h"
|
||||
#include "wx/dynlib.h"
|
||||
|
||||
#include "wx/msw/private/darkmode.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// methods common to wxRendererMSW and wxRendererXP
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
@ -927,11 +930,8 @@ wxSize wxRendererXP::GetExpanderSize(wxWindow* win)
|
|||
return m_rendererNative.GetExpanderSize(win);
|
||||
}
|
||||
|
||||
void
|
||||
wxRendererXP::DrawCollapseButton(wxWindow *win,
|
||||
wxDC& dc,
|
||||
const wxRect& rect,
|
||||
int flags)
|
||||
static bool
|
||||
DoDrawCollapseButton(wxWindow* win, HDC hdc, RECT r, int flags)
|
||||
{
|
||||
wxUxThemeHandle hTheme(win, L"TASKDIALOG");
|
||||
|
||||
|
|
@ -948,20 +948,62 @@ wxRendererXP::DrawCollapseButton(wxWindow *win,
|
|||
if ( flags & wxCONTROL_EXPANDED )
|
||||
state += 3;
|
||||
|
||||
RECT r = ConvertToRECT(dc, rect);
|
||||
|
||||
::DrawThemeBackground
|
||||
(
|
||||
hTheme,
|
||||
GetHdcOf(dc.GetTempHDC()),
|
||||
hdc,
|
||||
TDLG_EXPANDOBUTTON,
|
||||
state,
|
||||
&r,
|
||||
nullptr
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
wxRendererXP::DrawCollapseButton(wxWindow *win,
|
||||
wxDC& dc,
|
||||
const wxRect& rect,
|
||||
int flags)
|
||||
{
|
||||
RECT r = ConvertToRECT(dc, rect);
|
||||
|
||||
// Default theme draws the button on light background which looks very out
|
||||
// of place when using dark mode, so invert it if necessary and fall back
|
||||
// on the generic version if this fails.
|
||||
//
|
||||
// Ideal would be to find the theme drawing the version appropriate for the
|
||||
// dark mode, but it's unknown if there is one providing this.
|
||||
if ( wxMSWDarkMode::IsActive() )
|
||||
{
|
||||
wxBitmap bmp(rect.GetSize());
|
||||
|
||||
bool ok;
|
||||
{
|
||||
wxMemoryDC mdc(bmp);
|
||||
ok = DoDrawCollapseButton(win, GetHdcOf(mdc), r, flags);
|
||||
}
|
||||
|
||||
if ( ok )
|
||||
{
|
||||
wxBitmap bmpInv = wxMSWDarkMode::InvertBitmap(bmp);
|
||||
if ( bmpInv.IsOk() )
|
||||
{
|
||||
dc.DrawBitmap(bmpInv, rect.GetPosition());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_rendererNative.DrawCollapseButton(win, dc, rect, flags);
|
||||
{
|
||||
if ( DoDrawCollapseButton(win, GetHdcOf(dc.GetTempHDC()), r, flags) )
|
||||
return;
|
||||
}
|
||||
|
||||
m_rendererNative.DrawCollapseButton(win, dc, rect, flags);
|
||||
}
|
||||
|
||||
wxSize wxRendererXP::GetCollapseButtonSize(wxWindow *win, wxDC& dc)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue