aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/cru/platform/native/ui_application.hpp5
-rw-r--r--include/cru/platform/native/window.hpp24
-rw-r--r--include/cru/ui/window.hpp34
-rw-r--r--include/cru/win/native/ui_application.hpp2
-rw-r--r--include/cru/win/native/window.hpp42
5 files changed, 74 insertions, 33 deletions
diff --git a/include/cru/platform/native/ui_application.hpp b/include/cru/platform/native/ui_application.hpp
index b69b1f52..edbcc578 100644
--- a/include/cru/platform/native/ui_application.hpp
+++ b/include/cru/platform/native/ui_application.hpp
@@ -3,6 +3,7 @@
#include <chrono>
#include <functional>
+#include <memory>
#include <vector>
namespace cru::platform::graph {
@@ -11,6 +12,7 @@ struct IGraphFactory;
namespace cru::platform::native {
struct INativeWindow;
+struct INativeWindowResolver;
struct ICursorManager;
// The entry point of a ui application.
@@ -39,7 +41,8 @@ struct IUiApplication : public virtual INativeResource {
virtual void CancelTimer(unsigned long id) = 0;
virtual std::vector<INativeWindow*> GetAllWindow() = 0;
- virtual INativeWindow* CreateWindow(INativeWindow* parent) = 0;
+ virtual std::shared_ptr<INativeWindowResolver> CreateWindow(
+ INativeWindow* parent) = 0;
virtual cru::platform::graph::IGraphFactory* GetGraphFactory() = 0;
diff --git a/include/cru/platform/native/window.hpp b/include/cru/platform/native/window.hpp
index bfaf170b..84193a13 100644
--- a/include/cru/platform/native/window.hpp
+++ b/include/cru/platform/native/window.hpp
@@ -12,22 +12,17 @@ struct IPainter;
}
namespace cru::platform::native {
+struct INativeWindowResolver;
+
// Represents a native window, which exposes some low-level events and
// operations.
//
-// Although you can always retain an instance of this class, the real window
-// associated with it might be have already been destroyed by explicitly calling
-// Close or closed by the user, which leads to an invalid instance. You can
-// check the validity by IsValid. When you call perform native operations on the
-// invalid instance, there is no effect.
+// Usually you save an INativeWindowResolver after creating a window. Because
+// window may be destroyed when user do certain actions like click the close
+// button. Then the INativeWindow instance is destroyed and
+// INativeWindowResolver::Resolve return nullptr to indicate the fact.
struct INativeWindow : virtual INativeResource {
- // Return if the window is still valid, that is, hasn't been closed or
- // destroyed.
- virtual bool IsValid() = 0;
-
- // Set if the instance is deleted automatically when the window is destroyed
- // by other ways. Default is true.
- virtual void SetDeleteThisOnDestroy(bool value) = 0;
+ virtual std::shared_ptr<INativeWindowResolver> GetResolver() = 0;
virtual void Close() = 0;
@@ -71,4 +66,9 @@ struct INativeWindow : virtual INativeResource {
virtual IEvent<int>* KeyDownEvent() = 0;
virtual IEvent<int>* KeyUpEvent() = 0;
};
+
+// See INativeWindow for more info.
+struct INativeWindowResolver : virtual INativeResource {
+ virtual INativeWindow* Resolve() = 0;
+};
} // namespace cru::platform::native
diff --git a/include/cru/ui/window.hpp b/include/cru/ui/window.hpp
index 35d6772e..105063d9 100644
--- a/include/cru/ui/window.hpp
+++ b/include/cru/ui/window.hpp
@@ -9,7 +9,8 @@
namespace cru::platform::native {
struct INativeWindow;
-}
+struct INativeWindowResolver;
+} // namespace cru::platform::native
namespace cru::ui {
namespace render {
@@ -38,13 +39,11 @@ class Window final : public ContentControl, public SelfResolvable<Window> {
~Window() override;
public:
- std::string_view GetControlType() const override final;
+ std::string_view GetControlType() const final;
render::RenderObject* GetRenderObject() const override;
- platform::native::INativeWindow* GetNativeWindow() const {
- return native_window_;
- }
+ platform::native::INativeWindow* GetNativeWindow();
// Get current control that mouse hovers on. This ignores the mouse-capture
// control. Even when mouse is captured by another control, this function
@@ -85,22 +84,29 @@ class Window final : public ContentControl, public SelfResolvable<Window> {
//*************** region: native messages ***************
- void OnNativeDestroy(std::nullptr_t);
- void OnNativePaint(std::nullptr_t);
- void OnNativeResize(const Size& size);
+ void OnNativeDestroy(platform::native::INativeWindow* window, std::nullptr_t);
+ void OnNativePaint(platform::native::INativeWindow* window, std::nullptr_t);
+ void OnNativeResize(platform::native::INativeWindow* window,
+ const Size& size);
- void OnNativeFocus(cru::platform::native::FocusChangeType focus);
+ void OnNativeFocus(platform::native::INativeWindow* window,
+ cru::platform::native::FocusChangeType focus);
void OnNativeMouseEnterLeave(
+ platform::native::INativeWindow* window,
cru::platform::native::MouseEnterLeaveType enter);
- void OnNativeMouseMove(const Point& point);
+ void OnNativeMouseMove(platform::native::INativeWindow* window,
+ const Point& point);
void OnNativeMouseDown(
+ platform::native::INativeWindow* window,
const platform::native::NativeMouseButtonEventArgs& args);
void OnNativeMouseUp(
+ platform::native::INativeWindow* window,
const platform::native::NativeMouseButtonEventArgs& args);
- void OnNativeKeyDown(int virtual_code);
- void OnNativeKeyUp(int virtual_code);
+ void OnNativeKeyDown(platform::native::INativeWindow* window,
+ int virtual_code);
+ void OnNativeKeyUp(platform::native::INativeWindow* window, int virtual_code);
//*************** region: event dispatcher helper ***************
@@ -112,7 +118,9 @@ class Window final : public ContentControl, public SelfResolvable<Window> {
void UpdateCursor();
private:
- platform::native::INativeWindow* native_window_;
+ std::shared_ptr<platform::native::INativeWindowResolver>
+ native_window_resolver_;
+
std::vector<EventRevokerGuard> event_revoker_guards_;
std::unique_ptr<render::WindowRenderObject> render_object_;
diff --git a/include/cru/win/native/ui_application.hpp b/include/cru/win/native/ui_application.hpp
index 80e358e4..73f67abe 100644
--- a/include/cru/win/native/ui_application.hpp
+++ b/include/cru/win/native/ui_application.hpp
@@ -45,7 +45,7 @@ class WinUiApplication : public WinNativeResource,
void CancelTimer(unsigned long id) override;
std::vector<INativeWindow*> GetAllWindow() override;
- INativeWindow* CreateWindow(INativeWindow* parent) override;
+ std::shared_ptr<INativeWindowResolver> CreateWindow(INativeWindow* parent) override;
cru::platform::graph::IGraphFactory* GetGraphFactory() override;
diff --git a/include/cru/win/native/window.hpp b/include/cru/win/native/window.hpp
index 9752682f..3c883338 100644
--- a/include/cru/win/native/window.hpp
+++ b/include/cru/win/native/window.hpp
@@ -12,12 +12,12 @@ class WinCursor;
class WindowClass;
class WindowManager;
class WindowRenderTarget;
+class WinNativeWindowResolver;
class WinNativeWindow : public WinNativeResource, public virtual INativeWindow {
public:
- WinNativeWindow(WinUiApplication* application,
- WindowClass* window_class, DWORD window_style,
- WinNativeWindow* parent);
+ WinNativeWindow(WinUiApplication* application, WindowClass* window_class,
+ DWORD window_style, WinNativeWindow* parent);
CRU_DELETE_COPY(WinNativeWindow)
CRU_DELETE_MOVE(WinNativeWindow)
@@ -25,8 +25,9 @@ class WinNativeWindow : public WinNativeResource, public virtual INativeWindow {
~WinNativeWindow() override;
public:
- bool IsValid() override;
- void SetDeleteThisOnDestroy(bool value) override;
+ std::shared_ptr<INativeWindowResolver> GetResolver() override {
+ return std::static_pointer_cast<INativeWindowResolver>(resolver_);
+ }
void Close() override;
@@ -118,7 +119,14 @@ class WinNativeWindow : public WinNativeResource, public virtual INativeWindow {
private:
WinUiApplication* application_;
- bool delete_this_on_destroy_ = true;
+ // when delete is called first, it set this to true to indicate
+ // destroy message handler not to double delete this instance;
+ // when destroy handler is called first (by user action or method
+ // Close), it set this to true to indicate delete not call Close
+ // again.
+ bool sync_flag_ = false;
+
+ std::shared_ptr<WinNativeWindowResolver> resolver_;
HWND hwnd_;
WinNativeWindow* parent_window_;
@@ -143,4 +151,26 @@ class WinNativeWindow : public WinNativeResource, public virtual INativeWindow {
Event<WindowNativeMessageEventArgs&> native_message_event_;
};
+
+class WinNativeWindowResolver : public WinNativeResource,
+ public virtual INativeWindowResolver {
+ friend WinNativeWindow::~WinNativeWindow();
+
+ public:
+ WinNativeWindowResolver(WinNativeWindow* window) : window_(window) {}
+
+ CRU_DELETE_COPY(WinNativeWindowResolver)
+ CRU_DELETE_MOVE(WinNativeWindowResolver)
+
+ ~WinNativeWindowResolver() override = default;
+
+ public:
+ INativeWindow* Resolve() override { return window_; }
+
+ private:
+ void Reset();
+
+ private:
+ WinNativeWindow* window_;
+};
} // namespace cru::platform::native::win