aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/platform/Check.h28
-rw-r--r--include/cru/platform/Exception.h2
-rw-r--r--include/cru/platform/Resource.h2
-rw-r--r--include/cru/platform/gui/xcb/Window.h10
-rw-r--r--src/platform/CMakeLists.txt2
-rw-r--r--src/platform/Exception.cpp2
-rw-r--r--src/platform/ForDllExport.cpp2
-rw-r--r--src/platform/Resource.cpp7
-rw-r--r--src/platform/gui/xcb/Window.cpp25
9 files changed, 70 insertions, 10 deletions
diff --git a/include/cru/platform/Check.h b/include/cru/platform/Check.h
index 270150e8..202ee86e 100644
--- a/include/cru/platform/Check.h
+++ b/include/cru/platform/Check.h
@@ -35,4 +35,32 @@ std::shared_ptr<TTarget> CheckPlatform(const std::shared_ptr<TSource>& resource,
}
return result;
}
+
+template <typename TTarget>
+TTarget* CheckPlatform(IPlatformResource* resource,
+ std::string target_platform) {
+ if (resource == nullptr) return nullptr;
+ const auto result = dynamic_cast<TTarget*>(resource);
+ if (result == nullptr) {
+ throw PlatformNotMatchException(
+ resource->GetPlatformIdUtf8(), target_platform,
+ "Try to convert resource to target platform failed.");
+ }
+ return result;
+}
+
+template <typename TTarget, typename TSource>
+std::shared_ptr<TTarget> CheckPlatform(const std::shared_ptr<TSource>& resource,
+ std::string target_platform) {
+ if (resource == nullptr) return nullptr;
+ static_assert(std::is_base_of_v<IPlatformResource, TSource>,
+ "TSource must be a subclass of IPlatformResource.");
+ const auto result = std::dynamic_pointer_cast<TTarget>(resource);
+ if (result == nullptr) {
+ throw PlatformNotMatchException(
+ resource->GetPlatformIdUtf8(), target_platform,
+ "Try to convert resource to target platform failed.");
+ }
+ return result;
+}
} // namespace cru::platform
diff --git a/include/cru/platform/Exception.h b/include/cru/platform/Exception.h
index 25017869..f8ed5b0c 100644
--- a/include/cru/platform/Exception.h
+++ b/include/cru/platform/Exception.h
@@ -14,7 +14,7 @@ class CRU_PLATFORM_API PlatformNotMatchException : public PlatformException {
public:
PlatformNotMatchException(
std::string resource_platform, std::string target_platform,
- std::optional<std::string> additional_message = std::nullopt);
+ std::optional<std::string_view> additional_message = std::nullopt);
PlatformNotMatchException(
StringView resource_platform, StringView target_platform,
diff --git a/include/cru/platform/Resource.h b/include/cru/platform/Resource.h
index 69210348..a16a9dbd 100644
--- a/include/cru/platform/Resource.h
+++ b/include/cru/platform/Resource.h
@@ -11,5 +11,7 @@ struct CRU_PLATFORM_API IPlatformResource : virtual Interface {
virtual String GetPlatformId() const = 0;
virtual String GetDebugString() { return String(); }
+
+ virtual std::string GetPlatformIdUtf8() const;
};
} // namespace cru::platform
diff --git a/include/cru/platform/gui/xcb/Window.h b/include/cru/platform/gui/xcb/Window.h
index e09fdbfb..f9fbf735 100644
--- a/include/cru/platform/gui/xcb/Window.h
+++ b/include/cru/platform/gui/xcb/Window.h
@@ -18,10 +18,10 @@ class XcbWindow : public XcbResource, public virtual INativeWindow {
explicit XcbWindow(XcbUiApplication* application);
~XcbWindow() override;
- virtual void Close() = 0;
+ void Close() override;
- virtual INativeWindow* GetParent() = 0;
- virtual void SetParent(INativeWindow* parent) = 0;
+ INativeWindow* GetParent() override;
+ void SetParent(INativeWindow* parent) override;
virtual WindowStyleFlag GetStyleFlag() = 0;
virtual void SetStyleFlag(WindowStyleFlag flag) = 0;
@@ -91,9 +91,11 @@ class XcbWindow : public XcbResource, public virtual INativeWindow {
private:
XcbUiApplication* application_;
std::optional<xcb_window_t> xcb_window_;
- cairo_surface_t *cairo_surface_;
+ cairo_surface_t* cairo_surface_;
Size current_size_;
+ XcbWindow* parent_;
+
Event<std::nullptr_t> create_event_;
Event<std::nullptr_t> destroy_event_;
Event<std::nullptr_t> paint_event_;
diff --git a/src/platform/CMakeLists.txt b/src/platform/CMakeLists.txt
index 63ef9058..cfa9e74d 100644
--- a/src/platform/CMakeLists.txt
+++ b/src/platform/CMakeLists.txt
@@ -1,8 +1,8 @@
add_library(CruPlatformBase
- ForDllExport.cpp
Color.cpp
Exception.cpp
GraphicsBase.cpp
+ Resource.cpp
)
target_link_libraries(CruPlatformBase PUBLIC CruBase)
target_compile_definitions(CruPlatformBase PRIVATE CRU_PLATFORM_EXPORT_API)
diff --git a/src/platform/Exception.cpp b/src/platform/Exception.cpp
index d5ae4702..744404e0 100644
--- a/src/platform/Exception.cpp
+++ b/src/platform/Exception.cpp
@@ -8,7 +8,7 @@
namespace cru::platform {
PlatformNotMatchException::PlatformNotMatchException(
std::string resource_platform, std::string target_platform,
- std::optional<std::string> additional_message)
+ std::optional<std::string_view> additional_message)
: PlatformException(std::format(
"Resource platform '{}' does not match target platform '{}'.",
resource_platform_, target_platform_)),
diff --git a/src/platform/ForDllExport.cpp b/src/platform/ForDllExport.cpp
deleted file mode 100644
index a0421317..00000000
--- a/src/platform/ForDllExport.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "cru/platform/Exception.h"
-#include "cru/platform/Resource.h"
diff --git a/src/platform/Resource.cpp b/src/platform/Resource.cpp
new file mode 100644
index 00000000..d0dbf53b
--- /dev/null
+++ b/src/platform/Resource.cpp
@@ -0,0 +1,7 @@
+#include "cru/platform/Resource.h"
+
+namespace cru::platform {
+std::string IPlatformResource::GetPlatformIdUtf8() const {
+ return GetPlatformId().ToUtf8();
+}
+} // namespace cru::platform
diff --git a/src/platform/gui/xcb/Window.cpp b/src/platform/gui/xcb/Window.cpp
index 29c31527..9dd510e9 100644
--- a/src/platform/gui/xcb/Window.cpp
+++ b/src/platform/gui/xcb/Window.cpp
@@ -1,4 +1,5 @@
#include "cru/platform/gui/xcb/Window.h"
+#include "cru/platform/Check.h"
#include "cru/platform/graphics/Painter.h"
#include "cru/platform/graphics/cairo/CairoPainter.h"
#include "cru/platform/gui/Base.h"
@@ -57,12 +58,34 @@ KeyModifier ConvertModifiers(uint32_t mask) {
XcbWindow::XcbWindow(XcbUiApplication *application)
: application_(application),
xcb_window_(std::nullopt),
- cairo_surface_(nullptr) {
+ cairo_surface_(nullptr),
+ parent_(nullptr) {
application->RegisterWindow(this);
}
XcbWindow::~XcbWindow() { application_->UnregisterWindow(this); }
+void XcbWindow::Close() {
+ if (xcb_window_) {
+ xcb_destroy_window(application_->GetXcbConnection(), *xcb_window_);
+ }
+}
+
+INativeWindow *XcbWindow::GetParent() { return parent_; }
+
+void XcbWindow::SetParent(INativeWindow *parent) {
+ parent_ = CheckPlatform<XcbWindow>(parent, GetPlatformIdUtf8());
+ if (xcb_window_) {
+ auto real_parent = application_->GetFirstXcbScreen()->root;
+ if (parent_ && parent_->xcb_window_) {
+ real_parent = *parent_->xcb_window_;
+ }
+ xcb_reparent_window(application_->GetXcbConnection(), *xcb_window_,
+ real_parent, 0, 0);
+ // TODO: Maybe restore position?
+ }
+}
+
std::unique_ptr<graphics::IPainter> XcbWindow::BeginPaint() {
assert(cairo_surface_);