diff --git a/docs/doxygen/overviews/xrc_format.h b/docs/doxygen/overviews/xrc_format.h
index e15ae5a876..235dcd927d 100644
--- a/docs/doxygen/overviews/xrc_format.h
+++ b/docs/doxygen/overviews/xrc_format.h
@@ -222,7 +222,7 @@ is "." regardless of the locale.
@subsection overview_xrcformat_type_colour Colour
-Colour specification can be either any string colour representation accepted
+A single colour can be either any string colour representation accepted
by wxColour::Set() or any wxSYS_COLOUR_XXX symbolic name accepted by
wxSystemSettings::GetColour(). In particular, the following forms are supported:
@@ -231,11 +231,21 @@ wxSystemSettings::GetColour(). In particular, the following forms are supported:
@li CSS-style "rgb(r,g,b)" and "rgba(r,g,b,a)"
@li wxSYS_COLOUR_XXX symbolic names
+Moreover, a single colour definition in XRC may contain more than one colour,
+separated by `|` (pipe symbol), with the first colour used by default and the
+subsequent colours in specific situations. Currently the only supported
+alternative colour is the colour to be used in dark mode, which must be
+prefixed with "dark:".
+
+It is recommended to provide both light and dark values when not using system
+colour names (that already adapt to the dark mode), as it's rare for the same
+colour to look well in both light and dark mode.
+
Some examples:
@code
red#ff0000
-rgb(255,0,0)
+rgb(192,192,192)|dark:#404040wxSYS_COLOUR_HIGHLIGHT
@endcode
diff --git a/include/wx/xrc/xmlres.h b/include/wx/xrc/xmlres.h
index fac667a5fe..8cc356b9cc 100644
--- a/include/wx/xrc/xmlres.h
+++ b/include/wx/xrc/xmlres.h
@@ -558,8 +558,12 @@ public:
// Gets a float value from the parameter.
float GetFloat(const wxString& param, float defaultv = 0) override;
- // Gets colour in HTML syntax (#RRGGBB).
- wxColour GetColour(const wxString& param, const wxColour& defaultv = wxNullColour) override;
+ // Gets colour from the parameter, returning one of the provided default
+ // values if it's not specified depending on whether we're using light or
+ // dark mode.
+ wxColour GetColour(const wxString& param,
+ const wxColour& defaultLight = wxNullColour,
+ const wxColour& defaultDark = wxNullColour) override;
// Gets the size (may be in dialog units).
wxSize GetSize(const wxString& param = wxT("size"),
diff --git a/include/wx/xrc/xmlreshandler.h b/include/wx/xrc/xmlreshandler.h
index 74c0e087fb..be71ad7af9 100644
--- a/include/wx/xrc/xmlreshandler.h
+++ b/include/wx/xrc/xmlreshandler.h
@@ -76,7 +76,8 @@ public:
virtual long GetLong(const wxString& param, long defaultv = 0) = 0;
virtual float GetFloat(const wxString& param, float defaultv = 0) = 0;
virtual wxColour GetColour(const wxString& param,
- const wxColour& defaultv = wxNullColour) = 0;
+ const wxColour& defaultLight = wxNullColour,
+ const wxColour& defaultDark = wxNullColour) = 0;
virtual wxSize GetSize(const wxString& param = wxT("size"),
wxWindow *windowToUse = nullptr) = 0;
virtual wxPoint GetPosition(const wxString& param = wxT("pos"),
@@ -301,9 +302,10 @@ protected:
return GetImpl()->GetFloat(param, defaultv);
}
wxColour GetColour(const wxString& param,
- const wxColour& defaultv = wxNullColour)
+ const wxColour& defaultLight = wxNullColour,
+ const wxColour& defaultDark = wxNullColour)
{
- return GetImpl()->GetColour(param, defaultv);
+ return GetImpl()->GetColour(param, defaultLight, defaultDark);
}
wxSize GetSize(const wxString& param = wxT("size"),
wxWindow *windowToUse = nullptr)
diff --git a/interface/wx/xrc/xmlres.h b/interface/wx/xrc/xmlres.h
index 2fefb75a4e..ea43e57a48 100644
--- a/interface/wx/xrc/xmlres.h
+++ b/interface/wx/xrc/xmlres.h
@@ -654,10 +654,16 @@ protected:
bool GetBool(const wxString& param, bool defaultv = false);
/**
- Gets colour in HTML syntax (\#RRGGBB).
+ Gets colour from the given parameter.
+
+ If the colour is not specified, returns @a defaultLight or @a
+ defaultDark if the application is using dark mode.
+
+ Parameter @a defaultDark is only available since wxWidgets 3.3.0.
*/
wxColour GetColour(const wxString& param,
- const wxColour& defaultColour = wxNullColour);
+ const wxColour& defaultLight = wxNullColour,
+ const wxColour& defaultDark = wxNullColour);
/**
Returns the current file system.
diff --git a/misc/schema/xrc_schema.rnc b/misc/schema/xrc_schema.rnc
index 88c3e69d3f..cab7948175 100644
--- a/misc/schema/xrc_schema.rnc
+++ b/misc/schema/xrc_schema.rnc
@@ -458,8 +458,7 @@ t_showeffect = "wxSHOW_EFFECT_NONE" | "wxSHOW_EFFECT_ROLL_TO_LEFT" |
"wxSHOW_EFFECT_EXPAND"
t_url = string
-t_colour = xsd:string { pattern = "#[0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z]" } |
- xsd:string { pattern = "[^#].*" }
+t_colour = xsd:string { pattern = "(#[0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z]|[a-zA-Z0-9 ]+)(\|dark:(#[0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z]|[a-zA-Z0-9 ]+))?" }
t_position = t_size
t_size = xsd:string { pattern = "(-?\d+),(-?\d+)d?" }
t_pair_ints = xsd:string { pattern = "(-?\d+),(-?\d+)" }
diff --git a/samples/xrc/rc/controls.xrc b/samples/xrc/rc/controls.xrc
index 638f91a167..9617db25e6 100644
--- a/samples/xrc/rc/controls.xrc
+++ b/samples/xrc/rc/controls.xrc
@@ -1396,7 +1396,7 @@ lay them out using wxSizers, absolute positioning, everything you like!
5