From 9cb5795da2ece9db5427607b5b37ca37de8fc27e Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Mon, 12 Dec 2022 17:40:40 +0100 Subject: [PATCH] chore: Update text to reflect requested changes --- ...nt-container.md => 0012-mouse-listener.md} | 106 +++++------------- 1 file changed, 30 insertions(+), 76 deletions(-) rename text/{0012-event-container.md => 0012-mouse-listener.md} (51%) diff --git a/text/0012-event-container.md b/text/0012-mouse-listener.md similarity index 51% rename from text/0012-event-container.md rename to text/0012-mouse-listener.md index 0e486bc..eaf12df 100644 --- a/text/0012-event-container.md +++ b/text/0012-mouse-listener.md @@ -1,8 +1,8 @@ -# Event Container +# Mouse Listener ## Summary -A programmable container that intercepts a variety of input events. +A programmable container that intercepts a variety of mouse input events. ## Motivation @@ -23,7 +23,7 @@ for (entity, metadata) in self.files.iter() { .on_middle_release(Message::OpenFile(entity)) .on_mouse_enter(Message::IconEnter(entity)) .on_mouse_exit(Message::IconExit(entity)); - + icon_widgets.push(file.into()); } ``` @@ -51,7 +51,7 @@ for (entity, metadata) in self.tabs.iter() { Another use case for this widget is a headerbar, which is a container placed at the top of the window to serve as a replacement for a window title bar when server-side decorations are disabled. If any part of the container is clicked that does not intercept that click event, then the container itself will receive the click and make it possible to initiate a window drag. ```rs -let headerbar = event_container(vec![left, center, right]) +let headerbar = mouse_listener(vec![left, center, right]) .on_press(Message::WindowDrag) .on_release(Message::WindowMaximize) .on_right_release(Message::WindowContext); @@ -59,93 +59,47 @@ let headerbar = event_container(vec![left, center, right]) ## Implementation strategy -Implementation is very similar to the container widget, but with a handful of possible events that can be emitted: +The implementation is simple, and only requires thinly wrapping any existing element to intercept mouse events over it. ```rs -struct EventMessages { +pub struct MouseListener<'a, Message, Renderer> { + content: Element<'a, Message, Renderer>, + + /// Sets the message to emit on a left mouse button press. on_press: Option, + + /// Sets the message to emit on a left mouse button release. on_release: Option, + + /// Sets the message to emit on a right mouse button press. on_right_press: Option, + + /// Sets the message to emit on a right mouse button release. on_right_release: Option, -} -``` -With an update method for publishing these messages on certain input events: + /// Sets the message to emit on a middle mouse button press. + on_middle_press: Option, -```rs -fn update( - event: Event, - layout: Layout<'_>, - cursor_position: Point, - shell: &mut Shell<'_, Message>, - messages: &EventMessages, -) -> event::Status { - let contains_bound = || layout.bounds().contains(cursor_position); - - if let Some(message) = messages.on_press.clone() { - if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) - | Event::Touch(touch::Event::FingerPressed { .. }) = event - { - return if contains_bound() { - shell.publish(message); - event::Status::Captured - } else { - event::Status::Ignored - }; - } - } - - if let Some(message) = messages.on_release.clone() { - if let Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) - | Event::Touch(touch::Event::FingerLifted { .. }) = event - { - return if contains_bound() { - shell.publish(message); - event::Status::Captured - } else { - event::Status::Ignored - }; - } - } - - if let Some(message) = messages.on_right_press.clone() { - if let Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Right)) = - event - { - return if contains_bound() { - shell.publish(message); - event::Status::Captured - } else { - event::Status::Ignored - }; - } - } - - if let Some(message) = messages.on_right_release.clone() { - if let Event::Mouse(mouse::Event::ButtonReleased( - mouse::Button::Right, - )) = event - { - return if contains_bound() { - shell.publish(message); - event::Status::Captured - } else { - event::Status::Ignored - }; - } - } - - event::Status::Ignored + /// Sets the message to emit on a middle mouse button release. + on_middle_release: Option, + + /// Sets the message to emit when the mouse enters the widget. + on_mouse_enter: Option, + + /// Sets the messsage to emit when the mouse exits the widget. + on_mouse_exit: Option, } ``` +The update method will emit these messages when their criteria is met. + ## Drawbacks -There's some duplicated code between the container widget and event_container widget. +N/A ## Rationale and alternatives -There doesn't seem to be any alternative approach besides enforcing application authors to bring their own event containers when needing to create a more sophisticated evented widget. +There doesn't seem to be any alternative approach besides enforcing application authors to bring their own mouse-event containers when needing to create a more sophisticated evented widget. ## Prior Art @@ -153,7 +107,7 @@ Similar to `gtk::EventBox` from GTK, which is essentially a `gtk::Box` but with ## Unresolved questions -Perhaps there's a way to handle events in a more flexible way that isn't soo cumbersome, since directly matching input events is rather tedious. +None ## Future Possibilities