diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/cru/platform/native/ui_application.hpp | 5 | ||||
-rw-r--r-- | include/cru/platform/native/window.hpp | 24 | ||||
-rw-r--r-- | include/cru/ui/window.hpp | 34 | ||||
-rw-r--r-- | include/cru/win/native/ui_application.hpp | 2 | ||||
-rw-r--r-- | include/cru/win/native/window.hpp | 42 |
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 |