Avoid changing checkbox background in wxGrid under non-MSW

Doing this makes the checkbox unusable with the default GTK 3 theme as
the default grid background colour (white) is the same as the colour of
the check mark -- so changing the checkbox background to it makes it
invisible.

Work around this by adding a new SetTransparentPartColour() method that
can be used by wxGrid (and, in the future, user code if we decide that
this is really the best solution to this problem that we can provide) to
make the checkbox blend in with its background without actually changing
its appearance.
This commit is contained in:
Vadim Zeitlin
2019-11-28 02:06:45 +01:00
parent e2bb8b05bf
commit 2eb312b5f9
3 changed files with 34 additions and 1 deletions

View File

@@ -99,6 +99,11 @@ public:
virtual bool HasTransparentBackground() wxOVERRIDE { return true; } virtual bool HasTransparentBackground() wxOVERRIDE { return true; }
// This semi-private function is currently used to allow wxMSW checkbox to
// blend in with its parent background colour without changing the
// background colour of the checkbox itself under the other platforms.
virtual void SetTransparentPartColour(const wxColour& WXUNUSED(col)) { }
// wxCheckBox-specific processing after processing the update event // wxCheckBox-specific processing after processing the update event
virtual void DoUpdateWindowUI(wxUpdateUIEvent& event) wxOVERRIDE virtual void DoUpdateWindowUI(wxUpdateUIEvent& event) wxOVERRIDE
{ {

View File

@@ -45,6 +45,11 @@ public:
// override some base class virtuals // override some base class virtuals
virtual void SetLabel(const wxString& label) wxOVERRIDE; virtual void SetLabel(const wxString& label) wxOVERRIDE;
virtual void SetTransparentPartColour(const wxColour& col) wxOVERRIDE
{
SetBackgroundColour(col);
}
virtual bool MSWCommand(WXUINT param, WXWORD id) wxOVERRIDE; virtual bool MSWCommand(WXUINT param, WXWORD id) wxOVERRIDE;
virtual void Command(wxCommandEvent& event) wxOVERRIDE; virtual void Command(wxCommandEvent& event) wxOVERRIDE;

View File

@@ -1240,10 +1240,33 @@ void wxGridCellBoolEditor::Show(bool show, wxGridCellAttr *attr)
{ {
m_control->Show(show); m_control->Show(show);
// Under MSW we need to set the checkbox background colour to the same
// colour as is used by the cell in order for it to blend in, but using
// just SetBackgroundColour() would be wrong as this would actually change
// the background of the checkbox with e.g. GTK 3, making it unusable in
// any theme where the check mark colour is the same, or close to, our
// background colour -- which happens to be the case for the default GTK 3
// theme, making this a rather serious problem.
//
// One possible workaround would be to set the foreground colour too, but
// wxRendererNative methods used in wxGridCellBoolRenderer don't currently
// take the colours into account, so this would mean that starting to edit
// a boolean field would change its colours, which would be jarring (and
// especially so as we currently set custom colours for all cells, not just
// those that really need them).
//
// A more portable solution could be to create a parent window using the
// background colour if it's different from the default and reparent the
// checkbox under it, so that the parent window colour showed through the
// transparent parts of the checkbox, but this would be more complicated
// for no real gain in practice.
//
// So, finally, just use the bespoke function that will change the
// background under MSW, but doesn't do anything elsewhere.
if ( show ) if ( show )
{ {
wxColour colBg = attr ? attr->GetBackgroundColour() : *wxLIGHT_GREY; wxColour colBg = attr ? attr->GetBackgroundColour() : *wxLIGHT_GREY;
CBox()->SetBackgroundColour(colBg); CBox()->SetTransparentPartColour(colBg);
} }
} }