diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs index 3d13e98865..e978b57ba4 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs @@ -48,6 +48,43 @@ public void SetUp() => Schedule(() => notificationOverlay.UnreadCount.ValueChanged += count => { displayedCount.Text = $"displayed count: {count.NewValue}"; }; }); + [Test] + public void TestForwardWithFlingRight() + { + bool activated = false; + SimpleNotification notification = null!; + + AddStep("post", () => + { + activated = false; + notificationOverlay.Post(notification = new SimpleNotification + { + Text = @"Welcome to osu!. Enjoy your stay!", + Activated = () => activated = true, + }); + }); + + AddStep("start drag", () => + { + InputManager.MoveMouseTo(notification.ChildrenOfType().Single()); + InputManager.PressButton(MouseButton.Left); + InputManager.MoveMouseTo(notification.ChildrenOfType().Single().ScreenSpaceDrawQuad.Centre + new Vector2(500, 0)); + }); + + AddStep("fling away", () => + { + InputManager.ReleaseButton(MouseButton.Left); + }); + + AddAssert("was not closed", () => !notification.WasClosed); + AddAssert("was not activated", () => !activated); + AddAssert("is not read", () => !notification.Read); + AddAssert("is not toast", () => !notification.IsInToastTray); + + AddStep("reset mouse position", () => InputManager.MoveMouseTo(Vector2.Zero)); + AddAssert("unread count one", () => notificationOverlay.UnreadCount.Value == 1); + } + [Test] public void TestDismissWithoutActivationFling() { diff --git a/osu.Game/Overlays/NotificationOverlayToastTray.cs b/osu.Game/Overlays/NotificationOverlayToastTray.cs index 1da05dab75..e3f8734581 100644 --- a/osu.Game/Overlays/NotificationOverlayToastTray.cs +++ b/osu.Game/Overlays/NotificationOverlayToastTray.cs @@ -100,6 +100,8 @@ public void Post(Notification notification) { ++runningDepth; + notification.ForwardToOverlay = () => forwardNotification(notification); + int depth = notification.DisplayOnTop ? -runningDepth : runningDepth; toastFlow.Insert(depth, notification); @@ -130,6 +132,9 @@ void scheduleDismissal() => Scheduler.AddDelayed(() => private void forwardNotification(Notification notification) { + if (!notification.IsInToastTray) + return; + Debug.Assert(notification.Parent == toastFlow); // Temporarily remove from flow so we can animate the position off to the right. diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index 6c1b43c3b5..885bb2fc6c 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -42,6 +42,8 @@ public abstract class Notification : Container /// public Func? Activated; + public Action? ForwardToOverlay { get; set; } + /// /// Should we show at the top of our section on display? /// @@ -310,6 +312,8 @@ protected override void OnDragEnd(DragEndEvent e) { if (Rotation < -10 || velocity.X < -0.3f) notification.Close(true); + else if (X > 30 || velocity.X > 0.3f) + notification.ForwardToOverlay?.Invoke(); else ResetPosition();