diff options
34 files changed, 275 insertions, 395 deletions
diff --git a/include/cru/base/Event.h b/include/cru/base/Event.h index 18d2c570..1f57e100 100644 --- a/include/cru/base/Event.h +++ b/include/cru/base/Event.h @@ -11,58 +11,36 @@ #include <vector> namespace cru { -class EventRevoker; +class EventHandlerRevoker; -namespace details { -template <class> -inline constexpr bool always_false_v = false; - -// Base class of all Event<T...>. -// It erases event args types and provides a -// unified form to create event revoker and -// revoke(remove) handler. -class EventBase : public SelfResolvable<EventBase> { - friend EventRevoker; +class EventBase : public Object, public SelfResolvable<EventBase> { + friend EventHandlerRevoker; protected: - using EventHandlerToken = long; - - EventBase() {} - CRU_DELETE_COPY(EventBase) - CRU_DEFAULT_MOVE(EventBase) - virtual ~EventBase() = default; + using EventHandlerToken = int; - // Remove the handler with the given token. If the token - // corresponds to no handler (which might have be revoked - // before), then nothing will be done. + /** + * Remove the handler with the given token. If the token corresponds to no + * handler (which might have be revoked before), then nothing will be done. + */ virtual void RemoveHandler(EventHandlerToken token) = 0; - // Create a revoker with the given token. - inline EventRevoker CreateRevoker(EventHandlerToken token); + inline EventHandlerRevoker CreateRevoker(EventHandlerToken token); }; -} // namespace details -// A non-copyable and movable event revoker. -// Call function call operator to revoke the handler. -class EventRevoker { - friend details::EventBase; +class EventHandlerRevoker { + friend EventBase; private: - EventRevoker(ObjectResolver<details::EventBase>&& resolver, - details::EventBase::EventHandlerToken token) + EventHandlerRevoker(ObjectResolver<EventBase>&& resolver, + EventBase::EventHandlerToken token) : resolver_(std::move(resolver)), token_(token) {} public: - EventRevoker(const EventRevoker& other) = default; - EventRevoker(EventRevoker&& other) = default; - EventRevoker& operator=(const EventRevoker& other) = default; - EventRevoker& operator=(EventRevoker&& other) = default; - ~EventRevoker() = default; - - // Revoke the registered handler. If the event has already - // been destroyed, then nothing will be done. If one of the - // copies calls this, then other copies's calls will have no - // effect. (They have the same token.) + /** + * Revoke the registered handler. If the event has already been destroyed or + * the handler is already revoked, nothing will be done. + */ void operator()() const { if (const auto event = resolver_.Resolve()) { event->RemoveHandler(token_); @@ -70,34 +48,17 @@ class EventRevoker { } private: - ObjectResolver<details::EventBase> resolver_; - details::EventBase::EventHandlerToken token_; + ObjectResolver<EventBase> resolver_; + EventBase::EventHandlerToken token_; }; -inline EventRevoker details::EventBase::CreateRevoker(EventHandlerToken token) { - return EventRevoker(CreateResolver(), token); +inline EventHandlerRevoker EventBase::CreateRevoker(EventHandlerToken token) { + return EventHandlerRevoker(CreateResolver(), token); } -// int -> int -// Point -> const Point& -// int& -> int& -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&>>; - -struct IBaseEvent { - protected: - IBaseEvent() = default; - CRU_DELETE_COPY(IBaseEvent) - CRU_DEFAULT_MOVE(IBaseEvent) - ~IBaseEvent() = default; // Note that user can't destroy a Event via IEvent. - // So destructor should be protected. - +struct IBaseEvent : public virtual Interface { using SpyOnlyHandler = std::function<void()>; - - public: - virtual EventRevoker AddSpyOnlyHandler(SpyOnlyHandler handler) = 0; + virtual EventHandlerRevoker AddSpyOnlyHandler(SpyOnlyHandler handler) = 0; }; // Provides an interface of event. @@ -106,94 +67,52 @@ struct IBaseEvent { // be able to emit the event. template <typename TEventArgs> struct IEvent : virtual IBaseEvent { - public: - using EventArgs = DeducedEventArgs<TEventArgs>; - using EventHandler = std::function<void(EventArgs)>; - using ShortCircuitHandler = std::function<bool(EventArgs)>; - - protected: - IEvent() = default; - CRU_DELETE_COPY(IEvent) - CRU_DEFAULT_MOVE(IEvent) - ~IEvent() = default; // Note that user can't destroy a Event via IEvent. So - // destructor should be protected. - - public: - virtual EventRevoker AddHandler(EventHandler handler) = 0; - virtual EventRevoker AddShortCircuitHandler(ShortCircuitHandler handler) = 0; - virtual EventRevoker PrependShortCircuitHandler( - ShortCircuitHandler handler) = 0; + using Args = TEventArgs; + using Handler = std::function<void(Args)>; + virtual EventHandlerRevoker AddHandler(Handler handler) = 0; }; // A non-copyable non-movable Event class. // It stores a list of event handlers. template <typename TEventArgs> -class Event : public details::EventBase, public IEvent<TEventArgs> { - using typename IEvent<TEventArgs>::EventArgs; +class Event : public EventBase, public IEvent<TEventArgs> { + using typename IEvent<TEventArgs>::Args; using typename IBaseEvent::SpyOnlyHandler; - using typename IEvent<TEventArgs>::EventHandler; - using typename IEvent<TEventArgs>::ShortCircuitHandler; + using typename IEvent<TEventArgs>::Handler; private: struct HandlerData { - HandlerData(EventHandlerToken token, ShortCircuitHandler handler) + HandlerData(EventHandlerToken token, Handler handler) : token(token), handler(std::move(handler)) {} EventHandlerToken token; - ShortCircuitHandler handler; + Handler handler; }; public: - Event() = default; - CRU_DELETE_COPY(Event) - CRU_DEFAULT_MOVE(Event) - ~Event() = default; - - EventRevoker AddSpyOnlyHandler(SpyOnlyHandler handler) override { - return AddShortCircuitHandler([handler = std::move(handler)](EventArgs) { - handler(); - return false; - }); - } - - EventRevoker AddHandler(EventHandler handler) override { - return AddShortCircuitHandler( - [handler = std::move(handler)](EventArgs args) { - handler(args); - return false; - }); + EventHandlerRevoker AddSpyOnlyHandler(SpyOnlyHandler handler) override { + return AddHandler([handler = std::move(handler)](Args) { handler(); }); } - // Handler return true to short circuit following handlers. - EventRevoker AddShortCircuitHandler(ShortCircuitHandler handler) override { + EventHandlerRevoker AddHandler(Handler handler) override { const auto token = current_token_++; this->handler_data_list_.emplace_back(token, std::move(handler)); return CreateRevoker(token); } - // Handler return true to short circuit following handlers. - EventRevoker PrependShortCircuitHandler( - ShortCircuitHandler handler) override { - const auto token = current_token_++; - this->handler_data_list_.emplace(this->handler_data_list_.cbegin(), token, - std::move(handler)); - return CreateRevoker(token); - } - // This method will make a copy of all handlers. Because user might delete a // handler in a handler, which may lead to seg fault as the handler is // deleted while being executed. Thanks to this behavior, all handlers will // be taken a snapshot when Raise is called, so even if you delete a handler // during this period, all handlers in the snapshot will be executed. - void Raise(EventArgs args) { - std::vector<ShortCircuitHandler> handlers; + void Raise(Args args) { + std::vector<Handler> handlers; handlers.reserve(this->handler_data_list_.size()); for (const auto& data : this->handler_data_list_) { handlers.push_back(data.handler); } for (const auto& handler : handlers) { - auto short_circuit = handler(args); - if (short_circuit) return; + handler(args); } } @@ -213,8 +132,8 @@ class Event : public details::EventBase, public IEvent<TEventArgs> { }; namespace details { -struct EventRevokerDestroyer { - void operator()(EventRevoker* p) { +struct EventHandlerRevokerDestroyer { + void operator()(EventHandlerRevoker* p) { (*p)(); delete p; } @@ -222,51 +141,38 @@ struct EventRevokerDestroyer { } // namespace details // A guard class for event revoker. Automatically revoke it when destroyed. -class EventRevokerGuard { +class EventHandlerRevokerGuard { public: - EventRevokerGuard() = default; - explicit EventRevokerGuard(EventRevoker&& revoker) - : revoker_(new EventRevoker(std::move(revoker))) {} - EventRevokerGuard(const EventRevokerGuard& other) = delete; - EventRevokerGuard(EventRevokerGuard&& other) = default; - EventRevokerGuard& operator=(const EventRevokerGuard& other) = delete; - EventRevokerGuard& operator=(EventRevokerGuard&& other) = default; - ~EventRevokerGuard() = default; - - EventRevoker Get() { + EventHandlerRevokerGuard() = default; + explicit EventHandlerRevokerGuard(EventHandlerRevoker&& revoker) + : revoker_(new EventHandlerRevoker(std::move(revoker))) {} + + EventHandlerRevoker Get() { // revoker is only null when this is moved // you shouldn't use a moved instance assert(revoker_); return *revoker_; } - EventRevoker Release() { return std::move(*revoker_.release()); } + EventHandlerRevoker Release() { return std::move(*revoker_.release()); } void Reset() { revoker_.reset(); } - void Reset(EventRevoker&& revoker) { - revoker_.reset(new EventRevoker(std::move(revoker))); + void Reset(EventHandlerRevoker&& revoker) { + revoker_.reset(new EventHandlerRevoker(std::move(revoker))); } private: - std::unique_ptr<EventRevoker, details::EventRevokerDestroyer> revoker_; + std::unique_ptr<EventHandlerRevoker, details::EventHandlerRevokerDestroyer> revoker_; }; -class EventRevokerListGuard { - public: - EventRevokerListGuard() = default; - EventRevokerListGuard(const EventRevokerListGuard& other) = delete; - EventRevokerListGuard(EventRevokerListGuard&& other) = default; - EventRevokerListGuard& operator=(const EventRevokerListGuard& other) = delete; - EventRevokerListGuard& operator=(EventRevokerListGuard&& other) = default; - ~EventRevokerListGuard() = default; - +class EventHandlerRevokerListGuard { public: - void Add(EventRevoker&& revoker) { - event_revoker_guard_list_.push_back(EventRevokerGuard(std::move(revoker))); + void Add(EventHandlerRevoker&& revoker) { + event_revoker_guard_list_.push_back(EventHandlerRevokerGuard(std::move(revoker))); } - EventRevokerListGuard& operator+=(EventRevoker&& revoker) { + EventHandlerRevokerListGuard& operator+=(EventHandlerRevoker&& revoker) { this->Add(std::move(revoker)); return *this; } @@ -276,6 +182,6 @@ class EventRevokerListGuard { bool IsEmpty() const { return event_revoker_guard_list_.empty(); } private: - std::vector<EventRevokerGuard> event_revoker_guard_list_; + std::vector<EventHandlerRevokerGuard> event_revoker_guard_list_; }; } // namespace cru diff --git a/include/cru/platform/gui/InputMethod.h b/include/cru/platform/gui/InputMethod.h index d178cb8a..2d5d0b76 100644 --- a/include/cru/platform/gui/InputMethod.h +++ b/include/cru/platform/gui/InputMethod.h @@ -61,6 +61,6 @@ struct IInputMethodContext : virtual IPlatformResource { virtual IEvent<std::nullptr_t>* CompositionStartEvent() = 0; virtual IEvent<std::nullptr_t>* CompositionEndEvent() = 0; virtual IEvent<std::nullptr_t>* CompositionEvent() = 0; - virtual IEvent<std::string>* TextEvent() = 0; + virtual IEvent<const std::string&>* TextEvent() = 0; }; } // namespace cru::platform::gui diff --git a/include/cru/platform/gui/Window.h b/include/cru/platform/gui/Window.h index 3be5b21b..b8973c5a 100644 --- a/include/cru/platform/gui/Window.h +++ b/include/cru/platform/gui/Window.h @@ -102,16 +102,16 @@ struct CRU_PLATFORM_GUI_API INativeWindow : virtual IPlatformResource { virtual IEvent<std::nullptr_t>* PaintEvent() = 0; virtual IEvent<WindowVisibilityType>* VisibilityChangeEvent() = 0; - virtual IEvent<Size>* ResizeEvent() = 0; + virtual IEvent<const Size&>* ResizeEvent() = 0; virtual IEvent<FocusChangeType>* FocusEvent() = 0; virtual IEvent<MouseEnterLeaveType>* MouseEnterLeaveEvent() = 0; - virtual IEvent<Point>* MouseMoveEvent() = 0; - virtual IEvent<NativeMouseButtonEventArgs>* MouseDownEvent() = 0; - virtual IEvent<NativeMouseButtonEventArgs>* MouseUpEvent() = 0; - virtual IEvent<NativeMouseWheelEventArgs>* MouseWheelEvent() = 0; - virtual IEvent<NativeKeyEventArgs>* KeyDownEvent() = 0; - virtual IEvent<NativeKeyEventArgs>* KeyUpEvent() = 0; + virtual IEvent<const Point&>* MouseMoveEvent() = 0; + virtual IEvent<const NativeMouseButtonEventArgs&>* MouseDownEvent() = 0; + virtual IEvent<const NativeMouseButtonEventArgs&>* MouseUpEvent() = 0; + virtual IEvent<const NativeMouseWheelEventArgs&>* MouseWheelEvent() = 0; + virtual IEvent<const NativeKeyEventArgs&>* KeyDownEvent() = 0; + virtual IEvent<const NativeKeyEventArgs&>* KeyUpEvent() = 0; virtual IInputMethodContext* GetInputMethodContext() = 0; }; diff --git a/include/cru/platform/gui/osx/InputMethod.h b/include/cru/platform/gui/osx/InputMethod.h index 9044a76c..ebb51b3e 100644 --- a/include/cru/platform/gui/osx/InputMethod.h +++ b/include/cru/platform/gui/osx/InputMethod.h @@ -42,7 +42,7 @@ class OsxInputMethodContext : public OsxGuiResource, IEvent<std::nullptr_t>* CompositionEvent() override; - IEvent<std::string>* TextEvent() override; + IEvent<const std::string&>* TextEvent() override; bool IsEnabled(); diff --git a/include/cru/platform/gui/osx/Window.h b/include/cru/platform/gui/osx/Window.h index f4bda28e..e36f4238 100644 --- a/include/cru/platform/gui/osx/Window.h +++ b/include/cru/platform/gui/osx/Window.h @@ -66,16 +66,16 @@ class OsxWindow : public OsxGuiResource, public INativeWindow { IEvent<std::nullptr_t>* PaintEvent() override; IEvent<WindowVisibilityType>* VisibilityChangeEvent() override; - IEvent<Size>* ResizeEvent() override; + IEvent<const Size&>* ResizeEvent() override; IEvent<FocusChangeType>* FocusEvent() override; IEvent<MouseEnterLeaveType>* MouseEnterLeaveEvent() override; - IEvent<Point>* MouseMoveEvent() override; - IEvent<NativeMouseButtonEventArgs>* MouseDownEvent() override; - IEvent<NativeMouseButtonEventArgs>* MouseUpEvent() override; - IEvent<NativeMouseWheelEventArgs>* MouseWheelEvent() override; - IEvent<NativeKeyEventArgs>* KeyDownEvent() override; - IEvent<NativeKeyEventArgs>* KeyUpEvent() override; + IEvent<const Point&>* MouseMoveEvent() override; + IEvent<const NativeMouseButtonEventArgs&>* MouseDownEvent() override; + IEvent<const NativeMouseButtonEventArgs&>* MouseUpEvent() override; + IEvent<const NativeMouseWheelEventArgs&>* MouseWheelEvent() override; + IEvent<const NativeKeyEventArgs&>* KeyDownEvent() override; + IEvent<const NativeKeyEventArgs&>* KeyUpEvent() override; IInputMethodContext* GetInputMethodContext() override; diff --git a/include/cru/platform/gui/sdl/Window.h b/include/cru/platform/gui/sdl/Window.h index c818ecce..8ffadd02 100644 --- a/include/cru/platform/gui/sdl/Window.h +++ b/include/cru/platform/gui/sdl/Window.h @@ -64,16 +64,16 @@ class SdlWindow : public SdlResource, public virtual INativeWindow { IEvent<std::nullptr_t>* PaintEvent() override; IEvent<WindowVisibilityType>* VisibilityChangeEvent() override; - IEvent<Size>* ResizeEvent() override; + IEvent<const Size&>* ResizeEvent() override; IEvent<FocusChangeType>* FocusEvent() override; IEvent<MouseEnterLeaveType>* MouseEnterLeaveEvent() override; - IEvent<Point>* MouseMoveEvent() override; - IEvent<NativeMouseButtonEventArgs>* MouseDownEvent() override; - IEvent<NativeMouseButtonEventArgs>* MouseUpEvent() override; - IEvent<NativeMouseWheelEventArgs>* MouseWheelEvent() override; - IEvent<NativeKeyEventArgs>* KeyDownEvent() override; - IEvent<NativeKeyEventArgs>* KeyUpEvent() override; + IEvent<const Point&>* MouseMoveEvent() override; + IEvent<const NativeMouseButtonEventArgs&>* MouseDownEvent() override; + IEvent<const NativeMouseButtonEventArgs&>* MouseUpEvent() override; + IEvent<const NativeMouseWheelEventArgs&>* MouseWheelEvent() override; + IEvent<const NativeKeyEventArgs&>* KeyDownEvent() override; + IEvent<const NativeKeyEventArgs&>* KeyUpEvent() override; IInputMethodContext* GetInputMethodContext() override; @@ -91,14 +91,14 @@ class SdlWindow : public SdlResource, public virtual INativeWindow { Event<std::nullptr_t> destroy_event_; Event<std::nullptr_t> paint_event_; Event<WindowVisibilityType> visibility_change_event_; - Event<Size> resize_event_; + Event<const Size&> resize_event_; Event<FocusChangeType> focus_event_; Event<MouseEnterLeaveType> mouse_enter_leave_event_; - Event<Point> mouse_move_event_; - Event<NativeMouseButtonEventArgs> mouse_down_event_; - Event<NativeMouseButtonEventArgs> mouse_up_event_; - Event<NativeMouseWheelEventArgs> mouse_wheel_event_; - Event<NativeKeyEventArgs> key_down_event_; - Event<NativeKeyEventArgs> key_up_event_; + Event<const Point&> mouse_move_event_; + Event<const NativeMouseButtonEventArgs&> mouse_down_event_; + Event<const NativeMouseButtonEventArgs&> mouse_up_event_; + Event<const NativeMouseWheelEventArgs&> mouse_wheel_event_; + Event<const NativeKeyEventArgs&> key_down_event_; + Event<const NativeKeyEventArgs&> key_up_event_; }; } // namespace cru::platform::gui::xcb diff --git a/include/cru/platform/gui/win/InputMethod.h b/include/cru/platform/gui/win/InputMethod.h index c246cbd7..fa4d5882 100644 --- a/include/cru/platform/gui/win/InputMethod.h +++ b/include/cru/platform/gui/win/InputMethod.h @@ -66,7 +66,7 @@ class CRU_WIN_GUI_API WinInputMethodContext IEvent<std::nullptr_t>* CompositionEvent() override; - IEvent<std::string>* TextEvent() override; + IEvent<const std::string&>* TextEvent() override; private: void OnWindowNativeMessage(WindowNativeMessageEventArgs& args); @@ -78,11 +78,11 @@ class CRU_WIN_GUI_API WinInputMethodContext private: WinNativeWindow* native_window_; - EventRevokerListGuard event_guard_; + EventHandlerRevokerListGuard event_guard_; Event<std::nullptr_t> composition_start_event_; Event<std::nullptr_t> composition_end_event_; Event<std::nullptr_t> composition_event_; - Event<std::string> text_event_; + Event<const std::string&> text_event_; }; } // namespace cru::platform::gui::win diff --git a/include/cru/platform/gui/win/Window.h b/include/cru/platform/gui/win/Window.h index cd720fbd..f315f3d3 100644 --- a/include/cru/platform/gui/win/Window.h +++ b/include/cru/platform/gui/win/Window.h @@ -69,19 +69,19 @@ class CRU_WIN_GUI_API WinNativeWindow : public WinNativeResource, IEvent<WindowVisibilityType>* VisibilityChangeEvent() override { return &visibility_change_event_; } - IEvent<Size>* ResizeEvent() override { return &resize_event_; } + IEvent<const Size&>* ResizeEvent() override { return &resize_event_; } IEvent<FocusChangeType>* FocusEvent() override { return &focus_event_; } IEvent<MouseEnterLeaveType>* MouseEnterLeaveEvent() override { return &mouse_enter_leave_event_; } - IEvent<Point>* MouseMoveEvent() override { return &mouse_move_event_; } + IEvent<const Point&>* MouseMoveEvent() override { return &mouse_move_event_; } IEvent<platform::gui::NativeMouseButtonEventArgs>* MouseDownEvent() override { return &mouse_down_event_; } IEvent<platform::gui::NativeMouseButtonEventArgs>* MouseUpEvent() override { return &mouse_up_event_; } - IEvent<NativeMouseWheelEventArgs>* MouseWheelEvent() override { + IEvent<const NativeMouseWheelEventArgs&>* MouseWheelEvent() override { return &mouse_wheel_event_; } @@ -200,11 +200,11 @@ class CRU_WIN_GUI_API WinNativeWindow : public WinNativeResource, Event<std::nullptr_t> create_event_; Event<std::nullptr_t> destroy_event_; Event<std::nullptr_t> paint_event_; - Event<Size> resize_event_; + Event<const Size&> resize_event_; Event<WindowVisibilityType> visibility_change_event_; Event<FocusChangeType> focus_event_; Event<MouseEnterLeaveType> mouse_enter_leave_event_; - Event<Point> mouse_move_event_; + Event<const Point&> mouse_move_event_; Event<platform::gui::NativeMouseButtonEventArgs> mouse_down_event_; Event<platform::gui::NativeMouseButtonEventArgs> mouse_up_event_; Event<platform::gui::NativeMouseWheelEventArgs> mouse_wheel_event_; diff --git a/include/cru/platform/gui/xcb/InputMethod.h b/include/cru/platform/gui/xcb/InputMethod.h index e32ed63e..710ea2e5 100644 --- a/include/cru/platform/gui/xcb/InputMethod.h +++ b/include/cru/platform/gui/xcb/InputMethod.h @@ -67,7 +67,7 @@ class XcbXimInputMethodContext : public XcbResource, IEvent<std::nullptr_t>* CompositionStartEvent() override; IEvent<std::nullptr_t>* CompositionEndEvent() override; IEvent<std::nullptr_t>* CompositionEvent() override; - IEvent<std::string>* TextEvent() override; + IEvent<const std::string&>* TextEvent() override; private: void CreateIc(xcb_window_t window); @@ -84,6 +84,6 @@ class XcbXimInputMethodContext : public XcbResource, Event<std::nullptr_t> composition_start_event_; Event<std::nullptr_t> composition_end_event_; Event<std::nullptr_t> composition_event_; - Event<std::string> text_event_; + Event<const std::string&> text_event_; }; } // namespace cru::platform::gui::xcb diff --git a/include/cru/platform/gui/xcb/Window.h b/include/cru/platform/gui/xcb/Window.h index bfd86297..4cb5f6da 100644 --- a/include/cru/platform/gui/xcb/Window.h +++ b/include/cru/platform/gui/xcb/Window.h @@ -68,16 +68,16 @@ class XcbWindow : public XcbResource, public virtual INativeWindow { IEvent<std::nullptr_t>* PaintEvent() override; IEvent<WindowVisibilityType>* VisibilityChangeEvent() override; - IEvent<Size>* ResizeEvent() override; + IEvent<const Size&>* ResizeEvent() override; IEvent<FocusChangeType>* FocusEvent() override; IEvent<MouseEnterLeaveType>* MouseEnterLeaveEvent() override; - IEvent<Point>* MouseMoveEvent() override; - IEvent<NativeMouseButtonEventArgs>* MouseDownEvent() override; - IEvent<NativeMouseButtonEventArgs>* MouseUpEvent() override; - IEvent<NativeMouseWheelEventArgs>* MouseWheelEvent() override; - IEvent<NativeKeyEventArgs>* KeyDownEvent() override; - IEvent<NativeKeyEventArgs>* KeyUpEvent() override; + IEvent<const Point&>* MouseMoveEvent() override; + IEvent<const NativeMouseButtonEventArgs&>* MouseDownEvent() override; + IEvent<const NativeMouseButtonEventArgs&>* MouseUpEvent() override; + IEvent<const NativeMouseWheelEventArgs&>* MouseWheelEvent() override; + IEvent<const NativeKeyEventArgs&>* KeyDownEvent() override; + IEvent<const NativeKeyEventArgs&>* KeyUpEvent() override; IInputMethodContext* GetInputMethodContext() override; @@ -127,14 +127,14 @@ class XcbWindow : public XcbResource, public virtual INativeWindow { Event<std::nullptr_t> paint_event_; Event<WindowVisibilityType> visibility_change_event_; - Event<Size> resize_event_; + Event<const Size&> resize_event_; Event<FocusChangeType> focus_event_; Event<MouseEnterLeaveType> mouse_enter_leave_event_; - Event<Point> mouse_move_event_; - Event<NativeMouseButtonEventArgs> mouse_down_event_; - Event<NativeMouseButtonEventArgs> mouse_up_event_; - Event<NativeMouseWheelEventArgs> mouse_wheel_event_; - Event<NativeKeyEventArgs> key_down_event_; - Event<NativeKeyEventArgs> key_up_event_; + Event<const Point&> mouse_move_event_; + Event<const NativeMouseButtonEventArgs&> mouse_down_event_; + Event<const NativeMouseButtonEventArgs&> mouse_up_event_; + Event<const NativeMouseWheelEventArgs&> mouse_wheel_event_; + Event<const NativeKeyEventArgs&> key_down_event_; + Event<const NativeKeyEventArgs&> key_up_event_; }; } // namespace cru::platform::gui::xcb diff --git a/include/cru/ui/controls/Button.h b/include/cru/ui/controls/Button.h index 3c01be32..e8fa50f1 100644 --- a/include/cru/ui/controls/Button.h +++ b/include/cru/ui/controls/Button.h @@ -33,7 +33,7 @@ class CRU_UI_API Button : public SingleChildControl<render::BorderRenderObject>, return click_detector_.StateChangeEvent(); } - IEvent<helper::ClickEventArgs>* ClickEvent() { + IEvent<const helper::ClickEventArgs&>* ClickEvent() { return click_detector_.ClickEvent(); } diff --git a/include/cru/ui/controls/IconButton.h b/include/cru/ui/controls/IconButton.h index 9e7572e0..e52d2a26 100644 --- a/include/cru/ui/controls/IconButton.h +++ b/include/cru/ui/controls/IconButton.h @@ -39,7 +39,7 @@ class CRU_UI_API IconButton : public NoChildControl, return click_detector_.StateChangeEvent(); } - IEvent<helper::ClickEventArgs>* ClickEvent() { + IEvent<const helper::ClickEventArgs&>* ClickEvent() { return click_detector_.ClickEvent(); } @@ -87,7 +87,8 @@ class CRU_UI_API IconButton : public NoChildControl, void SetIconWithSvgPathDataString(std::string_view icon_svg_path_data_string, const Rect& view_port); void SetIconWithSvgPathDataStringResourceKey( - std::string_view icon_svg_path_data_string_resource_key, const Rect& view_port); + std::string_view icon_svg_path_data_string_resource_key, + const Rect& view_port); std::shared_ptr<platform::graphics::IBrush> GetContentBrush() const override { return GetIconFillBrush(); diff --git a/include/cru/ui/controls/RootControl.h b/include/cru/ui/controls/RootControl.h index 5fa8090e..e662b655 100644 --- a/include/cru/ui/controls/RootControl.h +++ b/include/cru/ui/controls/RootControl.h @@ -28,7 +28,7 @@ class CRU_UI_API RootControl Control* attached_control_; - EventRevokerListGuard + EventHandlerRevokerListGuard gain_focus_on_create_and_destroy_when_lose_focus_event_guard_; }; } // namespace cru::ui::controls diff --git a/include/cru/ui/controls/TextHostControlService.h b/include/cru/ui/controls/TextHostControlService.h index 529225a7..a9f4f22b 100644 --- a/include/cru/ui/controls/TextHostControlService.h +++ b/include/cru/ui/controls/TextHostControlService.h @@ -187,8 +187,8 @@ class CRU_UI_API TextHostControlService : public Object { Event<std::nullptr_t> text_change_event_; - EventRevokerListGuard event_guard_; - EventRevokerListGuard input_method_context_event_guard_; + EventHandlerRevokerListGuard event_guard_; + EventHandlerRevokerListGuard input_method_context_event_guard_; std::string text_; TextRange selection_; diff --git a/include/cru/ui/events/RoutedEvent.h b/include/cru/ui/events/RoutedEvent.h index a01839a6..9a07e1e9 100644 --- a/include/cru/ui/events/RoutedEvent.h +++ b/include/cru/ui/events/RoutedEvent.h @@ -16,7 +16,7 @@ class CRU_UI_API RoutedEvent { using RawEventArgs = TEventArgs; using IEventType = IEvent<TEventArgs&>; - using EventArgs = typename IEventType::EventArgs; + using EventArgs = typename IEventType::Args; RoutedEvent() = default; RoutedEvent(const RoutedEvent& other) = delete; diff --git a/include/cru/ui/helper/ClickDetector.h b/include/cru/ui/helper/ClickDetector.h index eaf1f4af..2eb453d9 100644 --- a/include/cru/ui/helper/ClickDetector.h +++ b/include/cru/ui/helper/ClickDetector.h @@ -57,7 +57,7 @@ class ClickDetector : public Object { // deactivated. void SetTriggerButton(MouseButton trigger_button); - IEvent<ClickEventArgs>* ClickEvent() { return &event_; } + IEvent<const ClickEventArgs&>* ClickEvent() { return &event_; } IEvent<ClickState>* StateChangeEvent() { return &state_change_event_; } @@ -72,10 +72,10 @@ class ClickDetector : public Object { bool enable_ = true; MouseButton trigger_button_ = MouseButtons::Left | MouseButtons::Right; - Event<ClickEventArgs> event_; + Event<const ClickEventArgs&> event_; Event<ClickState> state_change_event_; - std::vector<EventRevokerGuard> event_rovoker_guards_; + std::vector<EventHandlerRevokerGuard> event_rovoker_guards_; Point down_point_; MouseButton button_; diff --git a/include/cru/ui/helper/ShortcutHub.h b/include/cru/ui/helper/ShortcutHub.h index d2c9952b..1b600c48 100644 --- a/include/cru/ui/helper/ShortcutHub.h +++ b/include/cru/ui/helper/ShortcutHub.h @@ -131,6 +131,6 @@ class CRU_UI_API ShortcutHub : public Object { Event<events::KeyEventArgs&> fallback_event_; - EventRevokerListGuard event_guard_; + EventHandlerRevokerListGuard event_guard_; }; } // namespace cru::ui::helper diff --git a/include/cru/ui/host/WindowHost.h b/include/cru/ui/host/WindowHost.h index 6e7a0f2e..889665d5 100644 --- a/include/cru/ui/host/WindowHost.h +++ b/include/cru/ui/host/WindowHost.h @@ -156,7 +156,7 @@ class CRU_UI_API WindowHost : public Object, public SelfResolvable<WindowHost> { Event<AfterLayoutEventArgs> after_layout_event_; std::vector<std::function<void()> > after_layout_stable_action_; - std::vector<EventRevokerGuard> event_revoker_guards_; + std::vector<EventHandlerRevokerGuard> event_revoker_guards_; controls::Control* mouse_hover_control_ = nullptr; diff --git a/include/cru/ui/render/ScrollBar.h b/include/cru/ui/render/ScrollBar.h index 8c531489..50b21386 100644 --- a/include/cru/ui/render/ScrollBar.h +++ b/include/cru/ui/render/ScrollBar.h @@ -136,7 +136,7 @@ class CRU_UI_API ScrollBar : public Object { std::optional<ScrollBarAreaKind> mouse_hover_; std::optional<ScrollBarAreaKind> mouse_press_; - EventRevokerListGuard event_guard_; + EventHandlerRevokerListGuard event_guard_; Event<Scroll> scroll_attempt_event_; diff --git a/include/cru/ui/render/ScrollRenderObject.h b/include/cru/ui/render/ScrollRenderObject.h index 63a49aa3..348d7af1 100644 --- a/include/cru/ui/render/ScrollRenderObject.h +++ b/include/cru/ui/render/ScrollRenderObject.h @@ -95,6 +95,6 @@ class CRU_UI_API ScrollRenderObject : public SingleChildRenderObject { bool is_mouse_wheel_enabled_ = true; - EventRevokerListGuard guard_; + EventHandlerRevokerListGuard guard_; }; } // namespace cru::ui::render diff --git a/include/cru/ui/style/StyleRuleSet.h b/include/cru/ui/style/StyleRuleSet.h index 0b7a237d..d89c3ae1 100644 --- a/include/cru/ui/style/StyleRuleSet.h +++ b/include/cru/ui/style/StyleRuleSet.h @@ -63,7 +63,7 @@ class CRU_UI_API StyleRuleSet : public Object, public model::IListChangeNotify { Event<model::ListChange> list_change_event_; std::shared_ptr<StyleRuleSet> parent_ = nullptr; - EventRevokerGuard parent_change_event_guard_; + EventHandlerRevokerGuard parent_change_event_guard_; std::vector<StyleRule> rules_; }; @@ -90,6 +90,6 @@ class CRU_UI_API StyleRuleSetBind { // child first, parent last. std::vector<StyleRuleSet*> ruleset_chain_cache_; - EventRevokerListGuard guard_; + EventHandlerRevokerListGuard guard_; }; } // namespace cru::ui::style diff --git a/src/platform/gui/osx/InputMethod.mm b/src/platform/gui/osx/InputMethod.mm index 10003a5d..11ba1ad6 100644 --- a/src/platform/gui/osx/InputMethod.mm +++ b/src/platform/gui/osx/InputMethod.mm @@ -78,7 +78,7 @@ IEvent<std::nullptr_t>* OsxInputMethodContext::CompositionEvent() { return &p_->composition_event_; } -IEvent<std::string>* OsxInputMethodContext::TextEvent() { return &p_->text_event_; } +IEvent<const std::string&>* OsxInputMethodContext::TextEvent() { return &p_->text_event_; } bool OsxInputMethodContext::IsEnabled() { return p_->is_enabled_; } } diff --git a/src/platform/gui/osx/InputMethodPrivate.h b/src/platform/gui/osx/InputMethodPrivate.h index 39f3be02..f5726205 100644 --- a/src/platform/gui/osx/InputMethodPrivate.h +++ b/src/platform/gui/osx/InputMethodPrivate.h @@ -56,7 +56,7 @@ class OsxInputMethodContextPrivate { Event<std::nullptr_t> composition_start_event_; Event<std::nullptr_t> composition_event_; Event<std::nullptr_t> composition_end_event_; - Event<std::string> text_event_; + Event<const std::string&> text_event_; bool is_enabled_ = false; }; diff --git a/src/platform/gui/osx/Window.mm b/src/platform/gui/osx/Window.mm index 600f4902..5f655185 100644 --- a/src/platform/gui/osx/Window.mm +++ b/src/platform/gui/osx/Window.mm @@ -379,17 +379,17 @@ IEvent<std::nullptr_t>* OsxWindow::PaintEvent() { return &p_->paint_event_; } IEvent<WindowVisibilityType>* OsxWindow::VisibilityChangeEvent() { return &p_->visibility_change_event_; } -IEvent<Size>* OsxWindow::ResizeEvent() { return &p_->resize_event_; } +IEvent<const Size&>* OsxWindow::ResizeEvent() { return &p_->resize_event_; } IEvent<FocusChangeType>* OsxWindow::FocusEvent() { return &p_->focus_event_; } IEvent<MouseEnterLeaveType>* OsxWindow::MouseEnterLeaveEvent() { return &p_->mouse_enter_leave_event_; } -IEvent<Point>* OsxWindow::MouseMoveEvent() { return &p_->mouse_move_event_; } -IEvent<NativeMouseButtonEventArgs>* OsxWindow::MouseDownEvent() { return &p_->mouse_down_event_; } -IEvent<NativeMouseButtonEventArgs>* OsxWindow::MouseUpEvent() { return &p_->mouse_up_event_; } -IEvent<NativeMouseWheelEventArgs>* OsxWindow::MouseWheelEvent() { return &p_->mouse_wheel_event_; } -IEvent<NativeKeyEventArgs>* OsxWindow::KeyDownEvent() { return &p_->key_down_event_; } -IEvent<NativeKeyEventArgs>* OsxWindow::KeyUpEvent() { return &p_->key_up_event_; } +IEvent<const Point&>* OsxWindow::MouseMoveEvent() { return &p_->mouse_move_event_; } +IEvent<const NativeMouseButtonEventArgs&>* OsxWindow::MouseDownEvent() { return &p_->mouse_down_event_; } +IEvent<const NativeMouseButtonEventArgs&>* OsxWindow::MouseUpEvent() { return &p_->mouse_up_event_; } +IEvent<const NativeMouseWheelEventArgs&>* OsxWindow::MouseWheelEvent() { return &p_->mouse_wheel_event_; } +IEvent<const NativeKeyEventArgs&>* OsxWindow::KeyDownEvent() { return &p_->key_down_event_; } +IEvent<const NativeKeyEventArgs&>* OsxWindow::KeyUpEvent() { return &p_->key_up_event_; } IInputMethodContext* OsxWindow::GetInputMethodContext() { return p_->input_method_context_.get(); } } // namespace cru::platform::gui::osx diff --git a/src/platform/gui/osx/WindowPrivate.h b/src/platform/gui/osx/WindowPrivate.h index 913f2b2b..94b7e948 100644 --- a/src/platform/gui/osx/WindowPrivate.h +++ b/src/platform/gui/osx/WindowPrivate.h @@ -103,15 +103,15 @@ class OsxWindowPrivate { Event<std::nullptr_t> destroy_event_; Event<std::nullptr_t> paint_event_; Event<WindowVisibilityType> visibility_change_event_; - Event<Size> resize_event_; + Event<const Size&> resize_event_; Event<FocusChangeType> focus_event_; Event<MouseEnterLeaveType> mouse_enter_leave_event_; - Event<Point> mouse_move_event_; - Event<NativeMouseButtonEventArgs> mouse_down_event_; - Event<NativeMouseButtonEventArgs> mouse_up_event_; - Event<NativeMouseWheelEventArgs> mouse_wheel_event_; - Event<NativeKeyEventArgs> key_down_event_; - Event<NativeKeyEventArgs> key_up_event_; + Event<const Point&> mouse_move_event_; + Event<const NativeMouseButtonEventArgs&> mouse_down_event_; + Event<const NativeMouseButtonEventArgs&> mouse_up_event_; + Event<const NativeMouseWheelEventArgs&> mouse_wheel_event_; + Event<const NativeKeyEventArgs&> key_down_event_; + Event<const NativeKeyEventArgs&> key_up_event_; }; } // namespace details } // namespace cru::platform::gui::osx diff --git a/src/platform/gui/sdl/Window.cpp b/src/platform/gui/sdl/Window.cpp index 1c2d53bc..e0898cb1 100644 --- a/src/platform/gui/sdl/Window.cpp +++ b/src/platform/gui/sdl/Window.cpp @@ -132,7 +132,7 @@ IEvent<WindowVisibilityType> *SdlWindow::VisibilityChangeEvent() { return &visibility_change_event_; } -IEvent<Size> *SdlWindow::ResizeEvent() { return &resize_event_; } +IEvent<const Size&> *SdlWindow::ResizeEvent() { return &resize_event_; } IEvent<FocusChangeType> *SdlWindow::FocusEvent() { return &focus_event_; } @@ -140,25 +140,25 @@ IEvent<MouseEnterLeaveType> *SdlWindow::MouseEnterLeaveEvent() { return &mouse_enter_leave_event_; } -IEvent<Point> *SdlWindow::MouseMoveEvent() { return &mouse_move_event_; } +IEvent<const Point&> *SdlWindow::MouseMoveEvent() { return &mouse_move_event_; } -IEvent<NativeMouseButtonEventArgs> *SdlWindow::MouseDownEvent() { +IEvent<const NativeMouseButtonEventArgs&> *SdlWindow::MouseDownEvent() { return &mouse_down_event_; } -IEvent<NativeMouseButtonEventArgs> *SdlWindow::MouseUpEvent() { +IEvent<const NativeMouseButtonEventArgs&> *SdlWindow::MouseUpEvent() { return &mouse_up_event_; } -IEvent<NativeMouseWheelEventArgs> *SdlWindow::MouseWheelEvent() { +IEvent<const NativeMouseWheelEventArgs&> *SdlWindow::MouseWheelEvent() { return &mouse_wheel_event_; } -IEvent<NativeKeyEventArgs> *SdlWindow::KeyDownEvent() { +IEvent<const NativeKeyEventArgs&> *SdlWindow::KeyDownEvent() { return &key_down_event_; } -IEvent<NativeKeyEventArgs> *SdlWindow::KeyUpEvent() { return &key_up_event_; } +IEvent<const NativeKeyEventArgs&> *SdlWindow::KeyUpEvent() { return &key_up_event_; } IInputMethodContext *SdlWindow::GetInputMethodContext() { NotImplemented(); } diff --git a/src/platform/gui/win/InputMethod.cpp b/src/platform/gui/win/InputMethod.cpp index e5b75cdb..1d7e2629 100644 --- a/src/platform/gui/win/InputMethod.cpp +++ b/src/platform/gui/win/InputMethod.cpp @@ -230,7 +230,7 @@ IEvent<std::nullptr_t>* WinInputMethodContext::CompositionEvent() { return &composition_event_; } -IEvent<std::string>* WinInputMethodContext::TextEvent() { return &text_event_; } +IEvent<const std::string&>* WinInputMethodContext::TextEvent() { return &text_event_; } void WinInputMethodContext::OnWindowNativeMessage( WindowNativeMessageEventArgs& args) { diff --git a/src/platform/gui/win/TimerManager.h b/src/platform/gui/win/TimerManager.h index d5a07f7f..9b049310 100644 --- a/src/platform/gui/win/TimerManager.h +++ b/src/platform/gui/win/TimerManager.h @@ -46,7 +46,7 @@ class TimerManager : public Object { private: GodWindow* god_window_; - EventRevokerListGuard event_guard_; + EventHandlerRevokerListGuard event_guard_; long long next_id_ = 1; std::unordered_map<long long, TimerInfo> info_map_; diff --git a/src/platform/gui/xcb/InputMethod.cpp b/src/platform/gui/xcb/InputMethod.cpp index d6d4b9e7..96d04348 100644 --- a/src/platform/gui/xcb/InputMethod.cpp +++ b/src/platform/gui/xcb/InputMethod.cpp @@ -204,7 +204,7 @@ IEvent<std::nullptr_t> *XcbXimInputMethodContext::CompositionEvent() { return &composition_event_; } -IEvent<std::string> *XcbXimInputMethodContext::TextEvent() { +IEvent<const std::string&> *XcbXimInputMethodContext::TextEvent() { return &text_event_; } diff --git a/src/platform/gui/xcb/Window.cpp b/src/platform/gui/xcb/Window.cpp index 96483e04..44db5af3 100644 --- a/src/platform/gui/xcb/Window.cpp +++ b/src/platform/gui/xcb/Window.cpp @@ -311,7 +311,7 @@ IEvent<WindowVisibilityType> *XcbWindow::VisibilityChangeEvent() { return &visibility_change_event_; } -IEvent<Size> *XcbWindow::ResizeEvent() { return &resize_event_; } +IEvent<const Size&> *XcbWindow::ResizeEvent() { return &resize_event_; } IEvent<FocusChangeType> *XcbWindow::FocusEvent() { return &focus_event_; } @@ -319,25 +319,25 @@ IEvent<MouseEnterLeaveType> *XcbWindow::MouseEnterLeaveEvent() { return &mouse_enter_leave_event_; } -IEvent<Point> *XcbWindow::MouseMoveEvent() { return &mouse_move_event_; } +IEvent<const Point&> *XcbWindow::MouseMoveEvent() { return &mouse_move_event_; } -IEvent<NativeMouseButtonEventArgs> *XcbWindow::MouseDownEvent() { +IEvent<const NativeMouseButtonEventArgs&> *XcbWindow::MouseDownEvent() { return &mouse_down_event_; } -IEvent<NativeMouseButtonEventArgs> *XcbWindow::MouseUpEvent() { +IEvent<const NativeMouseButtonEventArgs&> *XcbWindow::MouseUpEvent() { return &mouse_up_event_; } -IEvent<NativeMouseWheelEventArgs> *XcbWindow::MouseWheelEvent() { +IEvent<const NativeMouseWheelEventArgs&> *XcbWindow::MouseWheelEvent() { return &mouse_wheel_event_; } -IEvent<NativeKeyEventArgs> *XcbWindow::KeyDownEvent() { +IEvent<const NativeKeyEventArgs&> *XcbWindow::KeyDownEvent() { return &key_down_event_; } -IEvent<NativeKeyEventArgs> *XcbWindow::KeyUpEvent() { return &key_up_event_; } +IEvent<const NativeKeyEventArgs&> *XcbWindow::KeyUpEvent() { return &key_up_event_; } IInputMethodContext *XcbWindow::GetInputMethodContext() { return input_method_; diff --git a/src/ui/helper/ClickDetector.cpp b/src/ui/helper/ClickDetector.cpp index 21caff35..cf219db0 100644 --- a/src/ui/helper/ClickDetector.cpp +++ b/src/ui/helper/ClickDetector.cpp @@ -23,7 +23,7 @@ ClickDetector::ClickDetector(controls::Control* control) { control_ = control; event_rovoker_guards_.push_back( - EventRevokerGuard(control->MouseEnterEvent()->Direct()->AddHandler( + EventHandlerRevokerGuard(control->MouseEnterEvent()->Direct()->AddHandler( [this](events::MouseEventArgs&) { if (this->enable_) { if (this->state_ == ClickState::PressInactive) { @@ -37,7 +37,7 @@ ClickDetector::ClickDetector(controls::Control* control) { }))); event_rovoker_guards_.push_back( - EventRevokerGuard(control->MouseLeaveEvent()->Direct()->AddHandler( + EventHandlerRevokerGuard(control->MouseLeaveEvent()->Direct()->AddHandler( [this](events::MouseEventArgs&) { if (this->enable_) { if (this->state_ == ClickState::Press) { @@ -51,7 +51,7 @@ ClickDetector::ClickDetector(controls::Control* control) { }))); event_rovoker_guards_.push_back( - EventRevokerGuard(control->MouseDownEvent()->Direct()->AddHandler( + EventHandlerRevokerGuard(control->MouseDownEvent()->Direct()->AddHandler( [this](events::MouseButtonEventArgs& args) { const auto button = args.GetButton(); if (this->enable_ && (button & this->trigger_button_) && @@ -70,7 +70,7 @@ ClickDetector::ClickDetector(controls::Control* control) { }))); event_rovoker_guards_.push_back( - EventRevokerGuard(control->MouseUpEvent()->Direct()->AddHandler( + EventHandlerRevokerGuard(control->MouseUpEvent()->Direct()->AddHandler( [this](events::MouseButtonEventArgs& args) { const auto button = args.GetButton(); if (this->enable_ && (button & this->trigger_button_) && diff --git a/src/ui/host/WindowHost.cpp b/src/ui/host/WindowHost.cpp index 4c707772..7417740d 100644 --- a/src/ui/host/WindowHost.cpp +++ b/src/ui/host/WindowHost.cpp @@ -93,9 +93,9 @@ namespace { template <typename T> inline void BindNativeEvent( WindowHost* host, INativeWindow* native_window, IEvent<T>* event, - void (WindowHost::*handler)(INativeWindow*, typename IEvent<T>::EventArgs), - std::vector<EventRevokerGuard>& guard_pool) { - guard_pool.push_back(EventRevokerGuard(event->AddHandler( + void (WindowHost::*handler)(INativeWindow*, typename IEvent<T>::Args), + std::vector<EventHandlerRevokerGuard>& guard_pool) { + guard_pool.push_back(EventHandlerRevokerGuard(event->AddHandler( std::bind(handler, host, native_window, std::placeholders::_1)))); } } // namespace diff --git a/src/ui/render/ScrollBar.cpp b/src/ui/render/ScrollBar.cpp index a3bee22c..804395e4 100644 --- a/src/ui/render/ScrollBar.cpp +++ b/src/ui/render/ScrollBar.cpp @@ -115,143 +115,121 @@ void ScrollBar::Draw(platform::graphics::IPainter* painter) { void ScrollBar::InstallHandlers(controls::Control* control) { event_guard_.Clear(); if (control != nullptr) { - event_guard_ += - control->MouseDownEvent()->Tunnel()->PrependShortCircuitHandler( - [control, this](events::MouseButtonEventArgs& event) { - if (event.GetButton() == MouseButtons::Left && IsEnabled() && - IsExpanded()) { - auto hit_test_result = - ExpandedHitTest(event.GetPoint(render_object_)); - if (!hit_test_result) return false; - - if (mouse_press_ != hit_test_result) { - mouse_press_ = hit_test_result; - render_object_->InvalidatePaint(); - } - - switch (*hit_test_result) { - case ScrollBarAreaKind::UpArrow: - this->scroll_attempt_event_.Raise( - {GetDirection(), ScrollKind::Line, -1}); - event.SetHandled(); - return true; - case ScrollBarAreaKind::DownArrow: - this->scroll_attempt_event_.Raise( - {GetDirection(), ScrollKind::Line, 1}); - event.SetHandled(); - return true; - case ScrollBarAreaKind::UpSlot: - this->scroll_attempt_event_.Raise( - {GetDirection(), ScrollKind::Page, -1}); - event.SetHandled(); - return true; - case ScrollBarAreaKind::DownSlot: - this->scroll_attempt_event_.Raise( - {GetDirection(), ScrollKind::Page, 1}); - event.SetHandled(); - return true; - case ScrollBarAreaKind::Thumb: { - auto thumb_rect = - GetExpandedAreaRect(ScrollBarAreaKind::Thumb); - assert(thumb_rect); - - if (!control->CaptureMouse()) break; - move_thumb_thumb_original_rect_ = *thumb_rect; - move_thumb_start_ = event.GetPoint(); - event.SetHandled(); - return true; - } - default: - break; - } - } - - return false; - }); - - event_guard_ += - control->MouseUpEvent()->Tunnel()->PrependShortCircuitHandler( - [control, this](events::MouseButtonEventArgs& event) { - if (mouse_press_ != std::nullopt) { - mouse_press_ = std::nullopt; - render_object_->InvalidatePaint(); - } - - if (event.GetButton() == MouseButtons::Left && - move_thumb_start_) { - move_thumb_start_ = std::nullopt; - - auto hit_test_result = - ExpandedHitTest(event.GetPoint(this->render_object_)); - if (!hit_test_result) { - OnMouseLeave(); - } - - control->ReleaseMouse(); + event_guard_ += control->MouseDownEvent()->Tunnel()->AddHandler( + [control, this](events::MouseButtonEventArgs& event) { + if (event.GetButton() == MouseButtons::Left && IsEnabled() && + IsExpanded()) { + auto hit_test_result = + ExpandedHitTest(event.GetPoint(render_object_)); + if (!hit_test_result) return; + + if (mouse_press_ != hit_test_result) { + mouse_press_ = hit_test_result; + render_object_->InvalidatePaint(); + } + + switch (*hit_test_result) { + case ScrollBarAreaKind::UpArrow: + this->scroll_attempt_event_.Raise( + {GetDirection(), ScrollKind::Line, -1}); event.SetHandled(); - return true; - } - return false; - }); - - event_guard_ += - control->MouseMoveEvent()->Tunnel()->PrependShortCircuitHandler( - [this](events::MouseEventArgs& event) { - if (move_thumb_start_) { - auto new_scroll_position = CalculateNewScrollPosition( - move_thumb_thumb_original_rect_, - event.GetPoint() - *move_thumb_start_); - - this->scroll_attempt_event_.Raise({GetDirection(), - ScrollKind::Absolute, - new_scroll_position}); + case ScrollBarAreaKind::DownArrow: + this->scroll_attempt_event_.Raise( + {GetDirection(), ScrollKind::Line, 1}); event.SetHandled(); - return true; - } + case ScrollBarAreaKind::UpSlot: + this->scroll_attempt_event_.Raise( + {GetDirection(), ScrollKind::Page, -1}); + event.SetHandled(); + case ScrollBarAreaKind::DownSlot: + this->scroll_attempt_event_.Raise( + {GetDirection(), ScrollKind::Page, 1}); + event.SetHandled(); + case ScrollBarAreaKind::Thumb: { + auto thumb_rect = GetExpandedAreaRect(ScrollBarAreaKind::Thumb); + assert(thumb_rect); - if (IsEnabled()) { - if (IsExpanded()) { - auto hit_test_result = - ExpandedHitTest(event.GetPoint(this->render_object_)); - if (mouse_hover_ != hit_test_result) { - mouse_hover_ = hit_test_result; - render_object_->InvalidatePaint(); - } - if (hit_test_result) { - SetCursor(); - StopAutoCollapseTimer(); - } else { - OnMouseLeave(); - } - } else { - auto trigger_expand_area = - GetCollapsedTriggerExpandAreaRect(); - if (trigger_expand_area && - trigger_expand_area->IsPointInside( - event.GetPoint(this->render_object_))) { - SetExpanded(true); - SetCursor(); - event.SetHandled(); - return true; - } - } + if (!control->CaptureMouse()) break; + move_thumb_thumb_original_rect_ = *thumb_rect; + move_thumb_start_ = event.GetPoint(); + event.SetHandled(); } - - return false; - }); - - event_guard_ += - control->MouseLeaveEvent()->Tunnel()->PrependShortCircuitHandler( - [this](events::MouseEventArgs&) { - if (IsExpanded() && !move_thumb_start_) { - if (mouse_hover_ != std::nullopt) { - mouse_hover_ = std::nullopt; - render_object_->InvalidatePaint(); - } + default: + break; + } + } + }); + + event_guard_ += control->MouseUpEvent()->Tunnel()->AddHandler( + [control, this](events::MouseButtonEventArgs& event) { + if (mouse_press_ != std::nullopt) { + mouse_press_ = std::nullopt; + render_object_->InvalidatePaint(); + } + + if (event.GetButton() == MouseButtons::Left && move_thumb_start_) { + move_thumb_start_ = std::nullopt; + + auto hit_test_result = + ExpandedHitTest(event.GetPoint(this->render_object_)); + if (!hit_test_result) { + OnMouseLeave(); + } + + control->ReleaseMouse(); + event.SetHandled(); + } + }); + + event_guard_ += control->MouseMoveEvent()->Tunnel()->AddHandler( + [this](events::MouseEventArgs& event) { + if (move_thumb_start_) { + auto new_scroll_position = CalculateNewScrollPosition( + move_thumb_thumb_original_rect_, + event.GetPoint() - *move_thumb_start_); + + this->scroll_attempt_event_.Raise( + {GetDirection(), ScrollKind::Absolute, new_scroll_position}); + event.SetHandled(); + } + + if (IsEnabled()) { + if (IsExpanded()) { + auto hit_test_result = + ExpandedHitTest(event.GetPoint(this->render_object_)); + if (mouse_hover_ != hit_test_result) { + mouse_hover_ = hit_test_result; + render_object_->InvalidatePaint(); + } + if (hit_test_result) { + SetCursor(); + StopAutoCollapseTimer(); + } else { OnMouseLeave(); } - return false; - }); + } else { + auto trigger_expand_area = GetCollapsedTriggerExpandAreaRect(); + if (trigger_expand_area && + trigger_expand_area->IsPointInside( + event.GetPoint(this->render_object_))) { + SetExpanded(true); + SetCursor(); + event.SetHandled(); + } + } + } + }); + + event_guard_ += control->MouseLeaveEvent()->Tunnel()->AddHandler( + [this](events::MouseEventArgs&) { + if (IsExpanded() && !move_thumb_start_) { + if (mouse_hover_ != std::nullopt) { + mouse_hover_ = std::nullopt; + render_object_->InvalidatePaint(); + } + OnMouseLeave(); + } + }); } } diff --git a/src/ui/render/ScrollRenderObject.cpp b/src/ui/render/ScrollRenderObject.cpp index b8b6904d..ea93dd21 100644 --- a/src/ui/render/ScrollRenderObject.cpp +++ b/src/ui/render/ScrollRenderObject.cpp @@ -218,7 +218,7 @@ void ScrollRenderObject::InstallMouseWheelHandler(controls::Control* control) { guard_.Clear(); if (control != nullptr) { - guard_ += control->MouseWheelEvent()->Bubble()->PrependShortCircuitHandler( + guard_ += control->MouseWheelEvent()->Bubble()->AddHandler( [this](events::MouseWheelEventArgs& args) { auto delta = args.GetDelta(); @@ -228,24 +228,19 @@ void ScrollRenderObject::InstallMouseWheelHandler(controls::Control* control) { if (VerticalCanScrollDown()) { ApplyScroll( Scroll{Direction::Vertical, ScrollKind::Relative, delta}); - return true; } else if (HorizontalCanScrollDown()) { ApplyScroll( Scroll{Direction::Horizontal, ScrollKind::Relative, delta}); - return true; } } else if (delta < 0) { if (VerticalCanScrollUp()) { ApplyScroll( Scroll{Direction::Vertical, ScrollKind::Relative, delta}); - return true; } else if (HorizontalCanScrollUp()) { ApplyScroll( Scroll{Direction::Horizontal, ScrollKind::Relative, delta}); - return true; } } - return false; }); } } |
