diff options
author | crupest <crupest@outlook.com> | 2019-06-14 00:44:14 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2019-06-14 00:44:14 +0800 |
commit | 5ec370e5f91ad8b5ed7717eb93f4e3240ea4e784 (patch) | |
tree | 970188397f236715d3d021ddcfcbdeeee73ee860 /include/cru | |
parent | 7b1e9fd2410c9d4fafbe5de9459b18775e6cc465 (diff) | |
download | cru-5ec370e5f91ad8b5ed7717eb93f4e3240ea4e784.tar.gz cru-5ec370e5f91ad8b5ed7717eb93f4e3240ea4e784.tar.bz2 cru-5ec370e5f91ad8b5ed7717eb93f4e3240ea4e784.zip |
...
Diffstat (limited to 'include/cru')
-rw-r--r-- | include/cru/common/base.hpp | 5 | ||||
-rw-r--r-- | include/cru/common/event.hpp | 57 | ||||
-rw-r--r-- | include/cru/platform/native/native_event.hpp | 12 | ||||
-rw-r--r-- | include/cru/platform/native/native_window.hpp | 23 | ||||
-rw-r--r-- | include/cru/ui/window.hpp | 21 | ||||
-rw-r--r-- | include/cru/win/native/win_native_window.hpp | 36 |
6 files changed, 97 insertions, 57 deletions
diff --git a/include/cru/common/base.hpp b/include/cru/common/base.hpp index 7dfe8240..d72b97f2 100644 --- a/include/cru/common/base.hpp +++ b/include/cru/common/base.hpp @@ -13,6 +13,11 @@ class Object { }; struct Interface { + Interface() = default; + Interface(const Interface& other) = delete; + Interface(Interface&& other) = delete; + Interface& operator=(const Interface& other) = delete; + Interface& operator=(Interface&& other) = delete; virtual ~Interface() = default; }; } // namespace cru diff --git a/include/cru/common/event.hpp b/include/cru/common/event.hpp index d8a24330..af282c30 100644 --- a/include/cru/common/event.hpp +++ b/include/cru/common/event.hpp @@ -79,13 +79,44 @@ inline EventRevoker details::EventBase::CreateRevoker(EventHandlerToken token) { return EventRevoker(resolver_, token); } +template <typename TRaw> +using DeducedEventArgs = std::conditional_t< + std::is_lvalue_reference_v<TRaw>, TRaw, + std::conditional_t<std::is_scalar_v<TRaw>, TRaw, const TRaw&>>; + +// Provides an interface of event. +// +// Note that this class does not inherit Interface because Interface is +// public destructable, but I want to make this class not public +// destructable to prevent user from destructing it. +// +// IEvent only allow to add handler but not to raise the event. You may +// want to create an Event object and expose IEvent only so users won't +// be able to emit the event. +template <typename TEventArgs> +struct IEvent { + public: + using EventArgs = DeducedEventArgs<TEventArgs>; + using EventHandler = std::function<void(EventArgs)>; + + protected: + IEvent() = default; + IEvent(const IEvent& other) = delete; + IEvent(IEvent&& other) = delete; + IEvent& operator=(const IEvent& other) = delete; + IEvent& operator=(IEvent&& other) = delete; + ~IEvent() = default; + + public: + virtual EventRevoker AddHandler(const EventHandler& handler) = 0; + virtual EventRevoker AddHandler(EventHandler&& handler) = 0; +}; + // A non-copyable non-movable Event class. // It stores a list of event handlers. -template <typename... TArgs> -class Event : public details::EventBase { +template <typename TEventArgs> +class Event : public details::EventBase, public IEvent<TEventArgs> { public: - using EventHandler = std::function<void(TArgs...)>; - Event() = default; Event(const Event&) = delete; Event& operator=(const Event&) = delete; @@ -93,36 +124,26 @@ class Event : public details::EventBase { Event& operator=(Event&&) = delete; ~Event() = default; - EventRevoker AddHandler(const EventHandler& handler) { + EventRevoker AddHandler(const EventHandler& handler) override { const auto token = current_token_++; handlers_.emplace(token, handler); return CreateRevoker(token); } - EventRevoker AddHandler(EventHandler&& handler) { + EventRevoker AddHandler(EventHandler&& handler) override { const auto token = current_token_++; handlers_.emplace(token, std::move(handler)); return CreateRevoker(token); } - template <typename FArg> - EventRevoker AddHandler(FArg&& handler) { - static_assert(std::is_invocable_v<FArg, TArgs...>, - "Handler not invocable."); - const auto token = current_token_++; - handlers_.emplace(token, EventHandler(std::forward<FArg>(handler))); - return CreateRevoker(token); - } - - template <typename... FArg> - void Raise(FArg&&... args) { + void Raise(EventArgs args) { // copy the handlers to a list, because the handler might be removed // during executing, and the handler with its data will be destroyed. // if the handler is a lambda with member data, then the member data // will be destroyed and result in seg fault. std::list<EventHandler> handlers; for (const auto& [key, handler] : handlers_) handlers.push_back(handler); - for (const auto& handler : handlers) handler(std::forward<FArg>(args)...); + for (const auto& handler : handlers) handler(args); } protected: diff --git a/include/cru/platform/native/native_event.hpp b/include/cru/platform/native/native_event.hpp new file mode 100644 index 00000000..21db5f90 --- /dev/null +++ b/include/cru/platform/native/native_event.hpp @@ -0,0 +1,12 @@ +#pragma once +#include "cru/common/base.hpp" + +#include "basic_types.hpp" +#include "cru/common/ui_base.hpp" + +namespace cru::platform::native { +struct NativeMouseButtonEventArgs { + MouseButton button; + ui::Point point; +}; +} // namespace cru::platform::native diff --git a/include/cru/platform/native/native_window.hpp b/include/cru/platform/native/native_window.hpp index 3a0fd3e1..3e83a531 100644 --- a/include/cru/platform/native/native_window.hpp +++ b/include/cru/platform/native/native_window.hpp @@ -4,6 +4,7 @@ #include "basic_types.hpp" #include "cru/common/event.hpp" #include "cru/common/ui_base.hpp" +#include "native_event.hpp" namespace cru::platform::graph { struct IPainter; @@ -36,15 +37,15 @@ struct INativeWindow : public virtual Interface { virtual graph::IPainter* BeginPaint() = 0; - virtual Event<>* DestroyEvent() = 0; - virtual Event<const ui::Size&>* ResizeEvent() = 0; - virtual Event<>* PaintEvent() = 0; - virtual Event<bool>* FocusEvent() = 0; - virtual Event<bool>* MouseEnterLeaveEvent() = 0; - virtual Event<const ui::Point&>* MouseMoveEvent() = 0; - virtual Event<MouseButton, const ui::Point&>* MouseDownEvent() = 0; - virtual Event<MouseButton, const ui::Point&>* MouseUpEvent() = 0; - virtual Event<int>* KeyDownEvent() = 0; - virtual Event<int>* KeyUpEvent() = 0; + virtual IEvent<std::nullptr_t>* DestroyEvent() = 0; + virtual IEvent<std::nullptr_t>* PaintEvent() = 0; + virtual IEvent<ui::Size>* ResizeEvent() = 0; + virtual IEvent<bool>* FocusEvent() = 0; + virtual IEvent<bool>* MouseEnterLeaveEvent() = 0; + virtual IEvent<ui::Point>* MouseMoveEvent() = 0; + virtual IEvent<NativeMouseButtonEventArgs>* MouseDownEvent() = 0; + virtual IEvent<NativeMouseButtonEventArgs>* MouseUpEvent() = 0; + virtual IEvent<int>* KeyDownEvent() = 0; + virtual IEvent<int>* KeyUpEvent() = 0; }; -} // namespace cru::platform::ui +} // namespace cru::platform::native diff --git a/include/cru/ui/window.hpp b/include/cru/ui/window.hpp index 2ed05192..4bc0e41d 100644 --- a/include/cru/ui/window.hpp +++ b/include/cru/ui/window.hpp @@ -1,6 +1,7 @@ #pragma once #include "content_control.hpp" +#include "cru/platform/native/native_event.hpp" #include "event/ui_event.hpp" #include <memory> @@ -39,7 +40,9 @@ class Window final : public ContentControl { render::RenderObject* GetRenderObject() const override; - platform::native::INativeWindow* GetNativeWindow() const { return native_window_; } + platform::native::INativeWindow* GetNativeWindow() const { + return native_window_; + } Control* GetMouseHoverControl() const { return mouse_hover_control_; } @@ -59,18 +62,18 @@ class Window final : public ContentControl { //*************** region: native messages *************** - void OnNativeDestroy(); - void OnNativePaint(); + void OnNativeDestroy(std::nullptr_t); + void OnNativePaint(std::nullptr_t); void OnNativeResize(const Size& size); void OnNativeFocus(bool focus); void OnNativeMouseEnterLeave(bool enter); void OnNativeMouseMove(const Point& point); - void OnNativeMouseDown(platform::native::MouseButton button, - const Point& point); - void OnNativeMouseUp(platform::native::MouseButton button, - const Point& point); + void OnNativeMouseDown( + const platform::native::NativeMouseButtonEventArgs& args); + void OnNativeMouseUp( + const platform::native::NativeMouseButtonEventArgs& args); void OnNativeKeyDown(int virtual_code); void OnNativeKeyUp(int virtual_code); @@ -87,8 +90,8 @@ class Window final : public ContentControl { std::shared_ptr<render::WindowRenderObject> render_object_; - Control* mouse_hover_control_ = nullptr; + Control* mouse_hover_control_; - Control* focus_control_ = this; // "focus_control_" can't be nullptr + Control* focus_control_; // "focus_control_" can't be nullptr }; } // namespace cru::ui diff --git a/include/cru/win/native/win_native_window.hpp b/include/cru/win/native/win_native_window.hpp index 0fafc7fd..18de4f5d 100644 --- a/include/cru/win/native/win_native_window.hpp +++ b/include/cru/win/native/win_native_window.hpp @@ -47,28 +47,26 @@ class WinNativeWindow : public Object, platform::graph::IPainter* BeginPaint() override; - Event<>* DestroyEvent() override { return &destroy_event_; } - Event<const ui::Size&>* ResizeEvent() override { return &resize_event_; } - Event<>* PaintEvent() override { return &paint_event_; } - Event<bool>* FocusEvent() override { return &focus_event_; } - Event<bool>* MouseEnterLeaveEvent() override { + IEvent<std::nullptr_t>* DestroyEvent() override { return &destroy_event_; } + IEvent<std::nullptr_t>* PaintEvent() override { return &paint_event_; } + IEvent<ui::Size>* ResizeEvent() override { return &resize_event_; } + IEvent<bool>* FocusEvent() override { return &focus_event_; } + IEvent<bool>* MouseEnterLeaveEvent() override { return &mouse_enter_leave_event_; } - Event<const ui::Point&>* MouseMoveEvent() override { - return &mouse_move_event_; - } - Event<platform::native::MouseButton, const ui::Point&>* MouseDownEvent() + IEvent<ui::Point>* MouseMoveEvent() override { return &mouse_move_event_; } + IEvent<platform::native::NativeMouseButtonEventArgs>* MouseDownEvent() override { return &mouse_down_event_; } - Event<platform::native::MouseButton, const ui::Point&>* MouseUpEvent() + IEvent<platform::native::NativeMouseButtonEventArgs>* MouseUpEvent() override { return &mouse_up_event_; } - Event<int>* KeyDownEvent() override { return &key_down_event_; } - Event<int>* KeyUpEvent() override { return &key_up_event_; } + IEvent<int>* KeyDownEvent() override { return &key_down_event_; } + IEvent<int>* KeyUpEvent() override { return &key_up_event_; } - Event<WindowNativeMessageEventArgs&>* NativeMessageEvent() { + IEvent<WindowNativeMessageEventArgs&>* NativeMessageEvent() { return &native_message_event_; } @@ -121,14 +119,14 @@ class WinNativeWindow : public Object, std::shared_ptr<WindowRenderTarget> window_render_target_; - Event<> destroy_event_; - Event<const ui::Size&> resize_event_; - Event<> paint_event_; + Event<std::nullptr_t> destroy_event_; + Event<std::nullptr_t> paint_event_; + Event<ui::Size> resize_event_; Event<bool> focus_event_; Event<bool> mouse_enter_leave_event_; - Event<const ui::Point&> mouse_move_event_; - Event<platform::native::MouseButton, const ui::Point&> mouse_down_event_; - Event<platform::native::MouseButton, const ui::Point&> mouse_up_event_; + Event<ui::Point> mouse_move_event_; + Event<platform::native::NativeMouseButtonEventArgs> mouse_down_event_; + Event<platform::native::NativeMouseButtonEventArgs> mouse_up_event_; Event<int> key_down_event_; Event<int> key_up_event_; |