From 74bb9cd27242b9320f99ff4d2b50c3051576cc14 Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 8 Feb 2022 16:53:51 +0800 Subject: ... --- include/cru/platform/Base.h | 11 + include/cru/platform/Base.hpp | 11 - include/cru/platform/Check.h | 41 +++ include/cru/platform/Check.hpp | 41 --- include/cru/platform/Color.h | 265 +++++++++++++++++++ include/cru/platform/Color.hpp | 265 ------------------- include/cru/platform/Exception.h | 34 +++ include/cru/platform/Exception.hpp | 34 --- include/cru/platform/GraphicsBase.h | 287 +++++++++++++++++++++ include/cru/platform/GraphicsBase.hpp | 287 --------------------- include/cru/platform/Matrix.h | 110 ++++++++ include/cru/platform/Matrix.hpp | 110 -------- include/cru/platform/Resource.h | 17 ++ include/cru/platform/Resource.hpp | 17 -- include/cru/platform/bootstrap/Bootstrap.h | 17 ++ include/cru/platform/bootstrap/Bootstrap.hpp | 17 -- include/cru/platform/graphics/Base.h | 37 +++ include/cru/platform/graphics/Base.hpp | 37 --- include/cru/platform/graphics/Brush.h | 11 + include/cru/platform/graphics/Brush.hpp | 11 - include/cru/platform/graphics/Factory.h | 32 +++ include/cru/platform/graphics/Factory.hpp | 32 --- include/cru/platform/graphics/Font.h | 8 + include/cru/platform/graphics/Font.hpp | 8 - include/cru/platform/graphics/Geometry.h | 20 ++ include/cru/platform/graphics/Geometry.hpp | 20 -- include/cru/platform/graphics/Image.h | 10 + include/cru/platform/graphics/Image.hpp | 10 - include/cru/platform/graphics/ImageFactory.h | 11 + include/cru/platform/graphics/ImageFactory.hpp | 11 - include/cru/platform/graphics/NullPainter.h | 84 ++++++ include/cru/platform/graphics/NullPainter.hpp | 84 ------ include/cru/platform/graphics/Painter.h | 42 +++ include/cru/platform/graphics/Painter.hpp | 42 --- include/cru/platform/graphics/Resource.h | 10 + include/cru/platform/graphics/Resource.hpp | 10 - include/cru/platform/graphics/TextLayout.h | 33 +++ include/cru/platform/graphics/TextLayout.hpp | 33 --- include/cru/platform/graphics/util/Painter.h | 18 ++ include/cru/platform/graphics/util/Painter.hpp | 18 -- include/cru/platform/gui/Base.h | 37 +++ include/cru/platform/gui/Base.hpp | 37 --- include/cru/platform/gui/Clipboard.h | 9 + include/cru/platform/gui/Clipboard.hpp | 9 - include/cru/platform/gui/Cursor.h | 16 ++ include/cru/platform/gui/Cursor.hpp | 16 -- include/cru/platform/gui/DebugFlags.h | 8 + include/cru/platform/gui/DebugFlags.hpp | 8 - include/cru/platform/gui/InputMethod.h | 55 ++++ include/cru/platform/gui/InputMethod.hpp | 55 ---- include/cru/platform/gui/Keyboard.h | 140 ++++++++++ include/cru/platform/gui/Keyboard.hpp | 140 ---------- include/cru/platform/gui/Menu.h | 32 +++ include/cru/platform/gui/Menu.hpp | 32 --- include/cru/platform/gui/SaveOpenDialogOptions.h | 81 ++++++ include/cru/platform/gui/SaveOpenDialogOptions.hpp | 81 ------ include/cru/platform/gui/TimerHelper.h | 69 +++++ include/cru/platform/gui/TimerHelper.hpp | 69 ----- include/cru/platform/gui/UiApplication.h | 70 +++++ include/cru/platform/gui/UiApplication.hpp | 70 ----- include/cru/platform/gui/Window.h | 112 ++++++++ include/cru/platform/gui/Window.hpp | 112 -------- 62 files changed, 1727 insertions(+), 1727 deletions(-) create mode 100644 include/cru/platform/Base.h delete mode 100644 include/cru/platform/Base.hpp create mode 100644 include/cru/platform/Check.h delete mode 100644 include/cru/platform/Check.hpp create mode 100644 include/cru/platform/Color.h delete mode 100644 include/cru/platform/Color.hpp create mode 100644 include/cru/platform/Exception.h delete mode 100644 include/cru/platform/Exception.hpp create mode 100644 include/cru/platform/GraphicsBase.h delete mode 100644 include/cru/platform/GraphicsBase.hpp create mode 100644 include/cru/platform/Matrix.h delete mode 100644 include/cru/platform/Matrix.hpp create mode 100644 include/cru/platform/Resource.h delete mode 100644 include/cru/platform/Resource.hpp create mode 100644 include/cru/platform/bootstrap/Bootstrap.h delete mode 100644 include/cru/platform/bootstrap/Bootstrap.hpp create mode 100644 include/cru/platform/graphics/Base.h delete mode 100644 include/cru/platform/graphics/Base.hpp create mode 100644 include/cru/platform/graphics/Brush.h delete mode 100644 include/cru/platform/graphics/Brush.hpp create mode 100644 include/cru/platform/graphics/Factory.h delete mode 100644 include/cru/platform/graphics/Factory.hpp create mode 100644 include/cru/platform/graphics/Font.h delete mode 100644 include/cru/platform/graphics/Font.hpp create mode 100644 include/cru/platform/graphics/Geometry.h delete mode 100644 include/cru/platform/graphics/Geometry.hpp create mode 100644 include/cru/platform/graphics/Image.h delete mode 100644 include/cru/platform/graphics/Image.hpp create mode 100644 include/cru/platform/graphics/ImageFactory.h delete mode 100644 include/cru/platform/graphics/ImageFactory.hpp create mode 100644 include/cru/platform/graphics/NullPainter.h delete mode 100644 include/cru/platform/graphics/NullPainter.hpp create mode 100644 include/cru/platform/graphics/Painter.h delete mode 100644 include/cru/platform/graphics/Painter.hpp create mode 100644 include/cru/platform/graphics/Resource.h delete mode 100644 include/cru/platform/graphics/Resource.hpp create mode 100644 include/cru/platform/graphics/TextLayout.h delete mode 100644 include/cru/platform/graphics/TextLayout.hpp create mode 100644 include/cru/platform/graphics/util/Painter.h delete mode 100644 include/cru/platform/graphics/util/Painter.hpp create mode 100644 include/cru/platform/gui/Base.h delete mode 100644 include/cru/platform/gui/Base.hpp create mode 100644 include/cru/platform/gui/Clipboard.h delete mode 100644 include/cru/platform/gui/Clipboard.hpp create mode 100644 include/cru/platform/gui/Cursor.h delete mode 100644 include/cru/platform/gui/Cursor.hpp create mode 100644 include/cru/platform/gui/DebugFlags.h delete mode 100644 include/cru/platform/gui/DebugFlags.hpp create mode 100644 include/cru/platform/gui/InputMethod.h delete mode 100644 include/cru/platform/gui/InputMethod.hpp create mode 100644 include/cru/platform/gui/Keyboard.h delete mode 100644 include/cru/platform/gui/Keyboard.hpp create mode 100644 include/cru/platform/gui/Menu.h delete mode 100644 include/cru/platform/gui/Menu.hpp create mode 100644 include/cru/platform/gui/SaveOpenDialogOptions.h delete mode 100644 include/cru/platform/gui/SaveOpenDialogOptions.hpp create mode 100644 include/cru/platform/gui/TimerHelper.h delete mode 100644 include/cru/platform/gui/TimerHelper.hpp create mode 100644 include/cru/platform/gui/UiApplication.h delete mode 100644 include/cru/platform/gui/UiApplication.hpp create mode 100644 include/cru/platform/gui/Window.h delete mode 100644 include/cru/platform/gui/Window.hpp (limited to 'include/cru/platform') diff --git a/include/cru/platform/Base.h b/include/cru/platform/Base.h new file mode 100644 index 00000000..8589e6cb --- /dev/null +++ b/include/cru/platform/Base.h @@ -0,0 +1,11 @@ +#pragma once + +#ifdef CRU_PLATFORM_WINDOWS +#ifdef CRU_PLATFORM_EXPORT_API +#define CRU_PLATFORM_API __declspec(dllexport) +#else +#define CRU_PLATFORM_API __declspec(dllimport) +#endif +#else +#define CRU_PLATFORM_API +#endif diff --git a/include/cru/platform/Base.hpp b/include/cru/platform/Base.hpp deleted file mode 100644 index 8589e6cb..00000000 --- a/include/cru/platform/Base.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#ifdef CRU_PLATFORM_WINDOWS -#ifdef CRU_PLATFORM_EXPORT_API -#define CRU_PLATFORM_API __declspec(dllexport) -#else -#define CRU_PLATFORM_API __declspec(dllimport) -#endif -#else -#define CRU_PLATFORM_API -#endif diff --git a/include/cru/platform/Check.h b/include/cru/platform/Check.h new file mode 100644 index 00000000..1750c7e8 --- /dev/null +++ b/include/cru/platform/Check.h @@ -0,0 +1,41 @@ +#pragma once +#include "Exception.h" +#include "Resource.h" + +#include "cru/common/String.h" +#include "cru/common/Format.h" + +#include +#include + +namespace cru::platform { +template +TTarget* CheckPlatform(IPlatformResource* resource, + const String& target_platform) { + Expects(resource); + const auto result = dynamic_cast(resource); + if (result == nullptr) { + throw UnsupportPlatformException(Format( + u"Try to convert resource to target platform failed. Platform id of " + "resource to convert: {} . Target platform id: {} .", + resource->GetPlatformId(), target_platform)); + } + return result; +} + +template +std::shared_ptr CheckPlatform(const std::shared_ptr& resource, + const String& target_platform) { + static_assert(std::is_base_of_v, + "TSource must be a subclass of INativeResource."); + Expects(resource); + const auto result = std::dynamic_pointer_cast(resource); + if (result == nullptr) { + throw UnsupportPlatformException(Format( + u"Try to convert resource to target platform failed. Platform id of " + "resource to convert: {} . Target platform id: {} .", + resource->GetPlatformId(), target_platform)); + } + return result; +} +} // namespace cru::platform diff --git a/include/cru/platform/Check.hpp b/include/cru/platform/Check.hpp deleted file mode 100644 index 121e3505..00000000 --- a/include/cru/platform/Check.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once -#include "Exception.hpp" -#include "Resource.hpp" - -#include "cru/common/String.hpp" -#include "cru/common/Format.hpp" - -#include -#include - -namespace cru::platform { -template -TTarget* CheckPlatform(IPlatformResource* resource, - const String& target_platform) { - Expects(resource); - const auto result = dynamic_cast(resource); - if (result == nullptr) { - throw UnsupportPlatformException(Format( - u"Try to convert resource to target platform failed. Platform id of " - "resource to convert: {} . Target platform id: {} .", - resource->GetPlatformId(), target_platform)); - } - return result; -} - -template -std::shared_ptr CheckPlatform(const std::shared_ptr& resource, - const String& target_platform) { - static_assert(std::is_base_of_v, - "TSource must be a subclass of INativeResource."); - Expects(resource); - const auto result = std::dynamic_pointer_cast(resource); - if (result == nullptr) { - throw UnsupportPlatformException(Format( - u"Try to convert resource to target platform failed. Platform id of " - "resource to convert: {} . Target platform id: {} .", - resource->GetPlatformId(), target_platform)); - } - return result; -} -} // namespace cru::platform diff --git a/include/cru/platform/Color.h b/include/cru/platform/Color.h new file mode 100644 index 00000000..4e35ae63 --- /dev/null +++ b/include/cru/platform/Color.h @@ -0,0 +1,265 @@ +#pragma once +#include "cru/common/Base.h" +#include "cru/platform/Base.h" + +#include "cru/common/String.h" +#include "cru/common/Format.h" + +#include +#include +#include +#include + +namespace cru::platform { +struct CRU_PLATFORM_API 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 >> 24) & mask, (hex >> 16) & mask, (hex >> 8) & mask, + hex & mask); + } + + constexpr Color WithAlpha(std::uint8_t new_alpha) const { + auto result = *this; + result.alpha = new_alpha; + return result; + } + + float GetFloatRed() const { return static_cast(red) / 255.f; } + float GetFloatGreen() const { return static_cast(green) / 255.f; } + float GetFloatBlue() const { return static_cast(blue) / 255.f; } + float GetFloatAlpha() const { return static_cast(alpha) / 255.f; } + + String ToString() const; + + std::uint8_t red; + std::uint8_t green; + std::uint8_t blue; + std::uint8_t alpha; + + static std::optional Parse(StringView 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; + cru::hash_combine(seed, color.red); + cru::hash_combine(seed, color.green); + cru::hash_combine(seed, color.blue); + cru::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(StringView name); + +inline String ToString(const Color& color) { + return cru::Format(u"rgba({}, {}, {}, {})", color.red, color.green, + color.blue, color.alpha); +} +} // namespace cru::platform diff --git a/include/cru/platform/Color.hpp b/include/cru/platform/Color.hpp deleted file mode 100644 index cdc6518b..00000000 --- a/include/cru/platform/Color.hpp +++ /dev/null @@ -1,265 +0,0 @@ -#pragma once -#include "cru/common/Base.hpp" -#include "cru/platform/Base.hpp" - -#include "cru/common/String.hpp" -#include "cru/common/Format.hpp" - -#include -#include -#include -#include - -namespace cru::platform { -struct CRU_PLATFORM_API 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 >> 24) & mask, (hex >> 16) & mask, (hex >> 8) & mask, - hex & mask); - } - - constexpr Color WithAlpha(std::uint8_t new_alpha) const { - auto result = *this; - result.alpha = new_alpha; - return result; - } - - float GetFloatRed() const { return static_cast(red) / 255.f; } - float GetFloatGreen() const { return static_cast(green) / 255.f; } - float GetFloatBlue() const { return static_cast(blue) / 255.f; } - float GetFloatAlpha() const { return static_cast(alpha) / 255.f; } - - String ToString() const; - - std::uint8_t red; - std::uint8_t green; - std::uint8_t blue; - std::uint8_t alpha; - - static std::optional Parse(StringView 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; - cru::hash_combine(seed, color.red); - cru::hash_combine(seed, color.green); - cru::hash_combine(seed, color.blue); - cru::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(StringView name); - -inline String ToString(const Color& color) { - return cru::Format(u"rgba({}, {}, {}, {})", color.red, color.green, - color.blue, color.alpha); -} -} // namespace cru::platform diff --git a/include/cru/platform/Exception.h b/include/cru/platform/Exception.h new file mode 100644 index 00000000..7d194d41 --- /dev/null +++ b/include/cru/platform/Exception.h @@ -0,0 +1,34 @@ +#pragma once +#include "Base.h" +#include "cru/common/Base.h" +#include "cru/common/Exception.h" +#include "cru/common/platform/Exception.h" + +namespace cru::platform { +// This exception is thrown when a resource is used on another platform. +// Of course, you can't mix resources of two different platform. +// For example, Win32 Brush (may add in the future) with Direct Painter. +class CRU_PLATFORM_API UnsupportPlatformException : public Exception { + public: + using Exception::Exception; // inherit constructors + + CRU_DEFAULT_COPY(UnsupportPlatformException) + CRU_DEFAULT_MOVE(UnsupportPlatformException) + + CRU_DEFAULT_DESTRUCTOR(UnsupportPlatformException) +}; + +// This exception is thrown when a resource has been disposed and not usable +// again. +// For example, calling Build twice on a GeometryBuilder::Build will lead to +// this exception. +class CRU_PLATFORM_API ReuseException : public Exception { + public: + using Exception::Exception; // inherit constructors + + CRU_DEFAULT_COPY(ReuseException) + CRU_DEFAULT_MOVE(ReuseException) + + CRU_DEFAULT_DESTRUCTOR(ReuseException) +}; +} // namespace cru::platform diff --git a/include/cru/platform/Exception.hpp b/include/cru/platform/Exception.hpp deleted file mode 100644 index b50e8c67..00000000 --- a/include/cru/platform/Exception.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include "Base.hpp" -#include "cru/common/Base.hpp" -#include "cru/common/Exception.hpp" -#include "cru/common/platform/Exception.hpp" - -namespace cru::platform { -// This exception is thrown when a resource is used on another platform. -// Of course, you can't mix resources of two different platform. -// For example, Win32 Brush (may add in the future) with Direct Painter. -class CRU_PLATFORM_API UnsupportPlatformException : public Exception { - public: - using Exception::Exception; // inherit constructors - - CRU_DEFAULT_COPY(UnsupportPlatformException) - CRU_DEFAULT_MOVE(UnsupportPlatformException) - - CRU_DEFAULT_DESTRUCTOR(UnsupportPlatformException) -}; - -// This exception is thrown when a resource has been disposed and not usable -// again. -// For example, calling Build twice on a GeometryBuilder::Build will lead to -// this exception. -class CRU_PLATFORM_API ReuseException : public Exception { - public: - using Exception::Exception; // inherit constructors - - CRU_DEFAULT_COPY(ReuseException) - CRU_DEFAULT_MOVE(ReuseException) - - CRU_DEFAULT_DESTRUCTOR(ReuseException) -}; -} // namespace cru::platform diff --git a/include/cru/platform/GraphicsBase.h b/include/cru/platform/GraphicsBase.h new file mode 100644 index 00000000..8fb9a3af --- /dev/null +++ b/include/cru/platform/GraphicsBase.h @@ -0,0 +1,287 @@ +#pragma once +#include "cru/common/Base.h" + +#include "cru/common/Range.h" +#include "cru/common/String.h" +#include "cru/common/Format.h" + +#include +#include +#include +#include +#include + +namespace cru::platform { +struct Size; + +struct Point final { + constexpr Point() = default; + constexpr Point(const float x, const float y) : x(x), y(y) {} + explicit constexpr Point(const Size& size); + + constexpr Point& operator+=(const Point& other) { + this->x += other.x; + this->y += other.y; + return *this; + } + + float x = 0; + float y = 0; +}; + +constexpr Point operator+(const Point& left, const Point& right) { + return Point(left.x + right.x, left.y + right.y); +} + +constexpr Point operator-(const Point& left, const Point& right) { + return Point(left.x - right.x, left.y - right.y); +} + +constexpr bool operator==(const Point& left, const Point& right) { + return left.x == right.x && left.y == right.y; +} + +constexpr bool operator!=(const Point& left, const Point& right) { + return !(left == right); +} + +inline String ToString(const Point& point) { + return Format(u"(x: {}, y: {})", point.x, point.y); +} + +struct Size final { + constexpr Size() = default; + constexpr Size(const float width, const float height) + : width(width), height(height) {} + explicit constexpr Size(const Point& point) + : width(point.x), height(point.y) {} + + constexpr static Size Infinate() { + return Size{std::numeric_limits::max(), + std::numeric_limits::max()}; + } + + float width = 0; + float height = 0; +}; + +constexpr Point::Point(const Size& size) : x(size.width), y(size.height) {} + +constexpr Size operator+(const Size& left, const Size& right) { + return Size(left.width + right.width, left.height + right.height); +} + +constexpr Size operator-(const Size& left, const Size& right) { + return Size(left.width - right.width, left.height - right.height); +} + +constexpr bool operator==(const Size& left, const Size& right) { + return left.width == right.width && left.height == right.height; +} + +constexpr bool operator!=(const Size& left, const Size& right) { + return !(left == right); +} + +inline String ToString(const Size& size) { + return Format(u"(width: {}, height: {})", size.width, size.height); +} + +struct Thickness final { + constexpr Thickness() : Thickness(0) {} + + constexpr explicit Thickness(const float width) + : left(width), top(width), right(width), bottom(width) {} + + constexpr explicit Thickness(const float horizontal, const float vertical) + : left(horizontal), top(vertical), right(horizontal), bottom(vertical) {} + + constexpr Thickness(const float left, const float top, const float right, + const float bottom) + : left(left), top(top), right(right), bottom(bottom) {} + + constexpr float GetHorizontalTotal() const { return left + right; } + + constexpr float GetVerticalTotal() const { return top + bottom; } + + void SetLeftRight(const float value) { left = right = value; } + + void SetTopBottom(const float value) { top = bottom = value; } + + void SetAll(const float value) { left = top = right = bottom = value; } + + constexpr float Validate() const { + return left >= 0.0 && top >= 0.0 && right >= 0.0 && bottom >= 0.0; + } + + float left; + float top; + float right; + float bottom; +}; + +constexpr Size operator+(const Size& size, const Thickness& thickness) { + return {size.width + thickness.left + thickness.right, + size.height + thickness.top + thickness.bottom}; +} + +constexpr Size operator+(const Thickness& thickness, const Size& size) { + return operator+(size, thickness); +} + +constexpr Thickness operator+(const Thickness& left, const Thickness& right) { + return {left.left + right.left, left.top + right.top, + left.right + right.right, left.bottom + right.bottom}; +} + +constexpr bool operator==(const Thickness& left, const Thickness& right) { + return left.left == right.left && left.top == right.top && + left.right == right.right && left.bottom == right.bottom; +} + +constexpr bool operator!=(const Thickness& left, const Thickness& right) { + return !(left == right); +} + +struct Rect final { + constexpr Rect() = default; + constexpr Rect(const float left, const float top, const float width, + const float height) + : left(left), top(top), width(width), height(height) {} + constexpr Rect(const Point& lefttop, const Size& size) + : left(lefttop.x), + top(lefttop.y), + width(size.width), + height(size.height) {} + + constexpr static Rect FromVertices(const float left, const float top, + const float right, const float bottom) { + return Rect(left, top, right - left, bottom - top); + } + + constexpr static Rect FromCenter(const Point& center, const float width, + const float height) { + return Rect(center.x - width / 2.0f, center.y - height / 2.0f, width, + height); + } + + constexpr float GetRight() const { return left + width; } + + constexpr float GetBottom() const { return top + height; } + + constexpr Point GetLeftTop() const { return Point(left, top); } + + constexpr Point GetRightBottom() const { + return Point(left + width, top + height); + } + + constexpr Point GetLeftBottom() const { return Point(left, top + height); } + + constexpr Point GetRightTop() const { return Point(left + width, top); } + + constexpr Point GetCenter() const { + return Point(left + width / 2.0f, top + height / 2.0f); + } + + constexpr void SetSize(const Size& size) { + width = size.width; + height = size.height; + } + + constexpr Size GetSize() const { return Size(width, height); } + + constexpr Rect Expand(const Thickness& thickness) const { + return Rect(left - thickness.left, top - thickness.top, + width + thickness.GetHorizontalTotal(), + height + thickness.GetVerticalTotal()); + } + + constexpr Rect Shrink(const Thickness& thickness) const { + return Rect(left + thickness.left, top + thickness.top, + width - thickness.GetHorizontalTotal(), + height - thickness.GetVerticalTotal()); + } + + constexpr bool IsPointInside(const Point& point) const { + return point.x >= left && point.x < GetRight() && point.y >= top && + point.y < GetBottom(); + } + + constexpr Rect Normalize() const { + Rect result = *this; + if (result.width < 0) { + result.left += result.width; + result.width = -result.width; + } + if (result.height < 0) { + result.top += result.height; + result.height = -result.height; + } + return result; + } + + float left = 0.0f; + float top = 0.0f; + float width = 0.0f; + float height = 0.0f; +}; + +constexpr bool operator==(const Rect& left, const Rect& right) { + return left.left == right.left && left.top == right.top && + left.width == right.width && left.height == right.height; +} + +constexpr bool operator!=(const Rect& left, const Rect& right) { + return !(left == right); +} + +struct RoundedRect final { + constexpr RoundedRect() = default; + constexpr RoundedRect(const Rect& rect, const float radius_x, + const float radius_y) + : rect(rect), radius_x(radius_x), radius_y(radius_y) {} + + Rect rect{}; + float radius_x = 0.0f; + float radius_y = 0.0f; +}; + +constexpr bool operator==(const RoundedRect& left, const RoundedRect& right) { + return left.rect == right.rect && left.radius_x == right.radius_x && + left.radius_y == right.radius_y; +} + +constexpr bool operator!=(const RoundedRect& left, const RoundedRect& right) { + return !(left == right); +} + +struct Ellipse final { + constexpr Ellipse() = default; + constexpr Ellipse(const Point& center, const float radius_x, + const float radius_y) + : center(center), radius_x(radius_x), radius_y(radius_y) {} + + constexpr static Ellipse FromRect(const Rect& rect) { + return Ellipse(rect.GetCenter(), rect.width / 2.0f, rect.height / 2.0f); + } + + constexpr Rect GetBoundRect() const { + return Rect::FromCenter(center, radius_x * 2.0f, radius_y * 2.0f); + } + + Point center{}; + float radius_x = 0.0f; + float radius_y = 0.0f; +}; + +constexpr bool operator==(const Ellipse& left, const Ellipse& right) { + return left.center == right.center && left.radius_x == right.radius_x && + left.radius_y == right.radius_y; +} + +constexpr bool operator!=(const Ellipse& left, const Ellipse& right) { + return !(left == right); +} + +using TextRange = Range; +} // namespace cru::platform diff --git a/include/cru/platform/GraphicsBase.hpp b/include/cru/platform/GraphicsBase.hpp deleted file mode 100644 index 088086e9..00000000 --- a/include/cru/platform/GraphicsBase.hpp +++ /dev/null @@ -1,287 +0,0 @@ -#pragma once -#include "cru/common/Base.hpp" - -#include "cru/common/Range.hpp" -#include "cru/common/String.hpp" -#include "cru/common/Format.hpp" - -#include -#include -#include -#include -#include - -namespace cru::platform { -struct Size; - -struct Point final { - constexpr Point() = default; - constexpr Point(const float x, const float y) : x(x), y(y) {} - explicit constexpr Point(const Size& size); - - constexpr Point& operator+=(const Point& other) { - this->x += other.x; - this->y += other.y; - return *this; - } - - float x = 0; - float y = 0; -}; - -constexpr Point operator+(const Point& left, const Point& right) { - return Point(left.x + right.x, left.y + right.y); -} - -constexpr Point operator-(const Point& left, const Point& right) { - return Point(left.x - right.x, left.y - right.y); -} - -constexpr bool operator==(const Point& left, const Point& right) { - return left.x == right.x && left.y == right.y; -} - -constexpr bool operator!=(const Point& left, const Point& right) { - return !(left == right); -} - -inline String ToString(const Point& point) { - return Format(u"(x: {}, y: {})", point.x, point.y); -} - -struct Size final { - constexpr Size() = default; - constexpr Size(const float width, const float height) - : width(width), height(height) {} - explicit constexpr Size(const Point& point) - : width(point.x), height(point.y) {} - - constexpr static Size Infinate() { - return Size{std::numeric_limits::max(), - std::numeric_limits::max()}; - } - - float width = 0; - float height = 0; -}; - -constexpr Point::Point(const Size& size) : x(size.width), y(size.height) {} - -constexpr Size operator+(const Size& left, const Size& right) { - return Size(left.width + right.width, left.height + right.height); -} - -constexpr Size operator-(const Size& left, const Size& right) { - return Size(left.width - right.width, left.height - right.height); -} - -constexpr bool operator==(const Size& left, const Size& right) { - return left.width == right.width && left.height == right.height; -} - -constexpr bool operator!=(const Size& left, const Size& right) { - return !(left == right); -} - -inline String ToString(const Size& size) { - return Format(u"(width: {}, height: {})", size.width, size.height); -} - -struct Thickness final { - constexpr Thickness() : Thickness(0) {} - - constexpr explicit Thickness(const float width) - : left(width), top(width), right(width), bottom(width) {} - - constexpr explicit Thickness(const float horizontal, const float vertical) - : left(horizontal), top(vertical), right(horizontal), bottom(vertical) {} - - constexpr Thickness(const float left, const float top, const float right, - const float bottom) - : left(left), top(top), right(right), bottom(bottom) {} - - constexpr float GetHorizontalTotal() const { return left + right; } - - constexpr float GetVerticalTotal() const { return top + bottom; } - - void SetLeftRight(const float value) { left = right = value; } - - void SetTopBottom(const float value) { top = bottom = value; } - - void SetAll(const float value) { left = top = right = bottom = value; } - - constexpr float Validate() const { - return left >= 0.0 && top >= 0.0 && right >= 0.0 && bottom >= 0.0; - } - - float left; - float top; - float right; - float bottom; -}; - -constexpr Size operator+(const Size& size, const Thickness& thickness) { - return {size.width + thickness.left + thickness.right, - size.height + thickness.top + thickness.bottom}; -} - -constexpr Size operator+(const Thickness& thickness, const Size& size) { - return operator+(size, thickness); -} - -constexpr Thickness operator+(const Thickness& left, const Thickness& right) { - return {left.left + right.left, left.top + right.top, - left.right + right.right, left.bottom + right.bottom}; -} - -constexpr bool operator==(const Thickness& left, const Thickness& right) { - return left.left == right.left && left.top == right.top && - left.right == right.right && left.bottom == right.bottom; -} - -constexpr bool operator!=(const Thickness& left, const Thickness& right) { - return !(left == right); -} - -struct Rect final { - constexpr Rect() = default; - constexpr Rect(const float left, const float top, const float width, - const float height) - : left(left), top(top), width(width), height(height) {} - constexpr Rect(const Point& lefttop, const Size& size) - : left(lefttop.x), - top(lefttop.y), - width(size.width), - height(size.height) {} - - constexpr static Rect FromVertices(const float left, const float top, - const float right, const float bottom) { - return Rect(left, top, right - left, bottom - top); - } - - constexpr static Rect FromCenter(const Point& center, const float width, - const float height) { - return Rect(center.x - width / 2.0f, center.y - height / 2.0f, width, - height); - } - - constexpr float GetRight() const { return left + width; } - - constexpr float GetBottom() const { return top + height; } - - constexpr Point GetLeftTop() const { return Point(left, top); } - - constexpr Point GetRightBottom() const { - return Point(left + width, top + height); - } - - constexpr Point GetLeftBottom() const { return Point(left, top + height); } - - constexpr Point GetRightTop() const { return Point(left + width, top); } - - constexpr Point GetCenter() const { - return Point(left + width / 2.0f, top + height / 2.0f); - } - - constexpr void SetSize(const Size& size) { - width = size.width; - height = size.height; - } - - constexpr Size GetSize() const { return Size(width, height); } - - constexpr Rect Expand(const Thickness& thickness) const { - return Rect(left - thickness.left, top - thickness.top, - width + thickness.GetHorizontalTotal(), - height + thickness.GetVerticalTotal()); - } - - constexpr Rect Shrink(const Thickness& thickness) const { - return Rect(left + thickness.left, top + thickness.top, - width - thickness.GetHorizontalTotal(), - height - thickness.GetVerticalTotal()); - } - - constexpr bool IsPointInside(const Point& point) const { - return point.x >= left && point.x < GetRight() && point.y >= top && - point.y < GetBottom(); - } - - constexpr Rect Normalize() const { - Rect result = *this; - if (result.width < 0) { - result.left += result.width; - result.width = -result.width; - } - if (result.height < 0) { - result.top += result.height; - result.height = -result.height; - } - return result; - } - - float left = 0.0f; - float top = 0.0f; - float width = 0.0f; - float height = 0.0f; -}; - -constexpr bool operator==(const Rect& left, const Rect& right) { - return left.left == right.left && left.top == right.top && - left.width == right.width && left.height == right.height; -} - -constexpr bool operator!=(const Rect& left, const Rect& right) { - return !(left == right); -} - -struct RoundedRect final { - constexpr RoundedRect() = default; - constexpr RoundedRect(const Rect& rect, const float radius_x, - const float radius_y) - : rect(rect), radius_x(radius_x), radius_y(radius_y) {} - - Rect rect{}; - float radius_x = 0.0f; - float radius_y = 0.0f; -}; - -constexpr bool operator==(const RoundedRect& left, const RoundedRect& right) { - return left.rect == right.rect && left.radius_x == right.radius_x && - left.radius_y == right.radius_y; -} - -constexpr bool operator!=(const RoundedRect& left, const RoundedRect& right) { - return !(left == right); -} - -struct Ellipse final { - constexpr Ellipse() = default; - constexpr Ellipse(const Point& center, const float radius_x, - const float radius_y) - : center(center), radius_x(radius_x), radius_y(radius_y) {} - - constexpr static Ellipse FromRect(const Rect& rect) { - return Ellipse(rect.GetCenter(), rect.width / 2.0f, rect.height / 2.0f); - } - - constexpr Rect GetBoundRect() const { - return Rect::FromCenter(center, radius_x * 2.0f, radius_y * 2.0f); - } - - Point center{}; - float radius_x = 0.0f; - float radius_y = 0.0f; -}; - -constexpr bool operator==(const Ellipse& left, const Ellipse& right) { - return left.center == right.center && left.radius_x == right.radius_x && - left.radius_y == right.radius_y; -} - -constexpr bool operator!=(const Ellipse& left, const Ellipse& right) { - return !(left == right); -} - -using TextRange = Range; -} // namespace cru::platform diff --git a/include/cru/platform/Matrix.h b/include/cru/platform/Matrix.h new file mode 100644 index 00000000..c9a52158 --- /dev/null +++ b/include/cru/platform/Matrix.h @@ -0,0 +1,110 @@ +#pragma once +#include "GraphicsBase.h" + +#include +#include + +namespace cru::platform { +struct Matrix { + float m11; + float m12; + float m21; + float m22; + float m31; + float m32; + + Matrix() {} + + Matrix(float m11, float m12, float m21, float m22, float m31, float m32) { + this->m11 = m11; + this->m12 = m12; + this->m21 = m21; + this->m22 = m22; + this->m31 = m31; + this->m32 = m32; + } + + bool IsIdentity() const { + return m11 == 1.0f && m12 == 0.0f && m21 == 0.0f && m22 == 1.0f && + m31 == 0.0f && m32 == 0.0f; + } + + Matrix& operator*=(const Matrix& matrix) { + *this = Product(*this, matrix); + return *this; + } + + Matrix operator*(const Matrix& matrix) const { + return Product(*this, matrix); + } + + Point TransformPoint(const Point& point) const { + return Point{point.x * m11 + point.y * m21 + m31, + point.x * m12 + point.y * m22 + m32}; + } + + Rect TransformRect(const Rect& rect, bool normalize = true) const { + Point lefttop = TransformPoint(rect.GetLeftTop()), + rightbottom = TransformPoint(rect.GetRightBottom()); + auto result = + Rect::FromVertices(lefttop.x, lefttop.y, rightbottom.x, rightbottom.y); + if (normalize) result = result.Normalize(); + return result; + } + + static Matrix Identity() { + return Matrix{1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}; + } + + static Matrix Translation(float x, float y) { + return Matrix{1.0f, 0.0f, 0.0f, 1.0f, x, y}; + } + + static Matrix Translation(const Point& point) { + return Translation(point.x, point.y); + } + + static Matrix Scale(float sx, float sy) { + return Matrix{sx, 0.0f, 0.0f, sy, 0.0f, 0.0f}; + } + + // Clockwise. + static Matrix Rotation(float angle) { + float r = AngleToRadian(angle); + float s = std::sin(r); + float c = std::cos(r); + + return Matrix{c, s, -s, c, 0.0f, 0.0f}; + } + + static Matrix Skew(float sx, float sy) { + return Matrix{1.0f, sx, sy, 1.0f, 0.0f, 0.0f}; + } + + static Matrix Product(const Matrix& a, const Matrix& b) { + return Matrix{a.m11 * b.m11 + a.m12 * b.m21, + a.m11 * b.m12 + a.m12 * b.m22, + a.m21 * b.m11 + a.m22 * b.m21, + a.m21 * b.m12 + a.m22 * b.m22, + a.m31 * b.m11 + a.m32 * b.m21 + b.m31, + a.m31 * b.m12 + a.m32 * b.m22 + b.m32}; + } + + std::optional Inverted() const { + if (m11 * m22 == m12 * m21) return std::nullopt; + Matrix result; + result.m11 = m22 / (m11 * m22 - m12 * m21); + result.m12 = m12 / (m12 * m21 - m11 * m22); + result.m21 = m21 / (m12 * m21 - m11 * m22); + result.m22 = m11 / (m11 * m22 - m12 * m21); + result.m31 = (m21 * m32 - m22 * m31) / (m11 * m22 - m12 * m21); + result.m32 = (m31 * m12 - m11 * m32) / (m11 * m22 - m12 * m21); + return result; + } + + private: + static constexpr float PI = 3.1415926535f; + + static float AngleToRadian(float angle) { return angle / 180.f * PI; } +}; +} // namespace cru::platform diff --git a/include/cru/platform/Matrix.hpp b/include/cru/platform/Matrix.hpp deleted file mode 100644 index 47917d47..00000000 --- a/include/cru/platform/Matrix.hpp +++ /dev/null @@ -1,110 +0,0 @@ -#pragma once -#include "GraphicsBase.hpp" - -#include -#include - -namespace cru::platform { -struct Matrix { - float m11; - float m12; - float m21; - float m22; - float m31; - float m32; - - Matrix() {} - - Matrix(float m11, float m12, float m21, float m22, float m31, float m32) { - this->m11 = m11; - this->m12 = m12; - this->m21 = m21; - this->m22 = m22; - this->m31 = m31; - this->m32 = m32; - } - - bool IsIdentity() const { - return m11 == 1.0f && m12 == 0.0f && m21 == 0.0f && m22 == 1.0f && - m31 == 0.0f && m32 == 0.0f; - } - - Matrix& operator*=(const Matrix& matrix) { - *this = Product(*this, matrix); - return *this; - } - - Matrix operator*(const Matrix& matrix) const { - return Product(*this, matrix); - } - - Point TransformPoint(const Point& point) const { - return Point{point.x * m11 + point.y * m21 + m31, - point.x * m12 + point.y * m22 + m32}; - } - - Rect TransformRect(const Rect& rect, bool normalize = true) const { - Point lefttop = TransformPoint(rect.GetLeftTop()), - rightbottom = TransformPoint(rect.GetRightBottom()); - auto result = - Rect::FromVertices(lefttop.x, lefttop.y, rightbottom.x, rightbottom.y); - if (normalize) result = result.Normalize(); - return result; - } - - static Matrix Identity() { - return Matrix{1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}; - } - - static Matrix Translation(float x, float y) { - return Matrix{1.0f, 0.0f, 0.0f, 1.0f, x, y}; - } - - static Matrix Translation(const Point& point) { - return Translation(point.x, point.y); - } - - static Matrix Scale(float sx, float sy) { - return Matrix{sx, 0.0f, 0.0f, sy, 0.0f, 0.0f}; - } - - // Clockwise. - static Matrix Rotation(float angle) { - float r = AngleToRadian(angle); - float s = std::sin(r); - float c = std::cos(r); - - return Matrix{c, s, -s, c, 0.0f, 0.0f}; - } - - static Matrix Skew(float sx, float sy) { - return Matrix{1.0f, sx, sy, 1.0f, 0.0f, 0.0f}; - } - - static Matrix Product(const Matrix& a, const Matrix& b) { - return Matrix{a.m11 * b.m11 + a.m12 * b.m21, - a.m11 * b.m12 + a.m12 * b.m22, - a.m21 * b.m11 + a.m22 * b.m21, - a.m21 * b.m12 + a.m22 * b.m22, - a.m31 * b.m11 + a.m32 * b.m21 + b.m31, - a.m31 * b.m12 + a.m32 * b.m22 + b.m32}; - } - - std::optional Inverted() const { - if (m11 * m22 == m12 * m21) return std::nullopt; - Matrix result; - result.m11 = m22 / (m11 * m22 - m12 * m21); - result.m12 = m12 / (m12 * m21 - m11 * m22); - result.m21 = m21 / (m12 * m21 - m11 * m22); - result.m22 = m11 / (m11 * m22 - m12 * m21); - result.m31 = (m21 * m32 - m22 * m31) / (m11 * m22 - m12 * m21); - result.m32 = (m31 * m12 - m11 * m32) / (m11 * m22 - m12 * m21); - return result; - } - - private: - static constexpr float PI = 3.1415926535f; - - static float AngleToRadian(float angle) { return angle / 180.f * PI; } -}; -} // namespace cru::platform diff --git a/include/cru/platform/Resource.h b/include/cru/platform/Resource.h new file mode 100644 index 00000000..fe95ebb3 --- /dev/null +++ b/include/cru/platform/Resource.h @@ -0,0 +1,17 @@ +#pragma once +#include "Base.h" + +#include "cru/common/Base.h" +#include "cru/common/String.h" + +#include + +namespace cru::platform { +struct CRU_PLATFORM_API IPlatformResource : virtual Interface { + CRU_DEFAULT_CONSTRUCTOR_DESTRUCTOR(IPlatformResource) + + virtual String GetPlatformId() const = 0; + + virtual String GetDebugString() { return String(); } +}; +} // namespace cru::platform diff --git a/include/cru/platform/Resource.hpp b/include/cru/platform/Resource.hpp deleted file mode 100644 index c89068fa..00000000 --- a/include/cru/platform/Resource.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "Base.hpp" - -#include "cru/common/Base.hpp" -#include "cru/common/String.hpp" - -#include - -namespace cru::platform { -struct CRU_PLATFORM_API IPlatformResource : virtual Interface { - CRU_DEFAULT_CONSTRUCTOR_DESTRUCTOR(IPlatformResource) - - virtual String GetPlatformId() const = 0; - - virtual String GetDebugString() { return String(); } -}; -} // namespace cru::platform diff --git a/include/cru/platform/bootstrap/Bootstrap.h b/include/cru/platform/bootstrap/Bootstrap.h new file mode 100644 index 00000000..3ab89a91 --- /dev/null +++ b/include/cru/platform/bootstrap/Bootstrap.h @@ -0,0 +1,17 @@ +#pragma once +#include "cru/platform/gui/UiApplication.h" + +#ifdef CRU_PLATFORM_WINDOWS +#ifdef CRU_PLATFORM_BOOTSTRAP_EXPORT_API +#define CRU_PLATFORM_BOOTSTRAP_API __declspec(dllexport) +#else +#define CRU_PLATFORM_BOOTSTRAP_API __declspec(dllimport) +#endif +#else +#define CRU_PLATFORM_BOOTSTRAP_API +#endif + +namespace cru::platform::bootstrap { +CRU_PLATFORM_BOOTSTRAP_API cru::platform::gui::IUiApplication* +CreateUiApplication(); +} diff --git a/include/cru/platform/bootstrap/Bootstrap.hpp b/include/cru/platform/bootstrap/Bootstrap.hpp deleted file mode 100644 index 33fb5122..00000000 --- a/include/cru/platform/bootstrap/Bootstrap.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "cru/platform/gui/UiApplication.hpp" - -#ifdef CRU_PLATFORM_WINDOWS -#ifdef CRU_PLATFORM_BOOTSTRAP_EXPORT_API -#define CRU_PLATFORM_BOOTSTRAP_API __declspec(dllexport) -#else -#define CRU_PLATFORM_BOOTSTRAP_API __declspec(dllimport) -#endif -#else -#define CRU_PLATFORM_BOOTSTRAP_API -#endif - -namespace cru::platform::bootstrap { -CRU_PLATFORM_BOOTSTRAP_API cru::platform::gui::IUiApplication* -CreateUiApplication(); -} diff --git a/include/cru/platform/graphics/Base.h b/include/cru/platform/graphics/Base.h new file mode 100644 index 00000000..a134fb33 --- /dev/null +++ b/include/cru/platform/graphics/Base.h @@ -0,0 +1,37 @@ +#pragma once +#include "../Color.h" +#include "../GraphicsBase.h" +#include "../Matrix.h" +#include "../Resource.h" + +#include + +#ifdef CRU_PLATFORM_WINDOWS +#ifdef CRU_PLATFORM_GRAPHICS_EXPORT_API +#define CRU_PLATFORM_GRAPHICS_API __declspec(dllexport) +#else +#define CRU_PLATFORM_GRAPHICS_API __declspec(dllimport) +#endif +#else +#define CRU_PLATFORM_GRAPHICS_API +#endif + +namespace cru::platform::graphics { +// forward declarations +struct IGraphicsFactory; +struct IBrush; +struct ISolidColorBrush; +struct IFont; +struct IGeometry; +struct IGeometryBuilder; +struct IImage; +struct IImageFactory; +struct IPainter; +struct ITextLayout; + +struct TextHitTestResult { + gsl::index position; + bool trailing; + bool inside_text; +}; +} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Base.hpp b/include/cru/platform/graphics/Base.hpp deleted file mode 100644 index 416f0df4..00000000 --- a/include/cru/platform/graphics/Base.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include "../Color.hpp" -#include "../GraphicsBase.hpp" -#include "../Matrix.hpp" -#include "../Resource.hpp" - -#include - -#ifdef CRU_PLATFORM_WINDOWS -#ifdef CRU_PLATFORM_GRAPHICS_EXPORT_API -#define CRU_PLATFORM_GRAPHICS_API __declspec(dllexport) -#else -#define CRU_PLATFORM_GRAPHICS_API __declspec(dllimport) -#endif -#else -#define CRU_PLATFORM_GRAPHICS_API -#endif - -namespace cru::platform::graphics { -// forward declarations -struct IGraphicsFactory; -struct IBrush; -struct ISolidColorBrush; -struct IFont; -struct IGeometry; -struct IGeometryBuilder; -struct IImage; -struct IImageFactory; -struct IPainter; -struct ITextLayout; - -struct TextHitTestResult { - gsl::index position; - bool trailing; - bool inside_text; -}; -} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Brush.h b/include/cru/platform/graphics/Brush.h new file mode 100644 index 00000000..6f4a6902 --- /dev/null +++ b/include/cru/platform/graphics/Brush.h @@ -0,0 +1,11 @@ +#pragma once +#include "Resource.h" + +namespace cru::platform::graphics { +struct CRU_PLATFORM_GRAPHICS_API IBrush : virtual IGraphicsResource {}; + +struct CRU_PLATFORM_GRAPHICS_API ISolidColorBrush : virtual IBrush { + virtual Color GetColor() = 0; + virtual void SetColor(const Color& color) = 0; +}; +} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Brush.hpp b/include/cru/platform/graphics/Brush.hpp deleted file mode 100644 index 772edd5c..00000000 --- a/include/cru/platform/graphics/Brush.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include "Resource.hpp" - -namespace cru::platform::graphics { -struct CRU_PLATFORM_GRAPHICS_API IBrush : virtual IGraphicsResource {}; - -struct CRU_PLATFORM_GRAPHICS_API ISolidColorBrush : virtual IBrush { - virtual Color GetColor() = 0; - virtual void SetColor(const Color& color) = 0; -}; -} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Factory.h b/include/cru/platform/graphics/Factory.h new file mode 100644 index 00000000..d197d821 --- /dev/null +++ b/include/cru/platform/graphics/Factory.h @@ -0,0 +1,32 @@ +#pragma once +#include "Resource.h" + +#include "Brush.h" +#include "Font.h" +#include "Geometry.h" +#include "Image.h" +#include "ImageFactory.h" +#include "TextLayout.h" + +namespace cru::platform::graphics { +// Entry point of the graphics module. +struct CRU_PLATFORM_GRAPHICS_API IGraphicsFactory : virtual IPlatformResource { + virtual std::unique_ptr CreateSolidColorBrush() = 0; + + virtual std::unique_ptr CreateGeometryBuilder() = 0; + + virtual std::unique_ptr CreateFont(String font_family, + float font_size) = 0; + + virtual std::unique_ptr CreateTextLayout( + std::shared_ptr font, String text) = 0; + + std::unique_ptr CreateSolidColorBrush(const Color& color) { + std::unique_ptr brush = CreateSolidColorBrush(); + brush->SetColor(color); + return brush; + } + + virtual IImageFactory* GetImageFactory() = 0; +}; +} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Factory.hpp b/include/cru/platform/graphics/Factory.hpp deleted file mode 100644 index 7aa88ebd..00000000 --- a/include/cru/platform/graphics/Factory.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#include "Resource.hpp" - -#include "Brush.hpp" -#include "Font.hpp" -#include "Geometry.hpp" -#include "Image.hpp" -#include "ImageFactory.hpp" -#include "TextLayout.hpp" - -namespace cru::platform::graphics { -// Entry point of the graphics module. -struct CRU_PLATFORM_GRAPHICS_API IGraphicsFactory : virtual IPlatformResource { - virtual std::unique_ptr CreateSolidColorBrush() = 0; - - virtual std::unique_ptr CreateGeometryBuilder() = 0; - - virtual std::unique_ptr CreateFont(String font_family, - float font_size) = 0; - - virtual std::unique_ptr CreateTextLayout( - std::shared_ptr font, String text) = 0; - - std::unique_ptr CreateSolidColorBrush(const Color& color) { - std::unique_ptr brush = CreateSolidColorBrush(); - brush->SetColor(color); - return brush; - } - - virtual IImageFactory* GetImageFactory() = 0; -}; -} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Font.h b/include/cru/platform/graphics/Font.h new file mode 100644 index 00000000..24c35f7c --- /dev/null +++ b/include/cru/platform/graphics/Font.h @@ -0,0 +1,8 @@ +#pragma once +#include "Resource.h" + +namespace cru::platform::graphics { +struct CRU_PLATFORM_GRAPHICS_API IFont : virtual IGraphicsResource { + virtual float GetFontSize() = 0; +}; +} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Font.hpp b/include/cru/platform/graphics/Font.hpp deleted file mode 100644 index 2d1bc9a6..00000000 --- a/include/cru/platform/graphics/Font.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include "Resource.hpp" - -namespace cru::platform::graphics { -struct CRU_PLATFORM_GRAPHICS_API IFont : virtual IGraphicsResource { - virtual float GetFontSize() = 0; -}; -} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Geometry.h b/include/cru/platform/graphics/Geometry.h new file mode 100644 index 00000000..732fc547 --- /dev/null +++ b/include/cru/platform/graphics/Geometry.h @@ -0,0 +1,20 @@ +#pragma once +#include "Resource.h" + +namespace cru::platform::graphics { +struct CRU_PLATFORM_GRAPHICS_API IGeometry : virtual IGraphicsResource { + virtual bool FillContains(const Point& point) = 0; +}; + +// After called Build, calling every method will throw a + +struct CRU_PLATFORM_GRAPHICS_API IGeometryBuilder : virtual IGraphicsResource { + virtual void BeginFigure(const Point& point) = 0; + virtual void LineTo(const Point& point) = 0; + virtual void QuadraticBezierTo(const Point& control_point, + const Point& end_point) = 0; + virtual void CloseFigure(bool close) = 0; + + virtual std::unique_ptr Build() = 0; +}; +} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Geometry.hpp b/include/cru/platform/graphics/Geometry.hpp deleted file mode 100644 index e83d1c51..00000000 --- a/include/cru/platform/graphics/Geometry.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -#include "Resource.hpp" - -namespace cru::platform::graphics { -struct CRU_PLATFORM_GRAPHICS_API IGeometry : virtual IGraphicsResource { - virtual bool FillContains(const Point& point) = 0; -}; - -// After called Build, calling every method will throw a - -struct CRU_PLATFORM_GRAPHICS_API IGeometryBuilder : virtual IGraphicsResource { - virtual void BeginFigure(const Point& point) = 0; - virtual void LineTo(const Point& point) = 0; - virtual void QuadraticBezierTo(const Point& control_point, - const Point& end_point) = 0; - virtual void CloseFigure(bool close) = 0; - - virtual std::unique_ptr Build() = 0; -}; -} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Image.h b/include/cru/platform/graphics/Image.h new file mode 100644 index 00000000..51e27678 --- /dev/null +++ b/include/cru/platform/graphics/Image.h @@ -0,0 +1,10 @@ +#pragma once +#include "Resource.h" + +namespace cru::platform::graphics { +struct CRU_PLATFORM_GRAPHICS_API IImage : public virtual IGraphicsResource { + virtual float GetWidth() = 0; + virtual float GetHeight() = 0; + virtual std::unique_ptr CreateWithRect(const Rect& rect) = 0; +}; +} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Image.hpp b/include/cru/platform/graphics/Image.hpp deleted file mode 100644 index e8bf6671..00000000 --- a/include/cru/platform/graphics/Image.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "Resource.hpp" - -namespace cru::platform::graphics { -struct CRU_PLATFORM_GRAPHICS_API IImage : public virtual IGraphicsResource { - virtual float GetWidth() = 0; - virtual float GetHeight() = 0; - virtual std::unique_ptr CreateWithRect(const Rect& rect) = 0; -}; -} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/ImageFactory.h b/include/cru/platform/graphics/ImageFactory.h new file mode 100644 index 00000000..2a7902b2 --- /dev/null +++ b/include/cru/platform/graphics/ImageFactory.h @@ -0,0 +1,11 @@ +#pragma once +#include "Image.h" +#include "Resource.h" +#include "cru/common/io/Stream.h" + +namespace cru::platform::graphics { +struct CRU_PLATFORM_GRAPHICS_API IImageFactory + : public virtual IGraphicsResource { + virtual std::unique_ptr DecodeFromStream(io::Stream* stream) = 0; +}; +} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/ImageFactory.hpp b/include/cru/platform/graphics/ImageFactory.hpp deleted file mode 100644 index 3997f783..00000000 --- a/include/cru/platform/graphics/ImageFactory.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include "Image.hpp" -#include "Resource.hpp" -#include "cru/common/io/Stream.hpp" - -namespace cru::platform::graphics { -struct CRU_PLATFORM_GRAPHICS_API IImageFactory - : public virtual IGraphicsResource { - virtual std::unique_ptr DecodeFromStream(io::Stream* stream) = 0; -}; -} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/NullPainter.h b/include/cru/platform/graphics/NullPainter.h new file mode 100644 index 00000000..2c6e6cb1 --- /dev/null +++ b/include/cru/platform/graphics/NullPainter.h @@ -0,0 +1,84 @@ +#pragma once +#include "Painter.h" +#include "cru/common/Base.h" + +namespace cru::platform::graphics { +class CRU_PLATFORM_GRAPHICS_API NullPainter : public Object, + public virtual IPainter { + public: + NullPainter() = default; + + CRU_DELETE_COPY(NullPainter) + CRU_DELETE_MOVE(NullPainter) + + ~NullPainter() override = default; + + public: + String GetPlatformId() const override { return u"NULL"; } + + String GetDebugString() override { return u"NullPainter"; } + + Matrix GetTransform() override { return Matrix(); } + void SetTransform(const Matrix& matrix) override { CRU_UNUSED(matrix) } + + void ConcatTransform(const Matrix& matrix) override { CRU_UNUSED(matrix) } + + void Clear(const Color& color) override { CRU_UNUSED(color) } + + void DrawLine(const Point& start, const Point& end, IBrush* brush, + float width) override { + CRU_UNUSED(start) CRU_UNUSED(end) CRU_UNUSED(brush) CRU_UNUSED(width) + } + void StrokeRectangle(const Rect& rectangle, IBrush* brush, + float width) override { + CRU_UNUSED(rectangle) CRU_UNUSED(brush) CRU_UNUSED(width) + } + void FillRectangle(const Rect& rectangle, IBrush* brush) override { + CRU_UNUSED(rectangle) + CRU_UNUSED(brush) + } + void StrokeEllipse(const Rect& outline_rect, IBrush* brush, + float width) override { + CRU_UNUSED(outline_rect) + CRU_UNUSED(brush) + CRU_UNUSED(width) + } + void FillEllipse(const Rect& outline_rect, IBrush* brush) override { + CRU_UNUSED(outline_rect) + CRU_UNUSED(brush) + } + + void StrokeGeometry(IGeometry* geometry, IBrush* brush, + float width) override { + CRU_UNUSED(geometry) + CRU_UNUSED(brush) + CRU_UNUSED(width) + } + void FillGeometry(IGeometry* geometry, IBrush* brush) override { + CRU_UNUSED(geometry) + CRU_UNUSED(brush) + } + + void DrawText(const Point& offset, ITextLayout* text_layout, + IBrush* brush) override { + CRU_UNUSED(offset) + CRU_UNUSED(text_layout) + CRU_UNUSED(brush) + } + + void DrawImage(const Point& offset, IImage* image) override { + CRU_UNUSED(offset) + CRU_UNUSED(image) + } + + void PushLayer(const Rect& bounds) override { CRU_UNUSED(bounds) } + + void PopLayer() override {} + + void PushState() override {} + + void PopState() override {} + + void EndDraw() override {} +}; +} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/NullPainter.hpp b/include/cru/platform/graphics/NullPainter.hpp deleted file mode 100644 index 54c610c1..00000000 --- a/include/cru/platform/graphics/NullPainter.hpp +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once -#include "Painter.hpp" -#include "cru/common/Base.hpp" - -namespace cru::platform::graphics { -class CRU_PLATFORM_GRAPHICS_API NullPainter : public Object, - public virtual IPainter { - public: - NullPainter() = default; - - CRU_DELETE_COPY(NullPainter) - CRU_DELETE_MOVE(NullPainter) - - ~NullPainter() override = default; - - public: - String GetPlatformId() const override { return u"NULL"; } - - String GetDebugString() override { return u"NullPainter"; } - - Matrix GetTransform() override { return Matrix(); } - void SetTransform(const Matrix& matrix) override { CRU_UNUSED(matrix) } - - void ConcatTransform(const Matrix& matrix) override { CRU_UNUSED(matrix) } - - void Clear(const Color& color) override { CRU_UNUSED(color) } - - void DrawLine(const Point& start, const Point& end, IBrush* brush, - float width) override { - CRU_UNUSED(start) CRU_UNUSED(end) CRU_UNUSED(brush) CRU_UNUSED(width) - } - void StrokeRectangle(const Rect& rectangle, IBrush* brush, - float width) override { - CRU_UNUSED(rectangle) CRU_UNUSED(brush) CRU_UNUSED(width) - } - void FillRectangle(const Rect& rectangle, IBrush* brush) override { - CRU_UNUSED(rectangle) - CRU_UNUSED(brush) - } - void StrokeEllipse(const Rect& outline_rect, IBrush* brush, - float width) override { - CRU_UNUSED(outline_rect) - CRU_UNUSED(brush) - CRU_UNUSED(width) - } - void FillEllipse(const Rect& outline_rect, IBrush* brush) override { - CRU_UNUSED(outline_rect) - CRU_UNUSED(brush) - } - - void StrokeGeometry(IGeometry* geometry, IBrush* brush, - float width) override { - CRU_UNUSED(geometry) - CRU_UNUSED(brush) - CRU_UNUSED(width) - } - void FillGeometry(IGeometry* geometry, IBrush* brush) override { - CRU_UNUSED(geometry) - CRU_UNUSED(brush) - } - - void DrawText(const Point& offset, ITextLayout* text_layout, - IBrush* brush) override { - CRU_UNUSED(offset) - CRU_UNUSED(text_layout) - CRU_UNUSED(brush) - } - - void DrawImage(const Point& offset, IImage* image) override { - CRU_UNUSED(offset) - CRU_UNUSED(image) - } - - void PushLayer(const Rect& bounds) override { CRU_UNUSED(bounds) } - - void PopLayer() override {} - - void PushState() override {} - - void PopState() override {} - - void EndDraw() override {} -}; -} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Painter.h b/include/cru/platform/graphics/Painter.h new file mode 100644 index 00000000..38ff8849 --- /dev/null +++ b/include/cru/platform/graphics/Painter.h @@ -0,0 +1,42 @@ +#pragma once +#include "Resource.h" + +namespace cru::platform::graphics { + +struct CRU_PLATFORM_GRAPHICS_API IPainter : virtual IPlatformResource { + virtual Matrix GetTransform() = 0; + virtual void SetTransform(const Matrix& matrix) = 0; + + virtual void ConcatTransform(const Matrix& matrix) = 0; + + virtual void Clear(const Color& color) = 0; + + virtual void DrawLine(const Point& start, const Point& end, IBrush* brush, + float width) = 0; + virtual void StrokeRectangle(const Rect& rectangle, IBrush* brush, + float width) = 0; + virtual void FillRectangle(const Rect& rectangle, IBrush* brush) = 0; + virtual void StrokeEllipse(const Rect& outline_rect, IBrush* brush, + float width) = 0; + virtual void FillEllipse(const Rect& outline_rect, IBrush* brush) = 0; + + virtual void StrokeGeometry(IGeometry* geometry, IBrush* brush, + float width) = 0; + virtual void FillGeometry(IGeometry* geometry, IBrush* brush) = 0; + + virtual void DrawText(const Point& offset, ITextLayout* text_layout, + IBrush* brush) = 0; + + virtual void DrawImage(const Point& offset, IImage* image) = 0; + + virtual void PushLayer(const Rect& bounds) = 0; + + virtual void PopLayer() = 0; + + virtual void PushState() = 0; + + virtual void PopState() = 0; + + virtual void EndDraw() = 0; +}; +} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Painter.hpp b/include/cru/platform/graphics/Painter.hpp deleted file mode 100644 index 171e6260..00000000 --- a/include/cru/platform/graphics/Painter.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -#include "Resource.hpp" - -namespace cru::platform::graphics { - -struct CRU_PLATFORM_GRAPHICS_API IPainter : virtual IPlatformResource { - virtual Matrix GetTransform() = 0; - virtual void SetTransform(const Matrix& matrix) = 0; - - virtual void ConcatTransform(const Matrix& matrix) = 0; - - virtual void Clear(const Color& color) = 0; - - virtual void DrawLine(const Point& start, const Point& end, IBrush* brush, - float width) = 0; - virtual void StrokeRectangle(const Rect& rectangle, IBrush* brush, - float width) = 0; - virtual void FillRectangle(const Rect& rectangle, IBrush* brush) = 0; - virtual void StrokeEllipse(const Rect& outline_rect, IBrush* brush, - float width) = 0; - virtual void FillEllipse(const Rect& outline_rect, IBrush* brush) = 0; - - virtual void StrokeGeometry(IGeometry* geometry, IBrush* brush, - float width) = 0; - virtual void FillGeometry(IGeometry* geometry, IBrush* brush) = 0; - - virtual void DrawText(const Point& offset, ITextLayout* text_layout, - IBrush* brush) = 0; - - virtual void DrawImage(const Point& offset, IImage* image) = 0; - - virtual void PushLayer(const Rect& bounds) = 0; - - virtual void PopLayer() = 0; - - virtual void PushState() = 0; - - virtual void PopState() = 0; - - virtual void EndDraw() = 0; -}; -} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Resource.h b/include/cru/platform/graphics/Resource.h new file mode 100644 index 00000000..ab1b8de6 --- /dev/null +++ b/include/cru/platform/graphics/Resource.h @@ -0,0 +1,10 @@ +#pragma once +#include "Base.h" + +namespace cru::platform::graphics { +struct IGraphicsFactory; + +struct CRU_PLATFORM_GRAPHICS_API IGraphicsResource : virtual IPlatformResource { + virtual IGraphicsFactory* GetGraphicsFactory() = 0; +}; +} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/Resource.hpp b/include/cru/platform/graphics/Resource.hpp deleted file mode 100644 index e559b0e9..00000000 --- a/include/cru/platform/graphics/Resource.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "Base.hpp" - -namespace cru::platform::graphics { -struct IGraphicsFactory; - -struct CRU_PLATFORM_GRAPHICS_API IGraphicsResource : virtual IPlatformResource { - virtual IGraphicsFactory* GetGraphicsFactory() = 0; -}; -} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/TextLayout.h b/include/cru/platform/graphics/TextLayout.h new file mode 100644 index 00000000..e060186b --- /dev/null +++ b/include/cru/platform/graphics/TextLayout.h @@ -0,0 +1,33 @@ +#pragma once +#include "Resource.h" + +#include +#include + +namespace cru::platform::graphics { +// Requirement: +// All text must be left-top aligned. +struct CRU_PLATFORM_GRAPHICS_API ITextLayout : virtual IGraphicsResource { + virtual String GetText() = 0; + virtual void SetText(String new_text) = 0; + + virtual std::shared_ptr GetFont() = 0; + virtual void SetFont(std::shared_ptr font) = 0; + + virtual void SetMaxWidth(float max_width) = 0; + virtual void SetMaxHeight(float max_height) = 0; + + virtual bool IsEditMode() = 0; + virtual void SetEditMode(bool enable) = 0; + + virtual Index GetLineIndexFromCharIndex(Index char_index) = 0; + virtual Index GetLineCount() = 0; + virtual float GetLineHeight(Index line_index) = 0; + + virtual Rect GetTextBounds(bool includingTrailingSpace = false) = 0; + virtual std::vector TextRangeRect(const TextRange& text_range) = 0; + // Width is always 0, height is line height. + virtual Rect TextSinglePoint(Index position, bool trailing) = 0; + virtual TextHitTestResult HitTest(const Point& point) = 0; +}; +} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/TextLayout.hpp b/include/cru/platform/graphics/TextLayout.hpp deleted file mode 100644 index f9ccc824..00000000 --- a/include/cru/platform/graphics/TextLayout.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#include "Resource.hpp" - -#include -#include - -namespace cru::platform::graphics { -// Requirement: -// All text must be left-top aligned. -struct CRU_PLATFORM_GRAPHICS_API ITextLayout : virtual IGraphicsResource { - virtual String GetText() = 0; - virtual void SetText(String new_text) = 0; - - virtual std::shared_ptr GetFont() = 0; - virtual void SetFont(std::shared_ptr font) = 0; - - virtual void SetMaxWidth(float max_width) = 0; - virtual void SetMaxHeight(float max_height) = 0; - - virtual bool IsEditMode() = 0; - virtual void SetEditMode(bool enable) = 0; - - virtual Index GetLineIndexFromCharIndex(Index char_index) = 0; - virtual Index GetLineCount() = 0; - virtual float GetLineHeight(Index line_index) = 0; - - virtual Rect GetTextBounds(bool includingTrailingSpace = false) = 0; - virtual std::vector TextRangeRect(const TextRange& text_range) = 0; - // Width is always 0, height is line height. - virtual Rect TextSinglePoint(Index position, bool trailing) = 0; - virtual TextHitTestResult HitTest(const Point& point) = 0; -}; -} // namespace cru::platform::graphics diff --git a/include/cru/platform/graphics/util/Painter.h b/include/cru/platform/graphics/util/Painter.h new file mode 100644 index 00000000..e36d5c55 --- /dev/null +++ b/include/cru/platform/graphics/util/Painter.h @@ -0,0 +1,18 @@ +#pragma once +#include "../Painter.h" + +#include +#include + +namespace cru::platform::graphics::util { +template +void WithTransform(IPainter* painter, const Matrix& matrix, const Fn& action) { + static_assert(std::is_invocable_v, + "Action must can be be invoked with painter."); + const auto old = painter->GetTransform(); + painter->PushState(); + painter->ConcatTransform(matrix); + action(painter); + painter->PopState(); +} +} // namespace cru::platform::graphics::util diff --git a/include/cru/platform/graphics/util/Painter.hpp b/include/cru/platform/graphics/util/Painter.hpp deleted file mode 100644 index 2e0fbb51..00000000 --- a/include/cru/platform/graphics/util/Painter.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include "../Painter.hpp" - -#include -#include - -namespace cru::platform::graphics::util { -template -void WithTransform(IPainter* painter, const Matrix& matrix, const Fn& action) { - static_assert(std::is_invocable_v, - "Action must can be be invoked with painter."); - const auto old = painter->GetTransform(); - painter->PushState(); - painter->ConcatTransform(matrix); - action(painter); - painter->PopState(); -} -} // namespace cru::platform::graphics::util diff --git a/include/cru/platform/gui/Base.h b/include/cru/platform/gui/Base.h new file mode 100644 index 00000000..789ab308 --- /dev/null +++ b/include/cru/platform/gui/Base.h @@ -0,0 +1,37 @@ +#pragma once +#include "cru/common/Base.h" +#include "cru/common/Bitmask.h" +#include "cru/platform/graphics/Base.h" + +#include "../Resource.h" + +#ifdef CRU_PLATFORM_WINDOWS +#ifdef CRU_PLATFORM_GUI_EXPORT_API +#define CRU_PLATFORM_GUI_API __declspec(dllexport) +#else +#define CRU_PLATFORM_GUI_API __declspec(dllimport) +#endif +#else +#define CRU_PLATFORM_GUI_API +#endif + +namespace cru::platform::gui { +struct ICursor; +struct ICursorManager; +struct IUiApplication; +struct INativeWindow; +struct IInputMethodContext; +struct IClipboard; + +namespace details { +struct TagMouseButton {}; +} // namespace details + +using MouseButton = Bitmask; + +namespace mouse_buttons { +constexpr MouseButton left{0b1}; +constexpr MouseButton middle{0b10}; +constexpr MouseButton right{0b100}; +} // namespace mouse_buttons +} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/Base.hpp b/include/cru/platform/gui/Base.hpp deleted file mode 100644 index b432a2e0..00000000 --- a/include/cru/platform/gui/Base.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include "cru/common/Base.hpp" -#include "cru/common/Bitmask.hpp" -#include "cru/platform/graphics/Base.hpp" - -#include "../Resource.hpp" - -#ifdef CRU_PLATFORM_WINDOWS -#ifdef CRU_PLATFORM_GUI_EXPORT_API -#define CRU_PLATFORM_GUI_API __declspec(dllexport) -#else -#define CRU_PLATFORM_GUI_API __declspec(dllimport) -#endif -#else -#define CRU_PLATFORM_GUI_API -#endif - -namespace cru::platform::gui { -struct ICursor; -struct ICursorManager; -struct IUiApplication; -struct INativeWindow; -struct IInputMethodContext; -struct IClipboard; - -namespace details { -struct TagMouseButton {}; -} // namespace details - -using MouseButton = Bitmask; - -namespace mouse_buttons { -constexpr MouseButton left{0b1}; -constexpr MouseButton middle{0b10}; -constexpr MouseButton right{0b100}; -} // namespace mouse_buttons -} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/Clipboard.h b/include/cru/platform/gui/Clipboard.h new file mode 100644 index 00000000..47267895 --- /dev/null +++ b/include/cru/platform/gui/Clipboard.h @@ -0,0 +1,9 @@ +#pragma once +#include "Base.h" + +namespace cru::platform::gui { +struct IClipboard : virtual IPlatformResource { + virtual String GetText() = 0; + virtual void SetText(String text) = 0; +}; +} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/Clipboard.hpp b/include/cru/platform/gui/Clipboard.hpp deleted file mode 100644 index c3467de5..00000000 --- a/include/cru/platform/gui/Clipboard.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "Base.hpp" - -namespace cru::platform::gui { -struct IClipboard : virtual IPlatformResource { - virtual String GetText() = 0; - virtual void SetText(String text) = 0; -}; -} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/Cursor.h b/include/cru/platform/gui/Cursor.h new file mode 100644 index 00000000..99168656 --- /dev/null +++ b/include/cru/platform/gui/Cursor.h @@ -0,0 +1,16 @@ +#pragma once +#include "Base.h" + +#include + +namespace cru::platform::gui { +enum class SystemCursorType { Arrow, Hand, IBeam }; + +struct ICursor : virtual IPlatformResource {}; + +struct ICursorManager : virtual IPlatformResource { + virtual std::shared_ptr GetSystemCursor(SystemCursorType type) = 0; + + // TODO: Add method to create cursor. +}; +} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/Cursor.hpp b/include/cru/platform/gui/Cursor.hpp deleted file mode 100644 index abc8b064..00000000 --- a/include/cru/platform/gui/Cursor.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once -#include "Base.hpp" - -#include - -namespace cru::platform::gui { -enum class SystemCursorType { Arrow, Hand, IBeam }; - -struct ICursor : virtual IPlatformResource {}; - -struct ICursorManager : virtual IPlatformResource { - virtual std::shared_ptr GetSystemCursor(SystemCursorType type) = 0; - - // TODO: Add method to create cursor. -}; -} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/DebugFlags.h b/include/cru/platform/gui/DebugFlags.h new file mode 100644 index 00000000..2b7c7c19 --- /dev/null +++ b/include/cru/platform/gui/DebugFlags.h @@ -0,0 +1,8 @@ +#pragma once + +namespace cru::platform::gui { +struct DebugFlags { + static constexpr int paint = 0; + static constexpr int input_method = 0; +}; +} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/DebugFlags.hpp b/include/cru/platform/gui/DebugFlags.hpp deleted file mode 100644 index 2b7c7c19..00000000 --- a/include/cru/platform/gui/DebugFlags.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -namespace cru::platform::gui { -struct DebugFlags { - static constexpr int paint = 0; - static constexpr int input_method = 0; -}; -} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/InputMethod.h b/include/cru/platform/gui/InputMethod.h new file mode 100644 index 00000000..45e11c06 --- /dev/null +++ b/include/cru/platform/gui/InputMethod.h @@ -0,0 +1,55 @@ +#pragma once +#include "Base.h" + +#include "cru/common/Event.h" + +#include +#include + +namespace cru::platform::gui { +struct CompositionClause { + int start; + int end; + bool target; +}; + +using CompositionClauses = std::vector; + +struct CompositionText { + String text; + CompositionClauses clauses; + TextRange selection; +}; + +struct IInputMethodContext : virtual IPlatformResource { + // Return true if you should draw composition text manually. Return false if + // system will take care of that for you. + virtual bool ShouldManuallyDrawCompositionText() = 0; + + virtual void EnableIME() = 0; + + virtual void DisableIME() = 0; + + virtual void CompleteComposition() = 0; + + virtual void CancelComposition() = 0; + + virtual CompositionText GetCompositionText() = 0; + + // Set the candidate window lefttop. Relative to window lefttop. Use this + // method to prepare typing. + virtual void SetCandidateWindowPosition(const Point& point) = 0; + + // Triggered when user starts composition. + virtual IEvent* CompositionStartEvent() = 0; + + // Triggered when user stops composition. + virtual IEvent* CompositionEndEvent() = 0; + + // Triggered every time composition text changes. + virtual IEvent* CompositionEvent() = 0; + + virtual IEvent* TextEvent() = 0; +}; +} // namespace cru::platform::gui + diff --git a/include/cru/platform/gui/InputMethod.hpp b/include/cru/platform/gui/InputMethod.hpp deleted file mode 100644 index a34aba74..00000000 --- a/include/cru/platform/gui/InputMethod.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once -#include "Base.hpp" - -#include "cru/common/Event.hpp" - -#include -#include - -namespace cru::platform::gui { -struct CompositionClause { - int start; - int end; - bool target; -}; - -using CompositionClauses = std::vector; - -struct CompositionText { - String text; - CompositionClauses clauses; - TextRange selection; -}; - -struct IInputMethodContext : virtual IPlatformResource { - // Return true if you should draw composition text manually. Return false if - // system will take care of that for you. - virtual bool ShouldManuallyDrawCompositionText() = 0; - - virtual void EnableIME() = 0; - - virtual void DisableIME() = 0; - - virtual void CompleteComposition() = 0; - - virtual void CancelComposition() = 0; - - virtual CompositionText GetCompositionText() = 0; - - // Set the candidate window lefttop. Relative to window lefttop. Use this - // method to prepare typing. - virtual void SetCandidateWindowPosition(const Point& point) = 0; - - // Triggered when user starts composition. - virtual IEvent* CompositionStartEvent() = 0; - - // Triggered when user stops composition. - virtual IEvent* CompositionEndEvent() = 0; - - // Triggered every time composition text changes. - virtual IEvent* CompositionEvent() = 0; - - virtual IEvent* TextEvent() = 0; -}; -} // namespace cru::platform::gui - diff --git a/include/cru/platform/gui/Keyboard.h b/include/cru/platform/gui/Keyboard.h new file mode 100644 index 00000000..f25b25fa --- /dev/null +++ b/include/cru/platform/gui/Keyboard.h @@ -0,0 +1,140 @@ +#pragma once +#include "cru/common/Bitmask.h" +#include "cru/platform/gui/Base.h" + +#include +#include + +namespace cru::platform::gui { +// Because of the complexity of keyboard layout, I only add code in US keyboard +// layout, the most widely used layout in China. We should try to make it easy +// to add new keyboard layout. +enum class KeyCode { + Unknown, + LeftButton, + MiddleButton, + RightButton, + Escape, + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + N0, + N1, + N2, + N3, + N4, + N5, + N6, + N7, + N8, + N9, + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, + GraveAccent, + Tab, + CapsLock, + LeftShift, + LeftCtrl, + LeftSuper, + LeftAlt, + Minus, + Equal, + Backspace, + LeftSquareBracket, + RightSquareBracket, + BackSlash, + Semicolon, + Quote, + Comma, + Period, + Slash, + RightShift, + RightCtrl, + RightSuper, + RightAlt, + Insert, + Delete, + Home, + End, + PageUp, + PageDown, + Up, + Left, + Down, + Right, + PrintScreen, + ScrollLock, + Pause, + NumPad0, + NumPad1, + NumPad2, + NumPad3, + NumPad4, + NumPad5, + NumPad6, + NumPad7, + NumPad8, + NumPad9, + LeftCommand, + RightCommand, + Return, + Space +}; + +namespace details { +struct TagKeyModifier {}; +} // namespace details + +using KeyModifier = Bitmask; + +struct KeyModifiers { + static constexpr KeyModifier none{0}; + static constexpr KeyModifier shift{0b1}; + static constexpr KeyModifier ctrl{0b10}; + static constexpr KeyModifier alt{0b100}; + static constexpr KeyModifier command{0b1000}; +}; + +#ifdef CRU_PLATFORM_OSX +constexpr KeyModifier kKeyModifierCommand = KeyModifiers::command; +#else +constexpr KeyModifier kKeyModifierCommand = KeyModifiers::ctrl; +#endif + +CRU_PLATFORM_GUI_API String ToString(KeyCode key_code); +CRU_PLATFORM_GUI_API String ToString(KeyModifier key_modifier, + StringView separator = u"+"); +} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/Keyboard.hpp b/include/cru/platform/gui/Keyboard.hpp deleted file mode 100644 index 347b57bc..00000000 --- a/include/cru/platform/gui/Keyboard.hpp +++ /dev/null @@ -1,140 +0,0 @@ -#pragma once -#include "cru/common/Bitmask.hpp" -#include "cru/platform/gui/Base.hpp" - -#include -#include - -namespace cru::platform::gui { -// Because of the complexity of keyboard layout, I only add code in US keyboard -// layout, the most widely used layout in China. We should try to make it easy -// to add new keyboard layout. -enum class KeyCode { - Unknown, - LeftButton, - MiddleButton, - RightButton, - Escape, - F1, - F2, - F3, - F4, - F5, - F6, - F7, - F8, - F9, - F10, - F11, - F12, - N0, - N1, - N2, - N3, - N4, - N5, - N6, - N7, - N8, - N9, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - T, - U, - V, - W, - X, - Y, - Z, - GraveAccent, - Tab, - CapsLock, - LeftShift, - LeftCtrl, - LeftSuper, - LeftAlt, - Minus, - Equal, - Backspace, - LeftSquareBracket, - RightSquareBracket, - BackSlash, - Semicolon, - Quote, - Comma, - Period, - Slash, - RightShift, - RightCtrl, - RightSuper, - RightAlt, - Insert, - Delete, - Home, - End, - PageUp, - PageDown, - Up, - Left, - Down, - Right, - PrintScreen, - ScrollLock, - Pause, - NumPad0, - NumPad1, - NumPad2, - NumPad3, - NumPad4, - NumPad5, - NumPad6, - NumPad7, - NumPad8, - NumPad9, - LeftCommand, - RightCommand, - Return, - Space -}; - -namespace details { -struct TagKeyModifier {}; -} // namespace details - -using KeyModifier = Bitmask; - -struct KeyModifiers { - static constexpr KeyModifier none{0}; - static constexpr KeyModifier shift{0b1}; - static constexpr KeyModifier ctrl{0b10}; - static constexpr KeyModifier alt{0b100}; - static constexpr KeyModifier command{0b1000}; -}; - -#ifdef CRU_PLATFORM_OSX -constexpr KeyModifier kKeyModifierCommand = KeyModifiers::command; -#else -constexpr KeyModifier kKeyModifierCommand = KeyModifiers::ctrl; -#endif - -CRU_PLATFORM_GUI_API String ToString(KeyCode key_code); -CRU_PLATFORM_GUI_API String ToString(KeyModifier key_modifier, - StringView separator = u"+"); -} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/Menu.h b/include/cru/platform/gui/Menu.h new file mode 100644 index 00000000..6e2a8902 --- /dev/null +++ b/include/cru/platform/gui/Menu.h @@ -0,0 +1,32 @@ +#pragma once +#include "Base.h" + +#include "Keyboard.h" + +#include + +namespace cru::platform::gui { +struct IMenu; + +struct CRU_PLATFORM_GUI_API IMenuItem : virtual IPlatformResource { + virtual String GetTitle() = 0; + virtual void SetTitle(String title) = 0; + virtual bool IsEnabled() = 0; + virtual void SetEnabled(bool enabled) = 0; + virtual IMenu* GetParentMenu() = 0; + virtual IMenu* GetSubmenu() = 0; + virtual void SetKeyboardShortcut(KeyCode key, KeyModifier modifiers) = 0; + virtual void DeleteKeyboardShortcut() = 0; + virtual void SetOnClickHandler(std::function handler) = 0; +}; + +struct CRU_PLATFORM_GUI_API IMenu : virtual IPlatformResource { + virtual IMenuItem* GetItemAt(int index) = 0; + virtual int GetItemCount() = 0; + virtual IMenuItem* CreateItemAt(int index) = 0; + virtual void RemoveItemAt(int index) = 0; + + virtual std::vector GetItems(); + bool Empty() { return GetItemCount() == 0; } +}; +} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/Menu.hpp b/include/cru/platform/gui/Menu.hpp deleted file mode 100644 index fc2e844f..00000000 --- a/include/cru/platform/gui/Menu.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#include "Base.hpp" - -#include "Keyboard.hpp" - -#include - -namespace cru::platform::gui { -struct IMenu; - -struct CRU_PLATFORM_GUI_API IMenuItem : virtual IPlatformResource { - virtual String GetTitle() = 0; - virtual void SetTitle(String title) = 0; - virtual bool IsEnabled() = 0; - virtual void SetEnabled(bool enabled) = 0; - virtual IMenu* GetParentMenu() = 0; - virtual IMenu* GetSubmenu() = 0; - virtual void SetKeyboardShortcut(KeyCode key, KeyModifier modifiers) = 0; - virtual void DeleteKeyboardShortcut() = 0; - virtual void SetOnClickHandler(std::function handler) = 0; -}; - -struct CRU_PLATFORM_GUI_API IMenu : virtual IPlatformResource { - virtual IMenuItem* GetItemAt(int index) = 0; - virtual int GetItemCount() = 0; - virtual IMenuItem* CreateItemAt(int index) = 0; - virtual void RemoveItemAt(int index) = 0; - - virtual std::vector GetItems(); - bool Empty() { return GetItemCount() == 0; } -}; -} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/SaveOpenDialogOptions.h b/include/cru/platform/gui/SaveOpenDialogOptions.h new file mode 100644 index 00000000..cff4a44f --- /dev/null +++ b/include/cru/platform/gui/SaveOpenDialogOptions.h @@ -0,0 +1,81 @@ +#pragma once +#include "Base.h" + +namespace cru::platform::gui { +struct CRU_PLATFORM_GUI_API SaveDialogOptions { + String title; + String prompt; + String message; + std::vector allowed_file_types; + bool allow_all_file_types = false; +}; + +struct CRU_PLATFORM_GUI_API OpenDialogOptions : SaveDialogOptions { + bool can_choose_files = true; + bool can_choose_directories = false; + bool allow_mulitple_selection = false; +}; + +template +struct CRU_PLATFORM_GUI_API SaveDialogOptionsBuilderTemplate { + T options; + + SaveDialogOptionsBuilderTemplate& SetTitle(String title) { + options.title = std::move(title); + return *this; + } + + SaveDialogOptionsBuilderTemplate& SetPrompt(String prompt) { + options.prompt = std::move(prompt); + return *this; + } + + SaveDialogOptionsBuilderTemplate& SetMessage(String message) { + options.message = std::move(message); + return *this; + } + + SaveDialogOptionsBuilderTemplate& SetAllowedFileTypes( + std::vector allowed_file_types) { + options.allowed_file_types = std::move(allowed_file_types); + return *this; + } + + SaveDialogOptionsBuilderTemplate& AddAllowedFileType( + String allowed_file_type) { + options.allowed_file_types.push_back(allowed_file_type); + return *this; + } + + SaveDialogOptionsBuilderTemplate& SetAllowAllFileTypes( + bool allow_all_file_types) { + options.allow_all_file_types = allow_all_file_types; + return *this; + } + + T Build() { return options; } +}; + +using SaveDialogOptionsBuilder = + SaveDialogOptionsBuilderTemplate; + +struct CRU_PLATFORM_GUI_API OpenDialogOptionsBuilder + : SaveDialogOptionsBuilderTemplate { + OpenDialogOptionsBuilder& SetCanChooseFiles(bool can_choose_files) { + options.can_choose_files = can_choose_files; + return *this; + } + + OpenDialogOptionsBuilder& SetCanChooseDirectories( + bool can_choose_directories) { + options.can_choose_directories = can_choose_directories; + return *this; + } + + OpenDialogOptionsBuilder& SetAllowMultipleSelection( + bool allow_mulitple_selection) { + options.allow_mulitple_selection = allow_mulitple_selection; + return *this; + } +}; +} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/SaveOpenDialogOptions.hpp b/include/cru/platform/gui/SaveOpenDialogOptions.hpp deleted file mode 100644 index 907ec808..00000000 --- a/include/cru/platform/gui/SaveOpenDialogOptions.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once -#include "Base.hpp" - -namespace cru::platform::gui { -struct CRU_PLATFORM_GUI_API SaveDialogOptions { - String title; - String prompt; - String message; - std::vector allowed_file_types; - bool allow_all_file_types = false; -}; - -struct CRU_PLATFORM_GUI_API OpenDialogOptions : SaveDialogOptions { - bool can_choose_files = true; - bool can_choose_directories = false; - bool allow_mulitple_selection = false; -}; - -template -struct CRU_PLATFORM_GUI_API SaveDialogOptionsBuilderTemplate { - T options; - - SaveDialogOptionsBuilderTemplate& SetTitle(String title) { - options.title = std::move(title); - return *this; - } - - SaveDialogOptionsBuilderTemplate& SetPrompt(String prompt) { - options.prompt = std::move(prompt); - return *this; - } - - SaveDialogOptionsBuilderTemplate& SetMessage(String message) { - options.message = std::move(message); - return *this; - } - - SaveDialogOptionsBuilderTemplate& SetAllowedFileTypes( - std::vector allowed_file_types) { - options.allowed_file_types = std::move(allowed_file_types); - return *this; - } - - SaveDialogOptionsBuilderTemplate& AddAllowedFileType( - String allowed_file_type) { - options.allowed_file_types.push_back(allowed_file_type); - return *this; - } - - SaveDialogOptionsBuilderTemplate& SetAllowAllFileTypes( - bool allow_all_file_types) { - options.allow_all_file_types = allow_all_file_types; - return *this; - } - - T Build() { return options; } -}; - -using SaveDialogOptionsBuilder = - SaveDialogOptionsBuilderTemplate; - -struct CRU_PLATFORM_GUI_API OpenDialogOptionsBuilder - : SaveDialogOptionsBuilderTemplate { - OpenDialogOptionsBuilder& SetCanChooseFiles(bool can_choose_files) { - options.can_choose_files = can_choose_files; - return *this; - } - - OpenDialogOptionsBuilder& SetCanChooseDirectories( - bool can_choose_directories) { - options.can_choose_directories = can_choose_directories; - return *this; - } - - OpenDialogOptionsBuilder& SetAllowMultipleSelection( - bool allow_mulitple_selection) { - options.allow_mulitple_selection = allow_mulitple_selection; - return *this; - } -}; -} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/TimerHelper.h b/include/cru/platform/gui/TimerHelper.h new file mode 100644 index 00000000..91d436a4 --- /dev/null +++ b/include/cru/platform/gui/TimerHelper.h @@ -0,0 +1,69 @@ +#pragma once +#include "UiApplication.h" + +namespace cru::platform::gui { + +class TimerAutoCanceler { + public: + TimerAutoCanceler() : id_(0) {} + explicit TimerAutoCanceler(long long id) : id_(id) {} + + CRU_DELETE_COPY(TimerAutoCanceler) + + TimerAutoCanceler(TimerAutoCanceler&& other) : id_(other.id_) { + other.id_ = 0; + } + + TimerAutoCanceler& operator=(TimerAutoCanceler&& other) { + if (&other == this) { + return *this; + } + Reset(other.id_); + other.id_ = 0; + return *this; + } + + TimerAutoCanceler& operator=(long long other) { + return this->operator=(TimerAutoCanceler(other)); + } + + ~TimerAutoCanceler() { Reset(); } + + long long Release() { + auto temp = id_; + id_ = 0; + return temp; + } + + void Reset(long long id = 0) { + if (id_ > 0) IUiApplication::GetInstance()->CancelTimer(id_); + id_ = id; + } + + explicit operator bool() const { return id_; } + + private: + long long id_; +}; + +class TimerListAutoCanceler { + public: + TimerListAutoCanceler() = default; + CRU_DELETE_COPY(TimerListAutoCanceler) + CRU_DEFAULT_MOVE(TimerListAutoCanceler) + ~TimerListAutoCanceler() = default; + + TimerListAutoCanceler& operator+=(long long id) { + list_.push_back(TimerAutoCanceler(id)); + return *this; + } + + void Clear() { list_.clear(); } + + bool IsEmpty() const { return list_.empty(); } + + private: + std::vector list_; +}; + +} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/TimerHelper.hpp b/include/cru/platform/gui/TimerHelper.hpp deleted file mode 100644 index a61d2f04..00000000 --- a/include/cru/platform/gui/TimerHelper.hpp +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once -#include "UiApplication.hpp" - -namespace cru::platform::gui { - -class TimerAutoCanceler { - public: - TimerAutoCanceler() : id_(0) {} - explicit TimerAutoCanceler(long long id) : id_(id) {} - - CRU_DELETE_COPY(TimerAutoCanceler) - - TimerAutoCanceler(TimerAutoCanceler&& other) : id_(other.id_) { - other.id_ = 0; - } - - TimerAutoCanceler& operator=(TimerAutoCanceler&& other) { - if (&other == this) { - return *this; - } - Reset(other.id_); - other.id_ = 0; - return *this; - } - - TimerAutoCanceler& operator=(long long other) { - return this->operator=(TimerAutoCanceler(other)); - } - - ~TimerAutoCanceler() { Reset(); } - - long long Release() { - auto temp = id_; - id_ = 0; - return temp; - } - - void Reset(long long id = 0) { - if (id_ > 0) IUiApplication::GetInstance()->CancelTimer(id_); - id_ = id; - } - - explicit operator bool() const { return id_; } - - private: - long long id_; -}; - -class TimerListAutoCanceler { - public: - TimerListAutoCanceler() = default; - CRU_DELETE_COPY(TimerListAutoCanceler) - CRU_DEFAULT_MOVE(TimerListAutoCanceler) - ~TimerListAutoCanceler() = default; - - TimerListAutoCanceler& operator+=(long long id) { - list_.push_back(TimerAutoCanceler(id)); - return *this; - } - - void Clear() { list_.clear(); } - - bool IsEmpty() const { return list_.empty(); } - - private: - std::vector list_; -}; - -} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/UiApplication.h b/include/cru/platform/gui/UiApplication.h new file mode 100644 index 00000000..b39e2d36 --- /dev/null +++ b/include/cru/platform/gui/UiApplication.h @@ -0,0 +1,70 @@ +#pragma once +#include "Base.h" + +#include "cru/common/Bitmask.h" +#include "cru/platform/gui/Menu.h" + +#include "SaveOpenDialogOptions.h" + +#include +#include +#include +#include + +namespace cru::platform::gui { +// The entry point of a ui application. +struct CRU_PLATFORM_GUI_API IUiApplication : public virtual IPlatformResource { + public: + static IUiApplication* GetInstance() { return instance; } + + private: + static IUiApplication* instance; + + protected: + IUiApplication(); + + public: + ~IUiApplication() override; + + // Block current thread and run the message loop. Return the exit code when + // message loop gets a quit message (possibly posted by method RequestQuit). + virtual int Run() = 0; + + // Post a quit message with given quit code. + virtual void RequestQuit(int quit_code) = 0; + + virtual void AddOnQuitHandler(std::function handler) = 0; + + virtual bool IsQuitOnAllWindowClosed() = 0; + virtual void SetQuitOnAllWindowClosed(bool quit_on_all_window_closed) = 0; + + // Timer id should always be positive (not 0) and never the same. So it's ok + // to use negative value (or 0) to represent no timer. + virtual long long SetImmediate(std::function action) = 0; + virtual long long SetTimeout(std::chrono::milliseconds milliseconds, + std::function action) = 0; + virtual long long SetInterval(std::chrono::milliseconds milliseconds, + std::function action) = 0; + // Implementation should guarantee calls on timer id already canceled have no + // effects and do not crash. Also canceling negative id or 0 should always + // result in no-op. + virtual void CancelTimer(long long id) = 0; + + virtual std::vector GetAllWindow() = 0; + + virtual INativeWindow* CreateWindow() = 0; + + virtual cru::platform::graphics::IGraphicsFactory* GetGraphicsFactory() = 0; + + virtual ICursorManager* GetCursorManager() = 0; + + virtual IClipboard* GetClipboard() = 0; + + // If return nullptr, it means the menu is not supported. + virtual IMenu* GetApplicationMenu(); + + virtual std::optional ShowSaveDialog(SaveDialogOptions options); + virtual std::optional> ShowOpenDialog( + OpenDialogOptions options); +}; +} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/UiApplication.hpp b/include/cru/platform/gui/UiApplication.hpp deleted file mode 100644 index c917aa01..00000000 --- a/include/cru/platform/gui/UiApplication.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once -#include "Base.hpp" - -#include "cru/common/Bitmask.hpp" -#include "cru/platform/gui/Menu.hpp" - -#include "SaveOpenDialogOptions.hpp" - -#include -#include -#include -#include - -namespace cru::platform::gui { -// The entry point of a ui application. -struct CRU_PLATFORM_GUI_API IUiApplication : public virtual IPlatformResource { - public: - static IUiApplication* GetInstance() { return instance; } - - private: - static IUiApplication* instance; - - protected: - IUiApplication(); - - public: - ~IUiApplication() override; - - // Block current thread and run the message loop. Return the exit code when - // message loop gets a quit message (possibly posted by method RequestQuit). - virtual int Run() = 0; - - // Post a quit message with given quit code. - virtual void RequestQuit(int quit_code) = 0; - - virtual void AddOnQuitHandler(std::function handler) = 0; - - virtual bool IsQuitOnAllWindowClosed() = 0; - virtual void SetQuitOnAllWindowClosed(bool quit_on_all_window_closed) = 0; - - // Timer id should always be positive (not 0) and never the same. So it's ok - // to use negative value (or 0) to represent no timer. - virtual long long SetImmediate(std::function action) = 0; - virtual long long SetTimeout(std::chrono::milliseconds milliseconds, - std::function action) = 0; - virtual long long SetInterval(std::chrono::milliseconds milliseconds, - std::function action) = 0; - // Implementation should guarantee calls on timer id already canceled have no - // effects and do not crash. Also canceling negative id or 0 should always - // result in no-op. - virtual void CancelTimer(long long id) = 0; - - virtual std::vector GetAllWindow() = 0; - - virtual INativeWindow* CreateWindow() = 0; - - virtual cru::platform::graphics::IGraphicsFactory* GetGraphicsFactory() = 0; - - virtual ICursorManager* GetCursorManager() = 0; - - virtual IClipboard* GetClipboard() = 0; - - // If return nullptr, it means the menu is not supported. - virtual IMenu* GetApplicationMenu(); - - virtual std::optional ShowSaveDialog(SaveDialogOptions options); - virtual std::optional> ShowOpenDialog( - OpenDialogOptions options); -}; -} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/Window.h b/include/cru/platform/gui/Window.h new file mode 100644 index 00000000..d3f0daad --- /dev/null +++ b/include/cru/platform/gui/Window.h @@ -0,0 +1,112 @@ +#pragma once +#include "Base.h" + +#include "Keyboard.h" + +#include "cru/common/Event.h" + +#include + +namespace cru::platform::gui { +namespace details { +struct WindowStyleFlagTag; +} + +using WindowStyleFlag = Bitmask; + +struct WindowStyleFlags { + static constexpr WindowStyleFlag NoCaptionAndBorder{0b1}; +}; + +enum class WindowVisibilityType { Show, Hide, Minimize }; + +enum class FocusChangeType { Gain, Lose }; + +enum class MouseEnterLeaveType { Enter, Leave }; + +struct NativeMouseButtonEventArgs { + MouseButton button; + Point point; + KeyModifier modifier; +}; + +struct NativeMouseWheelEventArgs { + // Positive means down. Negative means up. + float delta; + Point point; + KeyModifier modifier; + bool horizontal; // true if horizontal wheel. +}; + +struct NativeKeyEventArgs { + KeyCode key; + KeyModifier modifier; +}; + +// Represents a native window, which exposes some low-level events and +// operations. +struct INativeWindow : virtual IPlatformResource { + virtual void Close() = 0; + + virtual INativeWindow* GetParent() = 0; + virtual void SetParent(INativeWindow* parent) = 0; + + virtual WindowStyleFlag GetStyleFlag() = 0; + virtual void SetStyleFlag(WindowStyleFlag flag) = 0; + + virtual String GetTitle() = 0; + virtual void SetTitle(String title) = 0; + + virtual WindowVisibilityType GetVisibility() = 0; + virtual void SetVisibility(WindowVisibilityType visibility) = 0; + + virtual Size GetClientSize() = 0; + virtual void SetClientSize(const Size& size) = 0; + + virtual Rect GetClientRect() = 0; + virtual void SetClientRect(const Rect& rect) = 0; + + // Get the rect of the window containing frame. + // The lefttop of the rect is relative to screen lefttop. + virtual Rect GetWindowRect() = 0; + + // Set the rect of the window containing frame. + // The lefttop of the rect is relative to screen lefttop. + virtual void SetWindowRect(const Rect& rect) = 0; + + virtual bool RequestFocus() = 0; + + // Relative to client lefttop. + virtual Point GetMousePosition() = 0; + + virtual bool CaptureMouse() = 0; + virtual bool ReleaseMouse() = 0; + + virtual void SetCursor(std::shared_ptr cursor) = 0; + + virtual void SetToForeground() = 0; + + virtual void RequestRepaint() = 0; + + // Remember to call EndDraw on return value and destroy it. + virtual std::unique_ptr BeginPaint() = 0; + + virtual IEvent* CreateEvent() = 0; + virtual IEvent* DestroyEvent() = 0; + virtual IEvent* PaintEvent() = 0; + + virtual IEvent* VisibilityChangeEvent() = 0; + virtual IEvent* ResizeEvent() = 0; + virtual IEvent* FocusEvent() = 0; + + virtual IEvent* MouseEnterLeaveEvent() = 0; + virtual IEvent* MouseMoveEvent() = 0; + virtual IEvent* MouseDownEvent() = 0; + virtual IEvent* MouseUpEvent() = 0; + virtual IEvent* MouseWheelEvent() = 0; + virtual IEvent* KeyDownEvent() = 0; + virtual IEvent* KeyUpEvent() = 0; + + virtual IInputMethodContext* GetInputMethodContext() = 0; +}; +} // namespace cru::platform::gui diff --git a/include/cru/platform/gui/Window.hpp b/include/cru/platform/gui/Window.hpp deleted file mode 100644 index a8fe3ca6..00000000 --- a/include/cru/platform/gui/Window.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once -#include "Base.hpp" - -#include "Keyboard.hpp" - -#include "cru/common/Event.hpp" - -#include - -namespace cru::platform::gui { -namespace details { -struct WindowStyleFlagTag; -} - -using WindowStyleFlag = Bitmask; - -struct WindowStyleFlags { - static constexpr WindowStyleFlag NoCaptionAndBorder{0b1}; -}; - -enum class WindowVisibilityType { Show, Hide, Minimize }; - -enum class FocusChangeType { Gain, Lose }; - -enum class MouseEnterLeaveType { Enter, Leave }; - -struct NativeMouseButtonEventArgs { - MouseButton button; - Point point; - KeyModifier modifier; -}; - -struct NativeMouseWheelEventArgs { - // Positive means down. Negative means up. - float delta; - Point point; - KeyModifier modifier; - bool horizontal; // true if horizontal wheel. -}; - -struct NativeKeyEventArgs { - KeyCode key; - KeyModifier modifier; -}; - -// Represents a native window, which exposes some low-level events and -// operations. -struct INativeWindow : virtual IPlatformResource { - virtual void Close() = 0; - - virtual INativeWindow* GetParent() = 0; - virtual void SetParent(INativeWindow* parent) = 0; - - virtual WindowStyleFlag GetStyleFlag() = 0; - virtual void SetStyleFlag(WindowStyleFlag flag) = 0; - - virtual String GetTitle() = 0; - virtual void SetTitle(String title) = 0; - - virtual WindowVisibilityType GetVisibility() = 0; - virtual void SetVisibility(WindowVisibilityType visibility) = 0; - - virtual Size GetClientSize() = 0; - virtual void SetClientSize(const Size& size) = 0; - - virtual Rect GetClientRect() = 0; - virtual void SetClientRect(const Rect& rect) = 0; - - // Get the rect of the window containing frame. - // The lefttop of the rect is relative to screen lefttop. - virtual Rect GetWindowRect() = 0; - - // Set the rect of the window containing frame. - // The lefttop of the rect is relative to screen lefttop. - virtual void SetWindowRect(const Rect& rect) = 0; - - virtual bool RequestFocus() = 0; - - // Relative to client lefttop. - virtual Point GetMousePosition() = 0; - - virtual bool CaptureMouse() = 0; - virtual bool ReleaseMouse() = 0; - - virtual void SetCursor(std::shared_ptr cursor) = 0; - - virtual void SetToForeground() = 0; - - virtual void RequestRepaint() = 0; - - // Remember to call EndDraw on return value and destroy it. - virtual std::unique_ptr BeginPaint() = 0; - - virtual IEvent* CreateEvent() = 0; - virtual IEvent* DestroyEvent() = 0; - virtual IEvent* PaintEvent() = 0; - - virtual IEvent* VisibilityChangeEvent() = 0; - virtual IEvent* ResizeEvent() = 0; - virtual IEvent* FocusEvent() = 0; - - virtual IEvent* MouseEnterLeaveEvent() = 0; - virtual IEvent* MouseMoveEvent() = 0; - virtual IEvent* MouseDownEvent() = 0; - virtual IEvent* MouseUpEvent() = 0; - virtual IEvent* MouseWheelEvent() = 0; - virtual IEvent* KeyDownEvent() = 0; - virtual IEvent* KeyUpEvent() = 0; - - virtual IInputMethodContext* GetInputMethodContext() = 0; -}; -} // namespace cru::platform::gui -- cgit v1.2.3