diff --git a/docs/changes.txt b/docs/changes.txt index c33c52f58c..3ffbd29f8a 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -41,6 +41,10 @@ Changes in behaviour not resulting in compilation errors See wxCONFIG_USE_XDG and wxCONFIG_USE_HOME for how to customize this behaviour. You may also find wxFileConfig::MigrateLocalFile() useful. +- Values of many colours in wxColourDatabase have been changed to use the + values from the CSS standard. Use wxColourDatabase::UseScheme() to revert to + using the traditional values if your application appearance depends on them. + - As first mentioned in 3.0 release notes, the value of wxTHREAD_WAIT_DEFAULT, used by wxThread::Delete() and Wait() by default, has changed from wxTHREAD_WAIT_YIELD to wxTHREAD_WAIT_BLOCK for safety and consistency. diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index 17d510fc5b..e5ccf8087a 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -961,6 +961,16 @@ public: wxColourDatabase(); ~wxColourDatabase(); + // use the given colour scheme: CSS one is the default since 3.3.0, + // Traditional is the legacy colour scheme used by wxWidgets before it. + enum Scheme + { + CSS, + Traditional + }; + + void UseScheme(Scheme scheme); + // find colour by name or name for the given colour wxColour Find(const wxString& name) const; wxString FindName(const wxColour& colour) const; @@ -977,6 +987,8 @@ private: void Initialize(); wxStringToColourHashMap *m_map; + + Scheme m_scheme; }; #if WXWIN_COMPATIBILITY_3_2 diff --git a/interface/wx/gdicmn.h b/interface/wx/gdicmn.h index bef77ab9d4..de8a9c4832 100644 --- a/interface/wx/gdicmn.h +++ b/interface/wx/gdicmn.h @@ -816,6 +816,13 @@ const wxPoint wxDefaultPosition; using AddColour() and may use it to look up colours by names using Find() or find the names for the standard colour using FindName(). + It is also possible to switch between the colour values defined in the CSS + standard (see https://www.w3.org/TR/css-color-4/#named-colors) and the + traditional colour values which were used by wxWidgets versions earlier + than 3.3.0, which may be useful to preserve the appearance of the existing + code: if you need to do this, please call UseScheme() with @c Traditional + argument, but the use of new, standard colours is recommended. + There is one predefined, global instance of this class called ::wxTheColourDatabase. @@ -939,6 +946,50 @@ public: @since 3.3.0 */ wxVector GetAllNames() const; + + /** + Possible colour schemes for UseScheme(). + + @since 3.3.0 + */ + enum Scheme + { + CSS, ///< Use CSS standard colours, default since 3.3.0. + Traditional ///< Use traditional wxWidgets colours for compatibility. + }; + + /** + Select the colour scheme to use. + + By default, wxColourDatabase uses CSS scheme which returns the standard + values for the colours defined in the CSS specification, see + https://www.w3.org/TR/css-color-4/#named-colors + + If preserving compatibility with the behaviour and appearance of the + previous wxWidgets versions is important, you may switch to the + traditional colour scheme by using this function with @c Traditional + argument, e.g. call + + @code + wxTheColourDatabase->UseScheme(wxColourDatabase::Traditional); + @endcode + + during the application initialization. + + Note that the colour names defined only by wxWidgets, which notably + includes all colour variants with spaces in their names, are still + available in the default CSS colour scheme, with their traditional + values but the names of colours defined by CSS standard are taken from + it, e.g. "GREEN" corresponds to @c #00ff00 in the traditional scheme + but to @c #008000 in the CSS scheme. Similarly, CSS colour names that + were not defined by the previous wxWidgets versions are available even + when using the traditional scheme, the scheme choice only affects the + values of the colours defined by both wxWidgets and CSS with different + values. + + @since 3.3.0 + */ + void UseScheme(Scheme scheme); }; diff --git a/samples/drawing/drawing.cpp b/samples/drawing/drawing.cpp index 7e1bd4fe3c..3dfd820cbc 100644 --- a/samples/drawing/drawing.cpp +++ b/samples/drawing/drawing.cpp @@ -391,6 +391,9 @@ enum Colour_AppearanceLight, Colour_AppearanceDark, + Colour_DatabaseCSS, + Colour_DatabaseTraditional, + #if wxUSE_COLOURDLG Colour_TextForeground, Colour_TextBackground, @@ -2508,6 +2511,9 @@ MyFrame::MyFrame(const wxString& title) menuColour->AppendRadioItem(Colour_AppearanceLight, "Use &light appearance"); menuColour->AppendRadioItem(Colour_AppearanceDark, "Use &dark appearance"); menuColour->AppendSeparator(); + menuColour->AppendRadioItem(Colour_DatabaseCSS, "&Use CSS colours"); + menuColour->AppendRadioItem(Colour_DatabaseTraditional, "Use &traditional colours"); + menuColour->AppendSeparator(); #if wxUSE_COLOURDLG menuColour->Append( Colour_TextForeground, "Text &foreground..." ); menuColour->Append( Colour_TextBackground, "Text &background..." ); @@ -2559,7 +2565,7 @@ MyFrame::MyFrame(const wxString& title) m_textureBackground = false; m_canvas = new MyCanvas( this ); - m_canvas->SetScrollbars( 10, 10, 100, 240 ); + m_canvas->SetScrollbars( 10, 10, 100, 450 ); SetSize(FromDIP(wxSize(800, 700))); Center(wxBOTH); @@ -2835,6 +2841,14 @@ void MyFrame::OnOption(wxCommandEvent& event) Refresh(); break; + case Colour_DatabaseCSS: + case Colour_DatabaseTraditional: + wxTheColourDatabase->UseScheme(event.GetId() == Colour_DatabaseCSS + ? wxColourDatabase::CSS + : wxColourDatabase::Traditional); + Refresh(); + break; + #if wxUSE_COLOURDLG case Colour_TextForeground: m_colourForeground = SelectColour(); diff --git a/src/common/gdicmn.cpp b/src/common/gdicmn.cpp index d18bec8075..6b5876512d 100644 --- a/src/common/gdicmn.cpp +++ b/src/common/gdicmn.cpp @@ -264,6 +264,28 @@ wxRealPoint::wxRealPoint(const wxPoint& pt) // wxColourDatabase // ============================================================================ +namespace +{ + +struct wxColourDesc +{ + const char *name; + unsigned char r,g,b; +}; + +using wxColourMap = std::unordered_map; + +void AddColours(wxColourMap& map, const wxColourDesc* table, size_t len) +{ + for ( size_t n = 0; n < len; n++ ) + { + const wxColourDesc& cc = table[n]; + map[wxString::FromAscii(cc.name)] = wxColour(cc.r, cc.g, cc.b); + } +} + +} // anonymous namespace + // Due to a bug mentioned in wx/hashmap.h we have to use aggregation here and // define a simple accessor function below. // @@ -271,24 +293,17 @@ wxRealPoint::wxRealPoint(const wxPoint& pt) class wxStringToColourHashMap { public: - std::unordered_map m_colours; + wxColourMap m_colours; }; namespace { -inline std::unordered_map& -GetColours(wxStringToColourHashMap* map) +inline wxColourMap& GetColours(wxStringToColourHashMap* map) { return map->m_colours; } -struct wxColourDesc -{ - const char *name; - unsigned char r,g,b; -}; - } // anonymous namespace // ---------------------------------------------------------------------------- @@ -299,6 +314,8 @@ wxColourDatabase::wxColourDatabase () { // will be created on demand in Initialize() m_map = nullptr; + + m_scheme = CSS; } wxColourDatabase::~wxColourDatabase () @@ -317,7 +334,7 @@ void wxColourDatabase::Initialize() m_map = new wxStringToColourHashMap; - static const wxColourDesc wxColourTable[] = + static const wxColourDesc legacyColours[] = { {"AQUAMARINE",112, 219, 147}, {"BLACK",0, 0, 0}, @@ -397,12 +414,193 @@ void wxColourDatabase::Initialize() {"YELLOW GREEN", 153, 204, 50} }; - size_t n; - - for ( n = 0; n < WXSIZEOF(wxColourTable); n++ ) + // See https://www.w3.org/TR/css-color-4/#named-colors + static const wxColourDesc cssColours[] = { - const wxColourDesc& cc = wxColourTable[n]; - GetColours(m_map)[wxString::FromAscii(cc.name)] = wxColour(cc.r, cc.g, cc.b); + { "ALICEBLUE", 240, 248, 255 }, // #f0f8ff + { "ANTIQUEWHITE", 250, 235, 215 }, // #faebd7 + { "AQUA", 0, 255, 255 }, // #00ffff + { "AQUAMARINE", 127, 255, 212 }, // #7fffd4 + { "AZURE", 240, 255, 255 }, // #f0ffff + { "BEIGE", 245, 245, 220 }, // #f5f5dc + { "BISQUE", 255, 228, 196 }, // #ffe4c4 + { "BLACK", 0, 0, 0 }, // #000000 + { "BLANCHEDALMOND", 255, 235, 205 }, // #ffebcd + { "BLUE", 0, 0, 255 }, // #0000ff + { "BLUEVIOLET", 138, 43, 226 }, // #8a2be2 + { "BROWN", 165, 42, 42 }, // #a52a2a + { "BURLYWOOD", 222, 184, 135 }, // #deb887 + { "CADETBLUE", 95, 158, 160 }, // #5f9ea0 + { "CHARTREUSE", 127, 255, 0 }, // #7fff00 + { "CHOCOLATE", 210, 105, 30 }, // #d2691e + { "CORAL", 255, 127, 80 }, // #ff7f50 + { "CORNFLOWERBLUE", 100, 149, 237 }, // #6495ed + { "CORNSILK", 255, 248, 220 }, // #fff8dc + { "CRIMSON", 220, 20, 60 }, // #dc143c + { "CYAN", 0, 255, 255 }, // #00ffff + { "DARKBLUE", 0, 0, 139 }, // #00008b + { "DARKCYAN", 0, 139, 139 }, // #008b8b + { "DARKGOLDENROD", 184, 134, 11 }, // #b8860b + { "DARKGRAY", 169, 169, 169 }, // #a9a9a9 + { "DARKGREEN", 0, 100, 0 }, // #006400 + { "DARKGREY", 169, 169, 169 }, // #a9a9a9 + { "DARKKHAKI", 189, 183, 107 }, // #bdb76b + { "DARKMAGENTA", 139, 0, 139 }, // #8b008b + { "DARKOLIVEGREEN", 85, 107, 47 }, // #556b2f + { "DARKORANGE", 255, 140, 0 }, // #ff8c00 + { "DARKORCHID", 153, 50, 204 }, // #9932cc + { "DARKRED", 139, 0, 0 }, // #8b0000 + { "DARKSALMON", 233, 150, 122 }, // #e9967a + { "DARKSEAGREEN", 143, 188, 143 }, // #8fbc8f + { "DARKSLATEBLUE", 72, 61, 139 }, // #483d8b + { "DARKSLATEGRAY", 47, 79, 79 }, // #2f4f4f + { "DARKSLATEGREY", 47, 79, 79 }, // #2f4f4f + { "DARKTURQUOISE", 0, 206, 209 }, // #00ced1 + { "DARKVIOLET", 148, 0, 211 }, // #9400d3 + { "DEEPPINK", 255, 20, 147 }, // #ff1493 + { "DEEPSKYBLUE", 0, 191, 255 }, // #00bfff + { "DIMGRAY", 105, 105, 105 }, // #696969 + { "DIMGREY", 105, 105, 105 }, // #696969 + { "DODGERBLUE", 30, 144, 255 }, // #1e90ff + { "FIREBRICK", 178, 34, 34 }, // #b22222 + { "FLORALWHITE", 255, 250, 240 }, // #fffaf0 + { "FORESTGREEN", 34, 139, 34 }, // #228b22 + { "FUCHSIA", 255, 0, 255 }, // #ff00ff + { "GAINSBORO", 220, 220, 220 }, // #dcdcdc + { "GHOSTWHITE", 248, 248, 255 }, // #f8f8ff + { "GOLD", 255, 215, 0 }, // #ffd700 + { "GOLDENROD", 218, 165, 32 }, // #daa520 + { "GRAY", 128, 128, 128 }, // #808080 + { "GREEN", 0, 128, 0 }, // #008000 + { "GREENYELLOW", 173, 255, 47 }, // #adff2f + { "GREY", 128, 128, 128 }, // #808080 + { "HONEYDEW", 240, 255, 240 }, // #f0fff0 + { "HOTPINK", 255, 105, 180 }, // #ff69b4 + { "INDIANRED", 205, 92, 92 }, // #cd5c5c + { "INDIGO", 75, 0, 130 }, // #4b0082 + { "IVORY", 255, 255, 240 }, // #fffff0 + { "KHAKI", 240, 230, 140 }, // #f0e68c + { "LAVENDER", 230, 230, 250 }, // #e6e6fa + { "LAVENDERBLUSH", 255, 240, 245 }, // #fff0f5 + { "LAWNGREEN", 124, 252, 0 }, // #7cfc00 + { "LEMONCHIFFON", 255, 250, 205 }, // #fffacd + { "LIGHTBLUE", 173, 216, 230 }, // #add8e6 + { "LIGHTCORAL", 240, 128, 128 }, // #f08080 + { "LIGHTCYAN", 224, 255, 255 }, // #e0ffff + { "LIGHTGOLDENRODYELLOW", 250, 250, 210 }, // #fafad2 + { "LIGHTGRAY", 211, 211, 211 }, // #d3d3d3 + { "LIGHTGREEN", 144, 238, 144 }, // #90ee90 + { "LIGHTGREY", 211, 211, 211 }, // #d3d3d3 + { "LIGHTPINK", 255, 182, 193 }, // #ffb6c1 + { "LIGHTSALMON", 255, 160, 122 }, // #ffa07a + { "LIGHTSEAGREEN", 32, 178, 170 }, // #20b2aa + { "LIGHTSKYBLUE", 135, 206, 250 }, // #87cefa + { "LIGHTSLATEGRAY", 119, 136, 153 }, // #778899 + { "LIGHTSLATEGREY", 119, 136, 153 }, // #778899 + { "LIGHTSTEELBLUE", 176, 196, 222 }, // #b0c4de + { "LIGHTYELLOW", 255, 255, 224 }, // #ffffe0 + { "LIME", 0, 255, 0 }, // #00ff00 + { "LIMEGREEN", 50, 205, 50 }, // #32cd32 + { "LINEN", 250, 240, 230 }, // #faf0e6 + { "MAGENTA", 255, 0, 255 }, // #ff00ff + { "MAROON", 128, 0, 0 }, // #800000 + { "MEDIUMAQUAMARINE", 102, 205, 170 }, // #66cdaa + { "MEDIUMBLUE", 0, 0, 205 }, // #0000cd + { "MEDIUMORCHID", 186, 85, 211 }, // #ba55d3 + { "MEDIUMPURPLE", 147, 112, 219 }, // #9370db + { "MEDIUMSEAGREEN", 60, 179, 113 }, // #3cb371 + { "MEDIUMSLATEBLUE", 123, 104, 238 }, // #7b68ee + { "MEDIUMSPRINGGREEN", 0, 250, 154 }, // #00fa9a + { "MEDIUMTURQUOISE", 72, 209, 204 }, // #48d1cc + { "MEDIUMVIOLETRED", 199, 21, 133 }, // #c71585 + { "MIDNIGHTBLUE", 25, 25, 112 }, // #191970 + { "MINTCREAM", 245, 255, 250 }, // #f5fffa + { "MISTYROSE", 255, 228, 225 }, // #ffe4e1 + { "MOCCASIN", 255, 228, 181 }, // #ffe4b5 + { "NAVAJOWHITE", 255, 222, 173 }, // #ffdead + { "NAVY", 0, 0, 128 }, // #000080 + { "OLDLACE", 253, 245, 230 }, // #fdf5e6 + { "OLIVE", 128, 128, 0 }, // #808000 + { "OLIVEDRAB", 107, 142, 35 }, // #6b8e23 + { "ORANGE", 255, 165, 0 }, // #ffa500 + { "ORANGERED", 255, 69, 0 }, // #ff4500 + { "ORCHID", 218, 112, 214 }, // #da70d6 + { "PALEGOLDENROD", 238, 232, 170 }, // #eee8aa + { "PALEGREEN", 152, 251, 152 }, // #98fb98 + { "PALETURQUOISE", 175, 238, 238 }, // #afeeee + { "PALEVIOLETRED", 219, 112, 147 }, // #db7093 + { "PAPAYAWHIP", 255, 239, 213 }, // #ffefd5 + { "PEACHPUFF", 255, 218, 185 }, // #ffdab9 + { "PERU", 205, 133, 63 }, // #cd853f + { "PINK", 255, 192, 203 }, // #ffc0cb + { "PLUM", 221, 160, 221 }, // #dda0dd + { "POWDERBLUE", 176, 224, 230 }, // #b0e0e6 + { "PURPLE", 128, 0, 128 }, // #800080 + { "REBECCAPURPLE", 102, 51, 153 }, // #663399 + { "RED", 255, 0, 0 }, // #ff0000 + { "ROSYBROWN", 188, 143, 143 }, // #bc8f8f + { "ROYALBLUE", 65, 105, 225 }, // #4169e1 + { "SADDLEBROWN", 139, 69, 19 }, // #8b4513 + { "SALMON", 250, 128, 114 }, // #fa8072 + { "SANDYBROWN", 244, 164, 96 }, // #f4a460 + { "SEAGREEN", 46, 139, 87 }, // #2e8b57 + { "SEASHELL", 255, 245, 238 }, // #fff5ee + { "SIENNA", 160, 82, 45 }, // #a0522d + { "SILVER", 192, 192, 192 }, // #c0c0c0 + { "SKYBLUE", 135, 206, 235 }, // #87ceeb + { "SLATEBLUE", 106, 90, 205 }, // #6a5acd + { "SLATEGRAY", 112, 128, 144 }, // #708090 + { "SLATEGREY", 112, 128, 144 }, // #708090 + { "SNOW", 255, 250, 250 }, // #fffafa + { "SPRINGGREEN", 0, 255, 127 }, // #00ff7f + { "STEELBLUE", 70, 130, 180 }, // #4682b4 + { "TAN", 210, 180, 140 }, // #d2b48c + { "TEAL", 0, 128, 128 }, // #008080 + { "THISTLE", 216, 191, 216 }, // #d8bfd8 + { "TOMATO", 255, 99, 71 }, // #ff6347 + { "TURQUOISE", 64, 224, 208 }, // #40e0d0 + { "VIOLET", 238, 130, 238 }, // #ee82ee + { "WHEAT", 245, 222, 179 }, // #f5deb3 + { "WHITE", 255, 255, 255 }, // #ffffff + { "WHITESMOKE", 245, 245, 245 }, // #f5f5f5 + { "YELLOW", 255, 255, 0 }, // #ffff00 + { "YELLOWGREEN", 154, 205, 50 }, // #9acd32 + }; + + auto& map = GetColours(m_map); + + // We still use the legacy colour names in CSS scheme, but we add them + // first so any conflicting values are overwritten with the correct values + // in the CSS table. Similarly, we provide CSS colour names even in the + // traditional scheme -- but legacy colour values take precedence for the + // colours that used to be defined by wxWidgets. + switch ( m_scheme ) + { + case CSS: + AddColours(map, legacyColours, WXSIZEOF(legacyColours)); + AddColours(map, cssColours, WXSIZEOF(cssColours)); + break; + + case Traditional: + AddColours(map, cssColours, WXSIZEOF(cssColours)); + AddColours(map, legacyColours, WXSIZEOF(legacyColours)); + break; + } +} + +void wxColourDatabase::UseScheme(Scheme scheme) +{ + if ( scheme == m_scheme ) + return; + + m_scheme = scheme; + + // Reset the existing map for the different scheme, it will be re-filled on + // next use. + if ( m_map ) + { + delete m_map; + m_map = nullptr; } }