From ae5042599688af2d8b462e49e3cd103b6ec92fe9 Mon Sep 17 00:00:00 2001 From: crupest Date: Mon, 10 May 2021 17:09:15 +0800 Subject: ... --- .vscode/settings.json | 3 +- include/cru/platform/Color.hpp | 250 +++++++++++++++++++++++++++++++++++++ include/cru/platform/GraphBase.hpp | 182 +-------------------------- include/cru/ui/ThemeManager.hpp | 27 ++++ src/platform/CMakeLists.txt | 9 +- src/platform/Color.cpp | 231 ++++++++++++++++++++++++++++++++++ src/ui/CMakeLists.txt | 2 + src/ui/ThemeManager.cpp | 1 + test/platform/CMakeLists.txt | 1 + test/platform/ColorTest.cpp | 14 +++ vcpkg.json | 8 +- 11 files changed, 541 insertions(+), 187 deletions(-) create mode 100644 include/cru/platform/Color.hpp create mode 100644 include/cru/ui/ThemeManager.hpp create mode 100644 src/platform/Color.cpp create mode 100644 src/ui/ThemeManager.cpp create mode 100644 test/platform/ColorTest.cpp diff --git a/.vscode/settings.json b/.vscode/settings.json index 78d7b4c9..f951b23c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -88,6 +88,5 @@ "unordered_set": "cpp", "variant": "cpp" }, - "cmake.generator": "Ninja", - "cmake.configureOnOpen": true, + "cmake.generator": "Ninja" } diff --git a/include/cru/platform/Color.hpp b/include/cru/platform/Color.hpp new file mode 100644 index 00000000..d1a9b678 --- /dev/null +++ b/include/cru/platform/Color.hpp @@ -0,0 +1,250 @@ +#pragma once +#include "boost/functional/hash.hpp" + +#include +#include +#include +#include + +namespace cru::platform { +struct Color { + constexpr Color() : Color(0, 0, 0, 255) {} + constexpr Color(std::uint8_t red, std::uint8_t green, std::uint8_t blue, + std::uint8_t alpha = 255) + : red(red), green(green), blue(blue), alpha(alpha) {} + + constexpr static Color FromHex(std::uint32_t hex) { + const std::uint32_t mask = 0b11111111; + return Color((hex >> 16) & mask, (hex >> 8) & mask, hex & mask, 255); + } + + constexpr static Color FromHexAlpha(std::uint32_t hex) { + const std::uint32_t mask = 0b11111111; + return Color((hex >> 16) & mask, (hex >> 8) & mask, hex & mask, + (hex >> 24) & mask); + } + + constexpr Color WithAlpha(std::uint8_t new_alpha) const { + auto result = *this; + result.alpha = new_alpha; + return result; + } + + std::uint8_t red; + std::uint8_t green; + std::uint8_t blue; + std::uint8_t alpha; + + static std::optional Parse(std::u16string_view string, + bool parse_predefined_color = true); +}; + +constexpr int Compare(const Color& left, const Color& right) { + if (left.red < right.red) return -1; + if (left.red > right.red) return 1; + if (left.green < right.green) return -1; + if (left.green > right.green) return 1; + if (left.blue < right.blue) return -1; + if (left.blue > right.blue) return 1; + if (left.alpha < right.alpha) return -1; + if (left.alpha > right.alpha) return 1; + return 0; +} + +constexpr bool operator==(const Color& left, const Color& right) { + return Compare(left, right) == 0; +} + +constexpr bool operator!=(const Color& left, const Color& right) { + return Compare(left, right) != 0; +} + +constexpr bool operator<(const Color& left, const Color& right) { + return Compare(left, right) < 0; +} + +constexpr bool operator<=(const Color& left, const Color& right) { + return Compare(left, right) <= 0; +} + +constexpr bool operator>(const Color& left, const Color& right) { + return Compare(left, right) > 0; +} + +constexpr bool operator>=(const Color& left, const Color& right) { + return Compare(left, right) >= 0; +} + +namespace colors { +constexpr Color transparent = Color::FromHexAlpha(0x00000000); +constexpr Color black = Color::FromHex(0x000000); +constexpr Color silver = Color::FromHex(0xc0c0c0); +constexpr Color gray = Color::FromHex(0x808080); +constexpr Color white = Color::FromHex(0xffffff); +constexpr Color maroon = Color::FromHex(0x800000); +constexpr Color red = Color::FromHex(0xff0000); +constexpr Color purple = Color::FromHex(0x800080); +constexpr Color fuchsia = Color::FromHex(0xff00ff); +constexpr Color green = Color::FromHex(0x008000); +constexpr Color lime = Color::FromHex(0x00ff00); +constexpr Color olive = Color::FromHex(0x808000); +constexpr Color yellow = Color::FromHex(0xffff00); +constexpr Color navy = Color::FromHex(0x000080); +constexpr Color blue = Color::FromHex(0x0000ff); +constexpr Color teal = Color::FromHex(0x008080); +constexpr Color aqua = Color::FromHex(0x00ffff); +constexpr Color orange = Color::FromHex(0xffa500); +constexpr Color aliceblue = Color::FromHex(0xf0f8ff); +constexpr Color antiquewhite = Color::FromHex(0xfaebd7); +constexpr Color aquamarine = Color::FromHex(0x7fffd4); +constexpr Color azure = Color::FromHex(0xf0ffff); +constexpr Color beige = Color::FromHex(0xf5f5dc); +constexpr Color bisque = Color::FromHex(0xffe4c4); +constexpr Color blanchedalmond = Color::FromHex(0xffebcd); +constexpr Color blueviolet = Color::FromHex(0x8a2be2); +constexpr Color brown = Color::FromHex(0xa52a2a); +constexpr Color burlywood = Color::FromHex(0xdeb887); +constexpr Color cadetblue = Color::FromHex(0x5f9ea0); +constexpr Color chartreuse = Color::FromHex(0x7fff00); +constexpr Color chocolate = Color::FromHex(0xd2691e); +constexpr Color coral = Color::FromHex(0xff7f50); +constexpr Color cornflowerblue = Color::FromHex(0x6495ed); +constexpr Color cornsilk = Color::FromHex(0xfff8dc); +constexpr Color crimson = Color::FromHex(0xdc143c); +constexpr Color cyan = aqua; +constexpr Color darkblue = Color::FromHex(0x00008b); +constexpr Color darkcyan = Color::FromHex(0x008b8b); +constexpr Color darkgoldenrod = Color::FromHex(0xb8860b); +constexpr Color darkgray = Color::FromHex(0xa9a9a9); +constexpr Color darkgreen = Color::FromHex(0x006400); +constexpr Color darkgrey = Color::FromHex(0xa9a9a9); +constexpr Color darkkhaki = Color::FromHex(0xbdb76b); +constexpr Color darkmagenta = Color::FromHex(0x8b008b); +constexpr Color darkolivegreen = Color::FromHex(0x556b2f); +constexpr Color darkorange = Color::FromHex(0xff8c00); +constexpr Color darkorchid = Color::FromHex(0x9932cc); +constexpr Color darkred = Color::FromHex(0x8b0000); +constexpr Color darksalmon = Color::FromHex(0xe9967a); +constexpr Color darkseagreen = Color::FromHex(0x8fbc8f); +constexpr Color darkslateblue = Color::FromHex(0x483d8b); +constexpr Color darkslategray = Color::FromHex(0x2f4f4f); +constexpr Color darkslategrey = Color::FromHex(0x2f4f4f); +constexpr Color darkturquoise = Color::FromHex(0x00ced1); +constexpr Color darkviolet = Color::FromHex(0x9400d3); +constexpr Color deeppink = Color::FromHex(0xff1493); +constexpr Color deepskyblue = Color::FromHex(0x00bfff); +constexpr Color dimgray = Color::FromHex(0x696969); +constexpr Color dimgrey = Color::FromHex(0x696969); +constexpr Color dodgerblue = Color::FromHex(0x1e90ff); +constexpr Color firebrick = Color::FromHex(0xb22222); +constexpr Color floralwhite = Color::FromHex(0xfffaf0); +constexpr Color forestgreen = Color::FromHex(0x228b22); +constexpr Color gainsboro = Color::FromHex(0xdcdcdc); +constexpr Color ghostwhite = Color::FromHex(0xf8f8ff); +constexpr Color gold = Color::FromHex(0xffd700); +constexpr Color goldenrod = Color::FromHex(0xdaa520); +constexpr Color greenyellow = Color::FromHex(0xadff2f); +constexpr Color grey = Color::FromHex(0x808080); +constexpr Color honeydew = Color::FromHex(0xf0fff0); +constexpr Color hotpink = Color::FromHex(0xff69b4); +constexpr Color indianred = Color::FromHex(0xcd5c5c); +constexpr Color indigo = Color::FromHex(0x4b0082); +constexpr Color ivory = Color::FromHex(0xfffff0); +constexpr Color khaki = Color::FromHex(0xf0e68c); +constexpr Color lavender = Color::FromHex(0xe6e6fa); +constexpr Color lavenderblush = Color::FromHex(0xfff0f5); +constexpr Color lawngreen = Color::FromHex(0x7cfc00); +constexpr Color lemonchiffon = Color::FromHex(0xfffacd); +constexpr Color lightblue = Color::FromHex(0xadd8e6); +constexpr Color lightcoral = Color::FromHex(0xf08080); +constexpr Color lightcyan = Color::FromHex(0xe0ffff); +constexpr Color lightgoldenrodyellow = Color::FromHex(0xfafad2); +constexpr Color lightgray = Color::FromHex(0xd3d3d3); +constexpr Color lightgreen = Color::FromHex(0x90ee90); +constexpr Color lightgrey = Color::FromHex(0xd3d3d3); +constexpr Color lightpink = Color::FromHex(0xffb6c1); +constexpr Color lightsalmon = Color::FromHex(0xffa07a); +constexpr Color lightseagreen = Color::FromHex(0x20b2aa); +constexpr Color lightskyblue = Color::FromHex(0x87cefa); +constexpr Color lightslategray = Color::FromHex(0x778899); +constexpr Color lightslategrey = Color::FromHex(0x778899); +constexpr Color lightsteelblue = Color::FromHex(0xb0c4de); +constexpr Color lightyellow = Color::FromHex(0xffffe0); +constexpr Color limegreen = Color::FromHex(0x32cd32); +constexpr Color linen = Color::FromHex(0xfaf0e6); +constexpr Color magenta = fuchsia; +constexpr Color mediumaquamarine = Color::FromHex(0x66cdaa); +constexpr Color mediumblue = Color::FromHex(0x0000cd); +constexpr Color mediumorchid = Color::FromHex(0xba55d3); +constexpr Color mediumpurple = Color::FromHex(0x9370db); +constexpr Color mediumseagreen = Color::FromHex(0x3cb371); +constexpr Color mediumslateblue = Color::FromHex(0x7b68ee); +constexpr Color mediumspringgreen = Color::FromHex(0x00fa9a); +constexpr Color mediumturquoise = Color::FromHex(0x48d1cc); +constexpr Color mediumvioletred = Color::FromHex(0xc71585); +constexpr Color midnightblue = Color::FromHex(0x191970); +constexpr Color mintcream = Color::FromHex(0xf5fffa); +constexpr Color mistyrose = Color::FromHex(0xffe4e1); +constexpr Color moccasin = Color::FromHex(0xffe4b5); +constexpr Color navajowhite = Color::FromHex(0xffdead); +constexpr Color oldlace = Color::FromHex(0xfdf5e6); +constexpr Color olivedrab = Color::FromHex(0x6b8e23); +constexpr Color orangered = Color::FromHex(0xff4500); +constexpr Color orchid = Color::FromHex(0xda70d6); +constexpr Color palegoldenrod = Color::FromHex(0xeee8aa); +constexpr Color palegreen = Color::FromHex(0x98fb98); +constexpr Color paleturquoise = Color::FromHex(0xafeeee); +constexpr Color palevioletred = Color::FromHex(0xdb7093); +constexpr Color papayawhip = Color::FromHex(0xffefd5); +constexpr Color peachpuff = Color::FromHex(0xffdab9); +constexpr Color peru = Color::FromHex(0xcd853f); +constexpr Color pink = Color::FromHex(0xffc0cb); +constexpr Color plum = Color::FromHex(0xdda0dd); +constexpr Color powderblue = Color::FromHex(0xb0e0e6); +constexpr Color rosybrown = Color::FromHex(0xbc8f8f); +constexpr Color royalblue = Color::FromHex(0x4169e1); +constexpr Color saddlebrown = Color::FromHex(0x8b4513); +constexpr Color salmon = Color::FromHex(0xfa8072); +constexpr Color sandybrown = Color::FromHex(0xf4a460); +constexpr Color seagreen = Color::FromHex(0x2e8b57); +constexpr Color seashell = Color::FromHex(0xfff5ee); +constexpr Color sienna = Color::FromHex(0xa0522d); +constexpr Color skyblue = Color::FromHex(0x87ceeb); +constexpr Color slateblue = Color::FromHex(0x6a5acd); +constexpr Color slategray = Color::FromHex(0x708090); +constexpr Color slategrey = Color::FromHex(0x708090); +constexpr Color snow = Color::FromHex(0xfffafa); +constexpr Color springgreen = Color::FromHex(0x00ff7f); +constexpr Color steelblue = Color::FromHex(0x4682b4); +constexpr Color tan = Color::FromHex(0xd2b48c); +constexpr Color thistle = Color::FromHex(0xd8bfd8); +constexpr Color tomato = Color::FromHex(0xff6347); +constexpr Color turquoise = Color::FromHex(0x40e0d0); +constexpr Color violet = Color::FromHex(0xee82ee); +constexpr Color wheat = Color::FromHex(0xf5deb3); +constexpr Color whitesmoke = Color::FromHex(0xf5f5f5); +constexpr Color yellowgreen = Color::FromHex(0x9acd32); +constexpr Color rebeccapurple = Color::FromHex(0x663399); +} // namespace colors +} // namespace cru::platform + +template <> +struct std::hash { + std::size_t operator()(const cru::platform::Color& color) const { + std::size_t seed = 0; + boost::hash_combine(seed, color.red); + boost::hash_combine(seed, color.green); + boost::hash_combine(seed, color.blue); + boost::hash_combine(seed, color.alpha); + return seed; + } +}; + +namespace cru::platform { +namespace details { +extern const std::unordered_map + predefined_name_color_map; +} // namespace details + +std::optional GetPredefinedColorByName(std::u16string_view name); +} // namespace cru::platform diff --git a/include/cru/platform/GraphBase.hpp b/include/cru/platform/GraphBase.hpp index 4d3c8f83..c4dd19f6 100644 --- a/include/cru/platform/GraphBase.hpp +++ b/include/cru/platform/GraphBase.hpp @@ -1,6 +1,7 @@ #pragma once #include "cru/common/Base.hpp" +#include "Color.hpp" #include "cru/common/Format.hpp" #include @@ -303,185 +304,4 @@ struct TextRange final { gsl::index position = 0; gsl::index count = 0; }; - -struct Color { - constexpr Color() : Color(0, 0, 0, 255) {} - constexpr Color(std::uint8_t red, std::uint8_t green, std::uint8_t blue, - std::uint8_t alpha = 255) - : red(red), green(green), blue(blue), alpha(alpha) {} - - constexpr static Color FromHex(std::uint32_t hex) { - const std::uint32_t mask = 0b11111111; - return Color((hex >> 16) & mask, (hex >> 8) & mask, hex & mask, 255); - } - - constexpr static Color FromHexAlpha(std::uint32_t hex) { - const std::uint32_t mask = 0b11111111; - return Color((hex >> 16) & mask, (hex >> 8) & mask, hex & mask, - (hex >> 24) & mask); - } - - constexpr Color WithAlpha(std::uint8_t new_alpha) const { - auto result = *this; - result.alpha = new_alpha; - return result; - } - - std::uint8_t red; - std::uint8_t green; - std::uint8_t blue; - std::uint8_t alpha; -}; - -namespace colors { -constexpr Color transparent = Color::FromHexAlpha(0x00000000); -constexpr Color black = Color::FromHex(0x000000); -constexpr Color silver = Color::FromHex(0xc0c0c0); -constexpr Color gray = Color::FromHex(0x808080); -constexpr Color white = Color::FromHex(0xffffff); -constexpr Color maroon = Color::FromHex(0x800000); -constexpr Color red = Color::FromHex(0xff0000); -constexpr Color purple = Color::FromHex(0x800080); -constexpr Color fuchsia = Color::FromHex(0xff00ff); -constexpr Color green = Color::FromHex(0x008000); -constexpr Color lime = Color::FromHex(0x00ff00); -constexpr Color olive = Color::FromHex(0x808000); -constexpr Color yellow = Color::FromHex(0xffff00); -constexpr Color navy = Color::FromHex(0x000080); -constexpr Color blue = Color::FromHex(0x0000ff); -constexpr Color teal = Color::FromHex(0x008080); -constexpr Color aqua = Color::FromHex(0x00ffff); -constexpr Color orange = Color::FromHex(0xffa500); -constexpr Color aliceblue = Color::FromHex(0xf0f8ff); -constexpr Color antiquewhite = Color::FromHex(0xfaebd7); -constexpr Color aquamarine = Color::FromHex(0x7fffd4); -constexpr Color azure = Color::FromHex(0xf0ffff); -constexpr Color beige = Color::FromHex(0xf5f5dc); -constexpr Color bisque = Color::FromHex(0xffe4c4); -constexpr Color blanchedalmond = Color::FromHex(0xffebcd); -constexpr Color blueviolet = Color::FromHex(0x8a2be2); -constexpr Color brown = Color::FromHex(0xa52a2a); -constexpr Color burlywood = Color::FromHex(0xdeb887); -constexpr Color cadetblue = Color::FromHex(0x5f9ea0); -constexpr Color chartreuse = Color::FromHex(0x7fff00); -constexpr Color chocolate = Color::FromHex(0xd2691e); -constexpr Color coral = Color::FromHex(0xff7f50); -constexpr Color cornflowerblue = Color::FromHex(0x6495ed); -constexpr Color cornsilk = Color::FromHex(0xfff8dc); -constexpr Color crimson = Color::FromHex(0xdc143c); -constexpr Color cyan = aqua; -constexpr Color darkblue = Color::FromHex(0x00008b); -constexpr Color darkcyan = Color::FromHex(0x008b8b); -constexpr Color darkgoldenrod = Color::FromHex(0xb8860b); -constexpr Color darkgray = Color::FromHex(0xa9a9a9); -constexpr Color darkgreen = Color::FromHex(0x006400); -constexpr Color darkgrey = Color::FromHex(0xa9a9a9); -constexpr Color darkkhaki = Color::FromHex(0xbdb76b); -constexpr Color darkmagenta = Color::FromHex(0x8b008b); -constexpr Color darkolivegreen = Color::FromHex(0x556b2f); -constexpr Color darkorange = Color::FromHex(0xff8c00); -constexpr Color darkorchid = Color::FromHex(0x9932cc); -constexpr Color darkred = Color::FromHex(0x8b0000); -constexpr Color darksalmon = Color::FromHex(0xe9967a); -constexpr Color darkseagreen = Color::FromHex(0x8fbc8f); -constexpr Color darkslateblue = Color::FromHex(0x483d8b); -constexpr Color darkslategray = Color::FromHex(0x2f4f4f); -constexpr Color darkslategrey = Color::FromHex(0x2f4f4f); -constexpr Color darkturquoise = Color::FromHex(0x00ced1); -constexpr Color darkviolet = Color::FromHex(0x9400d3); -constexpr Color deeppink = Color::FromHex(0xff1493); -constexpr Color deepskyblue = Color::FromHex(0x00bfff); -constexpr Color dimgray = Color::FromHex(0x696969); -constexpr Color dimgrey = Color::FromHex(0x696969); -constexpr Color dodgerblue = Color::FromHex(0x1e90ff); -constexpr Color firebrick = Color::FromHex(0xb22222); -constexpr Color floralwhite = Color::FromHex(0xfffaf0); -constexpr Color forestgreen = Color::FromHex(0x228b22); -constexpr Color gainsboro = Color::FromHex(0xdcdcdc); -constexpr Color ghostwhite = Color::FromHex(0xf8f8ff); -constexpr Color gold = Color::FromHex(0xffd700); -constexpr Color goldenrod = Color::FromHex(0xdaa520); -constexpr Color greenyellow = Color::FromHex(0xadff2f); -constexpr Color grey = Color::FromHex(0x808080); -constexpr Color honeydew = Color::FromHex(0xf0fff0); -constexpr Color hotpink = Color::FromHex(0xff69b4); -constexpr Color indianred = Color::FromHex(0xcd5c5c); -constexpr Color indigo = Color::FromHex(0x4b0082); -constexpr Color ivory = Color::FromHex(0xfffff0); -constexpr Color khaki = Color::FromHex(0xf0e68c); -constexpr Color lavender = Color::FromHex(0xe6e6fa); -constexpr Color lavenderblush = Color::FromHex(0xfff0f5); -constexpr Color lawngreen = Color::FromHex(0x7cfc00); -constexpr Color lemonchiffon = Color::FromHex(0xfffacd); -constexpr Color lightblue = Color::FromHex(0xadd8e6); -constexpr Color lightcoral = Color::FromHex(0xf08080); -constexpr Color lightcyan = Color::FromHex(0xe0ffff); -constexpr Color lightgoldenrodyellow = Color::FromHex(0xfafad2); -constexpr Color lightgray = Color::FromHex(0xd3d3d3); -constexpr Color lightgreen = Color::FromHex(0x90ee90); -constexpr Color lightgrey = Color::FromHex(0xd3d3d3); -constexpr Color lightpink = Color::FromHex(0xffb6c1); -constexpr Color lightsalmon = Color::FromHex(0xffa07a); -constexpr Color lightseagreen = Color::FromHex(0x20b2aa); -constexpr Color lightskyblue = Color::FromHex(0x87cefa); -constexpr Color lightslategray = Color::FromHex(0x778899); -constexpr Color lightslategrey = Color::FromHex(0x778899); -constexpr Color lightsteelblue = Color::FromHex(0xb0c4de); -constexpr Color lightyellow = Color::FromHex(0xffffe0); -constexpr Color limegreen = Color::FromHex(0x32cd32); -constexpr Color linen = Color::FromHex(0xfaf0e6); -constexpr Color magenta = fuchsia; -constexpr Color mediumaquamarine = Color::FromHex(0x66cdaa); -constexpr Color mediumblue = Color::FromHex(0x0000cd); -constexpr Color mediumorchid = Color::FromHex(0xba55d3); -constexpr Color mediumpurple = Color::FromHex(0x9370db); -constexpr Color mediumseagreen = Color::FromHex(0x3cb371); -constexpr Color mediumslateblue = Color::FromHex(0x7b68ee); -constexpr Color mediumspringgreen = Color::FromHex(0x00fa9a); -constexpr Color mediumturquoise = Color::FromHex(0x48d1cc); -constexpr Color mediumvioletred = Color::FromHex(0xc71585); -constexpr Color midnightblue = Color::FromHex(0x191970); -constexpr Color mintcream = Color::FromHex(0xf5fffa); -constexpr Color mistyrose = Color::FromHex(0xffe4e1); -constexpr Color moccasin = Color::FromHex(0xffe4b5); -constexpr Color navajowhite = Color::FromHex(0xffdead); -constexpr Color oldlace = Color::FromHex(0xfdf5e6); -constexpr Color olivedrab = Color::FromHex(0x6b8e23); -constexpr Color orangered = Color::FromHex(0xff4500); -constexpr Color orchid = Color::FromHex(0xda70d6); -constexpr Color palegoldenrod = Color::FromHex(0xeee8aa); -constexpr Color palegreen = Color::FromHex(0x98fb98); -constexpr Color paleturquoise = Color::FromHex(0xafeeee); -constexpr Color palevioletred = Color::FromHex(0xdb7093); -constexpr Color papayawhip = Color::FromHex(0xffefd5); -constexpr Color peachpuff = Color::FromHex(0xffdab9); -constexpr Color peru = Color::FromHex(0xcd853f); -constexpr Color pink = Color::FromHex(0xffc0cb); -constexpr Color plum = Color::FromHex(0xdda0dd); -constexpr Color powderblue = Color::FromHex(0xb0e0e6); -constexpr Color rosybrown = Color::FromHex(0xbc8f8f); -constexpr Color royalblue = Color::FromHex(0x4169e1); -constexpr Color saddlebrown = Color::FromHex(0x8b4513); -constexpr Color salmon = Color::FromHex(0xfa8072); -constexpr Color sandybrown = Color::FromHex(0xf4a460); -constexpr Color seagreen = Color::FromHex(0x2e8b57); -constexpr Color seashell = Color::FromHex(0xfff5ee); -constexpr Color sienna = Color::FromHex(0xa0522d); -constexpr Color skyblue = Color::FromHex(0x87ceeb); -constexpr Color slateblue = Color::FromHex(0x6a5acd); -constexpr Color slategray = Color::FromHex(0x708090); -constexpr Color slategrey = Color::FromHex(0x708090); -constexpr Color snow = Color::FromHex(0xfffafa); -constexpr Color springgreen = Color::FromHex(0x00ff7f); -constexpr Color steelblue = Color::FromHex(0x4682b4); -constexpr Color tan = Color::FromHex(0xd2b48c); -constexpr Color thistle = Color::FromHex(0xd8bfd8); -constexpr Color tomato = Color::FromHex(0xff6347); -constexpr Color turquoise = Color::FromHex(0x40e0d0); -constexpr Color violet = Color::FromHex(0xee82ee); -constexpr Color wheat = Color::FromHex(0xf5deb3); -constexpr Color whitesmoke = Color::FromHex(0xf5f5f5); -constexpr Color yellowgreen = Color::FromHex(0x9acd32); -constexpr Color rebeccapurple = Color::FromHex(0x663399); -} // namespace colors } // namespace cru::platform diff --git a/include/cru/ui/ThemeManager.hpp b/include/cru/ui/ThemeManager.hpp new file mode 100644 index 00000000..c9e17680 --- /dev/null +++ b/include/cru/ui/ThemeManager.hpp @@ -0,0 +1,27 @@ +#pragma once +#include "Base.hpp" +#include "cru/common/Base.hpp" +#include "cru/common/Event.hpp" + +#include +#include + +namespace cru::ui { +class ThemeManager : public Object { + public: + ThemeManager(); + + CRU_DELETE_COPY(ThemeManager) + CRU_DELETE_MOVE(ThemeManager) + + ~ThemeManager() override; + + IEvent* ThemeResourceChangeEvent() { + return &theme_resource_change_event_; + } + + private: + Event theme_resource_change_event_; + boost::property_tree::iptree theme_tree_; +}; +} // namespace cru::ui diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt index 623ec08f..23f4a0f6 100644 --- a/src/platform/CMakeLists.txt +++ b/src/platform/CMakeLists.txt @@ -1,14 +1,17 @@ set(CRU_PLATFORM_BASE_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/platform) -add_library(cru_platform_base INTERFACE) -target_sources(cru_platform_base INTERFACE +add_library(cru_platform_base STATIC + Color.cpp +) +target_sources(cru_platform_base PUBLIC ${CRU_PLATFORM_BASE_INCLUDE_DIR}/Check.hpp + ${CRU_PLATFORM_BASE_INCLUDE_DIR}/Color.hpp ${CRU_PLATFORM_BASE_INCLUDE_DIR}/Exception.hpp ${CRU_PLATFORM_BASE_INCLUDE_DIR}/GraphBase.hpp ${CRU_PLATFORM_BASE_INCLUDE_DIR}/HeapDebug.hpp ${CRU_PLATFORM_BASE_INCLUDE_DIR}/Matrix.hpp ${CRU_PLATFORM_BASE_INCLUDE_DIR}/Resource.hpp ) -target_link_libraries(cru_platform_base INTERFACE cru_base) +target_link_libraries(cru_platform_base PUBLIC cru_base) add_subdirectory(graphics) add_subdirectory(gui) diff --git a/src/platform/Color.cpp b/src/platform/Color.cpp new file mode 100644 index 00000000..325cf413 --- /dev/null +++ b/src/platform/Color.cpp @@ -0,0 +1,231 @@ +#include "cru/platform/Color.hpp" + +#include +#include +#include +#include +#include "gsl/gsl_util" + +namespace cru::platform { +std::optional Color::Parse(std::u16string_view string, + bool parse_predefined_color) { + if (parse_predefined_color) { + auto optional_predefined_color = GetPredefinedColorByName(string); + if (optional_predefined_color) { + return *optional_predefined_color; + } + } + + auto get_num = [](char16_t c) -> std::optional { + if (c >= u'0' && c <= u'9') return c - u'0'; + if (c >= u'A' && c <= u'F') return c - u'A' + 10; + if (c >= u'a' && c <= u'f') return c - u'a' + 10; + return std::nullopt; + }; + + auto get_num_for_two_digit = + [get_num](std::u16string_view str) -> std::optional { + int num = 0; + auto d1 = get_num(str[0]); + if (!d1) return std::nullopt; + num += *d1 * 16; + auto d2 = get_num(str[1]); + if (!d2) return std::nullopt; + num += *d2; + return num; + }; + + const auto string_size = string.size(); + + if (string_size == 7) { + if (string[0] != u'#') return std::nullopt; + auto r = get_num_for_two_digit(string.substr(1, 2)); + if (!r) return std::nullopt; + auto g = get_num_for_two_digit(string.substr(3, 2)); + if (!g) return std::nullopt; + auto b = get_num_for_two_digit(string.substr(5, 2)); + if (!b) return std::nullopt; + return Color(gsl::narrow_cast(*r), + gsl::narrow_cast(*g), + gsl::narrow_cast(*b)); + } else if (string_size == 9) { + if (string[0] != u'#') return std::nullopt; + auto a = get_num_for_two_digit(string.substr(1, 2)); + if (!a) return std::nullopt; + auto r = get_num_for_two_digit(string.substr(3, 2)); + if (!r) return std::nullopt; + auto g = get_num_for_two_digit(string.substr(5, 2)); + if (!g) return std::nullopt; + auto b = get_num_for_two_digit(string.substr(7, 2)); + if (!b) return std::nullopt; + return Color( + gsl::narrow_cast(*r), gsl::narrow_cast(*g), + gsl::narrow_cast(*b), gsl::narrow_cast(*a)); + } else { + return std::nullopt; + } +} + +namespace details { +const std::unordered_map predefined_name_color_map{ + {u"transparent", colors::transparent}, + {u"black", colors::black}, + {u"silver", colors::silver}, + {u"gray", colors::gray}, + {u"white", colors::white}, + {u"maroon", colors::maroon}, + {u"red", colors::red}, + {u"purple", colors::purple}, + {u"fuchsia", colors::fuchsia}, + {u"green", colors::green}, + {u"lime", colors::lime}, + {u"olive", colors::olive}, + {u"yellow", colors::yellow}, + {u"navy", colors::navy}, + {u"blue", colors::blue}, + {u"teal", colors::teal}, + {u"aqua", colors::aqua}, + {u"orange", colors::orange}, + {u"aliceblue", colors::aliceblue}, + {u"antiquewhite", colors::antiquewhite}, + {u"aquamarine", colors::aquamarine}, + {u"azure", colors::azure}, + {u"beige", colors::beige}, + {u"bisque", colors::bisque}, + {u"blanchedalmond", colors::blanchedalmond}, + {u"blueviolet", colors::blueviolet}, + {u"brown", colors::brown}, + {u"burlywood", colors::burlywood}, + {u"cadetblue", colors::cadetblue}, + {u"chartreuse", colors::chartreuse}, + {u"chocolate", colors::chocolate}, + {u"coral", colors::coral}, + {u"cornflowerblue", colors::cornflowerblue}, + {u"cornsilk", colors::cornsilk}, + {u"crimson", colors::crimson}, + {u"cyan", colors::cyan}, + {u"darkblue", colors::darkblue}, + {u"darkcyan", colors::darkcyan}, + {u"darkgoldenrod", colors::darkgoldenrod}, + {u"darkgray", colors::darkgray}, + {u"darkgreen", colors::darkgreen}, + {u"darkgrey", colors::darkgrey}, + {u"darkkhaki", colors::darkkhaki}, + {u"darkmagenta", colors::darkmagenta}, + {u"darkolivegreen", colors::darkolivegreen}, + {u"darkorange", colors::darkorange}, + {u"darkorchid", colors::darkorchid}, + {u"darkred", colors::darkred}, + {u"darksalmon", colors::darksalmon}, + {u"darkseagreen", colors::darkseagreen}, + {u"darkslateblue", colors::darkslateblue}, + {u"darkslategray", colors::darkslategray}, + {u"darkslategrey", colors::darkslategrey}, + {u"darkturquoise", colors::darkturquoise}, + {u"darkviolet", colors::darkviolet}, + {u"deeppink", colors::deeppink}, + {u"deepskyblue", colors::deepskyblue}, + {u"dimgray", colors::dimgray}, + {u"dimgrey", colors::dimgrey}, + {u"dodgerblue", colors::dodgerblue}, + {u"firebrick", colors::firebrick}, + {u"floralwhite", colors::floralwhite}, + {u"forestgreen", colors::forestgreen}, + {u"gainsboro", colors::gainsboro}, + {u"ghostwhite", colors::ghostwhite}, + {u"gold", colors::gold}, + {u"goldenrod", colors::goldenrod}, + {u"greenyellow", colors::greenyellow}, + {u"grey", colors::grey}, + {u"honeydew", colors::honeydew}, + {u"hotpink", colors::hotpink}, + {u"indianred", colors::indianred}, + {u"indigo", colors::indigo}, + {u"ivory", colors::ivory}, + {u"khaki", colors::khaki}, + {u"lavender", colors::lavender}, + {u"lavenderblush", colors::lavenderblush}, + {u"lawngreen", colors::lawngreen}, + {u"lemonchiffon", colors::lemonchiffon}, + {u"lightblue", colors::lightblue}, + {u"lightcoral", colors::lightcoral}, + {u"lightcyan", colors::lightcyan}, + {u"lightgoldenrodyellow", colors::lightgoldenrodyellow}, + {u"lightgray", colors::lightgray}, + {u"lightgreen", colors::lightgreen}, + {u"lightgrey", colors::lightgrey}, + {u"lightpink", colors::lightpink}, + {u"lightsalmon", colors::lightsalmon}, + {u"lightseagreen", colors::lightseagreen}, + {u"lightskyblue", colors::lightskyblue}, + {u"lightslategray", colors::lightslategray}, + {u"lightslategrey", colors::lightslategrey}, + {u"lightsteelblue", colors::lightsteelblue}, + {u"lightyellow", colors::lightyellow}, + {u"limegreen", colors::limegreen}, + {u"linen", colors::linen}, + {u"magenta", colors::magenta}, + {u"mediumaquamarine", colors::mediumaquamarine}, + {u"mediumblue", colors::mediumblue}, + {u"mediumorchid", colors::mediumorchid}, + {u"mediumpurple", colors::mediumpurple}, + {u"mediumseagreen", colors::mediumseagreen}, + {u"mediumslateblue", colors::mediumslateblue}, + {u"mediumspringgreen", colors::mediumspringgreen}, + {u"mediumturquoise", colors::mediumturquoise}, + {u"mediumvioletred", colors::mediumvioletred}, + {u"midnightblue", colors::midnightblue}, + {u"mintcream", colors::mintcream}, + {u"mistyrose", colors::mistyrose}, + {u"moccasin", colors::moccasin}, + {u"navajowhite", colors::navajowhite}, + {u"oldlace", colors::oldlace}, + {u"olivedrab", colors::olivedrab}, + {u"orangered", colors::orangered}, + {u"orchid", colors::orchid}, + {u"palegoldenrod", colors::palegoldenrod}, + {u"palegreen", colors::palegreen}, + {u"paleturquoise", colors::paleturquoise}, + {u"palevioletred", colors::palevioletred}, + {u"papayawhip", colors::papayawhip}, + {u"peachpuff", colors::peachpuff}, + {u"peru", colors::peru}, + {u"pink", colors::pink}, + {u"plum", colors::plum}, + {u"powderblue", colors::powderblue}, + {u"rosybrown", colors::rosybrown}, + {u"royalblue", colors::royalblue}, + {u"saddlebrown", colors::saddlebrown}, + {u"salmon", colors::salmon}, + {u"sandybrown", colors::sandybrown}, + {u"seagreen", colors::seagreen}, + {u"seashell", colors::seashell}, + {u"sienna", colors::sienna}, + {u"skyblue", colors::skyblue}, + {u"slateblue", colors::slateblue}, + {u"slategray", colors::slategray}, + {u"slategrey", colors::slategrey}, + {u"snow", colors::snow}, + {u"springgreen", colors::springgreen}, + {u"steelblue", colors::steelblue}, + {u"tan", colors::tan}, + {u"thistle", colors::thistle}, + {u"tomato", colors::tomato}, + {u"turquoise", colors::turquoise}, + {u"violet", colors::violet}, + {u"wheat", colors::wheat}, + {u"whitesmoke", colors::whitesmoke}, + {u"yellowgreen", colors::yellowgreen}, + {u"rebeccapurple", colors::rebeccapurple}, +}; +} // namespace details + +std::optional GetPredefinedColorByName(std::u16string_view name) { + auto result = details::predefined_name_color_map.find(name); + if (result != details::predefined_name_color_map.cend()) { + return result->second; + } else { + return std::nullopt; + } +} +} // namespace cru::platform diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 7d2792d6..c8476acf 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -5,6 +5,7 @@ add_library(cru_ui STATIC host/RoutedEventDispatch.hpp Helper.cpp + ThemeManager.cpp UiManager.cpp components/Component.cpp components/Menu.cpp @@ -45,6 +46,7 @@ add_library(cru_ui STATIC target_sources(cru_ui PUBLIC ${CRU_UI_INCLUDE_DIR}/Base.hpp ${CRU_UI_INCLUDE_DIR}/DebugFlags.hpp + ${CRU_UI_INCLUDE_DIR}/ThemeManager.hpp ${CRU_UI_INCLUDE_DIR}/UiManager.hpp ${CRU_UI_INCLUDE_DIR}/components/Component.hpp ${CRU_UI_INCLUDE_DIR}/components/Menu.hpp diff --git a/src/ui/ThemeManager.cpp b/src/ui/ThemeManager.cpp new file mode 100644 index 00000000..993edc34 --- /dev/null +++ b/src/ui/ThemeManager.cpp @@ -0,0 +1 @@ +#include "cru/ui/ThemeManager.hpp" diff --git a/test/platform/CMakeLists.txt b/test/platform/CMakeLists.txt index 9ad8fb51..9414e2b8 100644 --- a/test/platform/CMakeLists.txt +++ b/test/platform/CMakeLists.txt @@ -1,4 +1,5 @@ add_executable(cru_platform_base_test + ColorTest.cpp MatrixTest.cpp ) target_link_libraries(cru_platform_base_test PRIVATE cru_platform_base cru_test_base) diff --git a/test/platform/ColorTest.cpp b/test/platform/ColorTest.cpp new file mode 100644 index 00000000..c197779b --- /dev/null +++ b/test/platform/ColorTest.cpp @@ -0,0 +1,14 @@ +#include "cru/platform/Color.hpp" + +#include + +using cru::platform::Color; + +TEST(Color, Parse) { + ASSERT_EQ(Color::Parse(u"blue"), Color::Parse(u"#0000ff")); + ASSERT_EQ(Color::Parse(u"#12abAB"), Color::FromHex(0x12abAB)); + ASSERT_EQ(Color::Parse(u"#8812abAB"), Color::FromHexAlpha(0x8812abAB)); + ASSERT_EQ(Color::Parse(u"averystrangestring"), std::nullopt); + ASSERT_EQ(Color::Parse(u"112233"), std::nullopt); + ASSERT_EQ(Color::Parse(u"#7777777"), std::nullopt); +} diff --git a/vcpkg.json b/vcpkg.json index 0e89b26e..4d97e3fb 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -2,5 +2,11 @@ "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json", "name": "cruui", "version": "0.0.1", - "dependencies": ["ms-gsl", "fmt", "gtest"] + "dependencies": [ + "ms-gsl", + "fmt", + "gtest", + "boost-property-tree", + "boost-functional" + ] } -- cgit v1.2.3