Skip to content

Commit

Permalink
Route id (#1978)
Browse files Browse the repository at this point in the history
* implemented route

Signed-off-by: Christoph <xarvix@web.de>

* update CHANGELOG.md

Signed-off-by: Christoph <xarvix@web.de>

* reformat

Signed-off-by: Christoph <xarvix@web.de>

* Update command.rs

* Update druid/src/command.rs

Co-authored-by: Manmeet Maan <49202620+Maan2003@users.noreply.github.com>

* add send notifications test

Signed-off-by: Christoph <xarvix@web.de>

* fix

Signed-off-by: Christoph <xarvix@web.de>

* fix

Signed-off-by: Christoph <xarvix@web.de>

Co-authored-by: Christoph <xarvix@web.de>
Co-authored-by: Manmeet Maan <49202620+Maan2003@users.noreply.github.com>
  • Loading branch information
3 people committed Sep 25, 2021
1 parent 82ec0be commit 0223076
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 3 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ You can find its changes [documented below](#070---2021-01-01).
- Add #[data(eq)] shorthand attribute for Data derive macro ([#1884] by [@Maan2003])
- X11: detect keyboard layout ([#1779] by [@Maan2003])
- WindowDesc::with_config ([#1929] by [@Maan2003])
- `Notification::route` ([#1978] by [@xarvic])

### Changed

Expand Down Expand Up @@ -793,8 +794,9 @@ Last release without a changelog :(
[#1919]: https://github.com/linebender/druid/pull/1919
[#1929]: https://github.com/linebender/druid/pull/1929
[#1947]: https://github.com/linebender/druid/pull/1947
[#1967]: https://github.com/linebender/druid/pull/1967
[#1953]: https://github.com/linebender/druid/pull/1953
[#1967]: https://github.com/linebender/druid/pull/1967
[#1978]: https://github.com/linebender/druid/pull/1978

[Unreleased]: https://github.com/linebender/druid/compare/v0.7.0...master
[0.7.0]: https://github.com/linebender/druid/compare/v0.6.0...v0.7.0
Expand Down
30 changes: 30 additions & 0 deletions druid/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ pub struct Notification {
symbol: SelectorSymbol,
payload: Arc<dyn Any>,
source: WidgetId,
route: WidgetId,
}

/// A wrapper type for [`Command`] payloads that should only be used once.
Expand Down Expand Up @@ -407,6 +408,7 @@ impl Command {
symbol: self.symbol,
payload: self.payload,
source,
route: source,
}
}

Expand Down Expand Up @@ -528,6 +530,34 @@ impl Notification {
pub fn source(&self) -> WidgetId {
self.source
}

/// Change the route id
pub(crate) fn with_route(mut self, widget_id: WidgetId) -> Self {
self.route = widget_id;
self
}

/// The [`WidgetId`] of the last [`Widget`] that this [`Notification`] was passed through.
///
/// # Example
///
/// ```ignore
/// fn event(&mut self, ctx: &mut EventCtx, event: &Event, data: &mut (), env: &Env) {
/// if let Event::Notification(notification) = event {
/// if notification.route() == self.widget1.id() {
/// // the notification came from inside of widget1
/// }
/// if notification.route() == self.widget2.id() {
/// // the notification came from inside of widget2
/// }
/// }
/// }
/// ```
///
/// [`Widget`]: crate::Widget
pub fn route(&self) -> WidgetId {
self.route
}
}

impl<T: Any> SingleUse<T> {
Expand Down
62 changes: 60 additions & 2 deletions druid/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,9 @@ impl<T: Data, W: Widget<T>> WidgetPod<T, W> {
inner_ctx.is_handled = false;
} else if let Event::Notification(notification) = event {
// we will try again with the next parent
inner_ctx.notifications.push_back(notification);
inner_ctx
.notifications
.push_back(notification.with_route(self_id));
} else {
// could be unchecked but we avoid unsafe in druid :shrug:
unreachable!()
Expand Down Expand Up @@ -1376,7 +1378,7 @@ mod tests {
use super::*;
use crate::ext_event::ExtEventHost;
use crate::text::ParseFormatter;
use crate::widget::{Flex, Scroll, Split, TextBox};
use crate::widget::{Button, Flex, Scroll, Split, TextBox};
use crate::{WidgetExt, WindowHandle, WindowId};
use test_env_log::test;

Expand Down Expand Up @@ -1438,4 +1440,60 @@ mod tests {
// A textbox is composed of three components with distinct ids
assert_eq!(ctx.widget_state.children.entry_count(), 15);
}

#[test]
fn send_notifications() {
let mut widget = WidgetPod::new(Button::new("test".to_owned())).boxed();

let mut command_queue: CommandQueue = VecDeque::new();
let mut widget_state = WidgetState::new(WidgetId::next(), None);
let window = WindowHandle::default();
let ext_host = ExtEventHost::default();
let ext_handle = ext_host.make_sink();
let mut state = ContextState::new::<Option<u32>>(
&mut command_queue,
&ext_handle,
&window,
WindowId::next(),
None,
);

let mut ctx = EventCtx {
widget_state: &mut widget_state,
notifications: &mut Default::default(),
is_handled: false,
state: &mut state,
is_root: false,
};

let ids = [
WidgetId::next(),
WidgetId::next(),
WidgetId::next(),
WidgetId::next(),
];

let env = Env::with_default_i10n();

let notification = Command::new(druid::command::sys::CLOSE_WINDOW, (), Target::Global);

let mut notifictions = VecDeque::from(vec![
notification.clone().into_notification(ids[0]),
notification.clone().into_notification(ids[1]),
notification.clone().into_notification(ids[2]),
notification.into_notification(ids[3]),
]);

widget.send_notifications(&mut ctx, &mut notifictions, &mut (), &env);

assert_eq!(ctx.notifications.len(), 4);
assert_eq!(ctx.notifications[0].source(), ids[0]);
assert_eq!(ctx.notifications[0].route(), widget.id());
assert_eq!(ctx.notifications[1].source(), ids[1]);
assert_eq!(ctx.notifications[1].route(), widget.id());
assert_eq!(ctx.notifications[2].source(), ids[2]);
assert_eq!(ctx.notifications[2].route(), widget.id());
assert_eq!(ctx.notifications[3].source(), ids[3]);
assert_eq!(ctx.notifications[3].route(), widget.id());
}
}

0 comments on commit 0223076

Please sign in to comment.