From 2738c1a8077461b65c892ad0725ca928b1b220c6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Dec 2024 16:17:36 +0900 Subject: [PATCH 1/7] Add back right-click-for-new-combo and right-click-delete when in compose mode Requested too many times to count. I'm not sure what to do about the code quality of this. It's a bit weird that there's no way to check the current composition tool from a higher level. Also it was discussed IRL that there should be some kind of hinting that existing notes will be deleted when they are hovered, but I'm not sure how well this will work in normal mapping flows, since it will display even in cases that users aren't intending to delete an object. Still willing to explore this direction though (it's just non-trivial to implement so I haven't yet). --- .../Edit/OsuHitObjectComposer.cs | 14 +++++++++ .../Components/ComposeBlueprintContainer.cs | 2 ++ .../Components/EditorSelectionHandler.cs | 29 +++++++++++++++++-- .../Compose/Components/SelectionHandler.cs | 4 ++- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index b3e23daa99..ee386aa366 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -30,6 +30,7 @@ using osu.Game.Rulesets.UI; using osu.Game.Screens.Edit.Components.TernaryButtons; using osu.Game.Screens.Edit.Compose.Components; using osuTK; +using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit { @@ -351,6 +352,19 @@ namespace osu.Game.Rulesets.Osu.Edit } } + protected override bool OnMouseDown(MouseDownEvent e) + { + if (e.Button == MouseButton.Right) + { + var osuSelectionHandler = (OsuSelectionHandler)BlueprintContainer.SelectionHandler; + + osuSelectionHandler.SelectionNewComboState.Value = + osuSelectionHandler.SelectionNewComboState.Value == TernaryState.False ? TernaryState.True : TernaryState.False; + } + + return base.OnMouseDown(e); + } + protected override bool OnKeyDown(KeyDownEvent e) { if (e.Repeat) diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 4c57eee971..4414e963bf 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -387,6 +387,8 @@ namespace osu.Game.Screens.Edit.Compose.Components currentTool = value; + SelectionHandler.RightClickAlwaysQuickDeletes = currentTool is not SelectTool; + // As per stable editor, when changing tools, we should forcefully commit any pending placement. CommitIfPlacementActive(); } diff --git a/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs index f9e7ef6df8..e90936e38a 100644 --- a/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs @@ -10,16 +10,23 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; using osu.Game.Audio; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; +using osuTK.Input; namespace osu.Game.Screens.Edit.Compose.Components { public partial class EditorSelectionHandler : SelectionHandler { + /// + /// Whether right click should delete even when shift is not held. + /// + public bool RightClickAlwaysQuickDeletes { get; set; } + /// /// A special bank name that is only used in the editor UI. /// When selected and in placement mode, the bank of the last hit object will always be used. @@ -40,6 +47,14 @@ namespace osu.Game.Screens.Edit.Compose.Components SelectedItems.CollectionChanged += onSelectedItemsChanged; } + protected override bool ShouldQuickDelete(MouseButtonEvent e) + { + if (RightClickAlwaysQuickDeletes && e.Button == MouseButton.Right) + return true; + + return base.ShouldQuickDelete(e); + } + protected override void DeleteItems(IEnumerable items) => EditorBeatmap.RemoveRange(items); #region Selection State @@ -293,7 +308,8 @@ namespace osu.Game.Screens.Edit.Compose.Components foreach ((string bankName, var bindable) in SelectionAdditionBankStates) { - bindable.Value = GetStateFromSelection(samplesInSelection.SelectMany(s => s).Where(o => o.Name != HitSampleInfo.HIT_NORMAL), h => (bankName != HIT_BANK_AUTO && h.Bank == bankName && !h.EditorAutoBank) || (bankName == HIT_BANK_AUTO && h.EditorAutoBank)); + bindable.Value = GetStateFromSelection(samplesInSelection.SelectMany(s => s).Where(o => o.Name != HitSampleInfo.HIT_NORMAL), + h => (bankName != HIT_BANK_AUTO && h.Bank == bankName && !h.EditorAutoBank) || (bankName == HIT_BANK_AUTO && h.EditorAutoBank)); } } @@ -378,14 +394,21 @@ namespace osu.Game.Screens.Edit.Compose.Components return; string normalBank = h.Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL)?.Bank ?? HitSampleInfo.BANK_SOFT; - h.Samples = h.Samples.Select(s => s.Name != HitSampleInfo.HIT_NORMAL ? bankName == HIT_BANK_AUTO ? s.With(newBank: normalBank, newEditorAutoBank: true) : s.With(newBank: bankName, newEditorAutoBank: false) : s).ToList(); + h.Samples = h.Samples.Select(s => + s.Name != HitSampleInfo.HIT_NORMAL + ? bankName == HIT_BANK_AUTO ? s.With(newBank: normalBank, newEditorAutoBank: true) : s.With(newBank: bankName, newEditorAutoBank: false) + : s) + .ToList(); if (h is IHasRepeats hasRepeats) { for (int i = 0; i < hasRepeats.NodeSamples.Count; ++i) { normalBank = hasRepeats.NodeSamples[i].FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL)?.Bank ?? HitSampleInfo.BANK_SOFT; - hasRepeats.NodeSamples[i] = hasRepeats.NodeSamples[i].Select(s => s.Name != HitSampleInfo.HIT_NORMAL ? bankName == HIT_BANK_AUTO ? s.With(newBank: normalBank, newEditorAutoBank: true) : s.With(newBank: bankName, newEditorAutoBank: false) : s).ToList(); + hasRepeats.NodeSamples[i] = hasRepeats.NodeSamples[i].Select(s => + s.Name != HitSampleInfo.HIT_NORMAL + ? bankName == HIT_BANK_AUTO ? s.With(newBank: normalBank, newEditorAutoBank: true) : s.With(newBank: bankName, newEditorAutoBank: false) + : s).ToList(); } } }); diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index 39fff169b7..c1cb8149e7 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -263,6 +263,8 @@ namespace osu.Game.Screens.Edit.Compose.Components selectedBlueprints.Remove(blueprint); } + protected virtual bool ShouldQuickDelete(MouseButtonEvent e) => e.Button == MouseButton.Middle || (e.ShiftPressed && e.Button == MouseButton.Right); + /// /// Handle a blueprint requesting selection. /// @@ -271,7 +273,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// Whether a selection was performed. internal virtual bool MouseDownSelectionRequested(SelectionBlueprint blueprint, MouseButtonEvent e) { - if (e.Button == MouseButton.Middle || (e.ShiftPressed && e.Button == MouseButton.Right)) + if (ShouldQuickDelete(e)) { handleQuickDeletion(blueprint); return true; From 896caf4a8df9fb00cb48be52725ef6448f8dc01a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Feb 2025 17:52:43 +0900 Subject: [PATCH 2/7] Update test coverage --- .../Editor/TestSceneEditorPlacement.cs | 4 +- .../Editing/TestScenePlacementBlueprint.cs | 45 ++++++++++++++++--- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneEditorPlacement.cs b/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneEditorPlacement.cs index c523652ae1..0199e98af0 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneEditorPlacement.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneEditorPlacement.cs @@ -3,9 +3,7 @@ using System.Linq; using NUnit.Framework; -using osu.Framework.Graphics.UserInterface; using osu.Framework.Testing; -using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Game.Tests.Visual; @@ -31,7 +29,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Editor AddStep("hover over first hit", () => InputManager.MoveMouseTo(Editor.ChildrenOfType().ElementAt(1))); AddStep("hover over second hit", () => InputManager.MoveMouseTo(Editor.ChildrenOfType().ElementAt(0))); AddStep("right click", () => InputManager.Click(MouseButton.Right)); - AddUntilStep("context menu open", () => Editor.ChildrenOfType().Any(menu => menu.State == MenuState.Open)); + AddUntilStep("second hit deleted", () => Editor.ChildrenOfType().Count(), () => Is.EqualTo(1)); } } } diff --git a/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs b/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs index 4953cf83c9..37caccfa0d 100644 --- a/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs +++ b/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs @@ -7,6 +7,7 @@ using osu.Framework.Screens; using osu.Framework.Testing; using osu.Game.Audio; using osu.Game.Beatmaps; +using osu.Game.Graphics.UserInterface; using osu.Game.Input.Bindings; using osu.Game.Rulesets; using osu.Game.Rulesets.Edit; @@ -14,8 +15,10 @@ using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.UI; +using osu.Game.Screens.Edit.Components.TernaryButtons; using osu.Game.Screens.Edit.Compose.Components; using osu.Game.Tests.Beatmaps; +using osuTK; using osuTK.Input; namespace osu.Game.Tests.Visual.Editing @@ -58,17 +61,47 @@ namespace osu.Game.Tests.Visual.Editing } [Test] - public void TestContextMenu() + public void TestRightClickDuringEmptyPlacementTogglesNewCombo() { AddStep("select circle placement tool", () => InputManager.Key(Key.Number2)); AddStep("move mouse to center of playfield", () => InputManager.MoveMouseTo(this.ChildrenOfType().Single())); AddStep("place circle", () => InputManager.Click(MouseButton.Left)); - AddAssert("one circle added", () => EditorBeatmap.HitObjects, () => Has.One.Items); - AddStep("delete with right mouse", () => - { - InputManager.Click(MouseButton.Right); - }); + + AddStep("move mouse away from placed circle", () => InputManager.MoveMouseTo(this.ChildrenOfType().Single().ScreenSpaceDrawQuad.TopLeft + Vector2.One)); + + AddAssert("new combo false", () => this.ChildrenOfType().Single().Current.Value, () => Is.EqualTo(TernaryState.False)); + AddStep("click right mouse", () => InputManager.Click(MouseButton.Right)); + AddAssert("new combo true", () => this.ChildrenOfType().Single().Current.Value, () => Is.EqualTo(TernaryState.True)); + AddStep("click right mouse", () => InputManager.Click(MouseButton.Right)); + AddAssert("new combo false", () => this.ChildrenOfType().Single().Current.Value, () => Is.EqualTo(TernaryState.False)); + } + + [Test] + public void TestRightClickDuringPlacementDeletes() + { + AddStep("select circle placement tool", () => InputManager.Key(Key.Number2)); + AddStep("move mouse to center of playfield", () => InputManager.MoveMouseTo(this.ChildrenOfType().Single())); + AddStep("place circle", () => InputManager.Click(MouseButton.Left)); + AddAssert("one circle added", () => EditorBeatmap.HitObjects, () => Has.One.Items); + + AddStep("click right mouse", () => InputManager.Click(MouseButton.Right)); + + AddAssert("circle removed", () => EditorBeatmap.HitObjects, () => Has.Exactly(0).Items); + AddAssert("circle not selected", () => EditorBeatmap.SelectedHitObjects, () => Has.Exactly(0).Items); + } + + [Test] + public void TestRightClickDuringSelectionShowsContextMenu() + { + AddStep("select circle placement tool", () => InputManager.Key(Key.Number2)); + AddStep("move mouse to center of playfield", () => InputManager.MoveMouseTo(this.ChildrenOfType().Single())); + AddStep("place circle", () => InputManager.Click(MouseButton.Left)); + AddAssert("one circle added", () => EditorBeatmap.HitObjects, () => Has.One.Items); + + AddStep("select selection tool", () => InputManager.Key(Key.Number1)); + AddStep("click right mouse", () => InputManager.Click(MouseButton.Right)); + AddAssert("circle not removed", () => EditorBeatmap.HitObjects, () => Has.One.Items); AddAssert("circle selected", () => EditorBeatmap.SelectedHitObjects, () => Has.One.Items); } From a492e070fbf939b9b70022c8ed501a5cf7180a9c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 12 Mar 2025 15:57:53 +0900 Subject: [PATCH 3/7] Add failing test cases that came up in review --- .../Editing/TestScenePlacementBlueprint.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs b/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs index 37caccfa0d..ae20f5e5cf 100644 --- a/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs +++ b/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs @@ -73,8 +73,11 @@ namespace osu.Game.Tests.Visual.Editing AddAssert("new combo false", () => this.ChildrenOfType().Single().Current.Value, () => Is.EqualTo(TernaryState.False)); AddStep("click right mouse", () => InputManager.Click(MouseButton.Right)); AddAssert("new combo true", () => this.ChildrenOfType().Single().Current.Value, () => Is.EqualTo(TernaryState.True)); + AddAssert("context menu not visible", () => !Editor.ChildrenOfType().Any(c => c.IsPresent)); + AddStep("click right mouse", () => InputManager.Click(MouseButton.Right)); AddAssert("new combo false", () => this.ChildrenOfType().Single().Current.Value, () => Is.EqualTo(TernaryState.False)); + AddAssert("context menu not visible", () => !Editor.ChildrenOfType().Any(c => c.IsPresent)); } [Test] @@ -89,6 +92,8 @@ namespace osu.Game.Tests.Visual.Editing AddAssert("circle removed", () => EditorBeatmap.HitObjects, () => Has.Exactly(0).Items); AddAssert("circle not selected", () => EditorBeatmap.SelectedHitObjects, () => Has.Exactly(0).Items); + AddAssert("context menu not visible", () => !Editor.ChildrenOfType().Any(c => c.IsPresent)); + AddAssert("new combo false", () => this.ChildrenOfType().Single().Current.Value, () => Is.EqualTo(TernaryState.False)); } [Test] @@ -97,13 +102,22 @@ namespace osu.Game.Tests.Visual.Editing AddStep("select circle placement tool", () => InputManager.Key(Key.Number2)); AddStep("move mouse to center of playfield", () => InputManager.MoveMouseTo(this.ChildrenOfType().Single())); AddStep("place circle", () => InputManager.Click(MouseButton.Left)); - AddAssert("one circle added", () => EditorBeatmap.HitObjects, () => Has.One.Items); + + // ensure the circle we're selecting is not a new combo so we can assert + // new combo doesn't happen to get toggled by right click. + AddStep("seek forward", () => EditorClock.Seek(1000)); + AddStep("place second circle", () => InputManager.Click(MouseButton.Left)); + + AddAssert("two circles added", () => EditorBeatmap.HitObjects, () => Has.Exactly(2).Items); + AddAssert("context menu not visible", () => !Editor.ChildrenOfType().Any(c => c.IsPresent)); AddStep("select selection tool", () => InputManager.Key(Key.Number1)); AddStep("click right mouse", () => InputManager.Click(MouseButton.Right)); - AddAssert("circle not removed", () => EditorBeatmap.HitObjects, () => Has.One.Items); + AddAssert("circle not removed", () => EditorBeatmap.HitObjects, () => Has.Exactly(2).Items); AddAssert("circle selected", () => EditorBeatmap.SelectedHitObjects, () => Has.One.Items); + AddAssert("context menu visible", () => Editor.ChildrenOfType().Any(c => c.IsPresent)); + AddAssert("new combo false", () => this.ChildrenOfType().Single().Current.Value, () => Is.EqualTo(TernaryState.False)); } [Test] From db7d1f32d7801099caef27aa92272a2715657d38 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 12 Mar 2025 16:42:49 +0900 Subject: [PATCH 4/7] Fix quick delete still propagating right click mouse input upwards --- .../Edit/Compose/Components/BlueprintContainer.cs | 14 ++++++++------ .../Edit/Compose/Components/SelectionHandler.cs | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index dc04561242..872c4c2465 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -115,19 +115,21 @@ namespace osu.Game.Screens.Edit.Compose.Components protected override bool OnMouseDown(MouseDownEvent e) { - bool selectionPerformed = performMouseDownActions(e); + var selectionBefore = SelectionHandler.SelectedItems.ToArray(); + bool handled = performMouseDownActions(e); + bool selectionChanged = !SelectionHandler.SelectedItems.SequenceEqual(selectionBefore); bool movementPossible = prepareSelectionMovement(e); - // check if selection has occurred - if (selectionPerformed) + if (selectionChanged) { - // only unmodified right click should show context menu + // if the selection changed and there are no modifiers pressed, don't block so the context menu still shows. bool shouldShowContextMenu = e.Button == MouseButton.Right && !e.ShiftPressed && !e.AltPressed && !e.SuperPressed; - - // stop propagation if not showing context menu return !shouldShowContextMenu; } + if (handled) + return true; + // even if a selection didn't occur, a drag event may still move the selection. return e.Button == MouseButton.Left && movementPossible; } diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index 59b64ad192..758b712fef 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -262,7 +262,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// The blueprint. /// The mouse event responsible for selection. - /// Whether a selection was performed. + /// Whether an action was performed. internal virtual bool MouseDownSelectionRequested(SelectionBlueprint blueprint, MouseButtonEvent e) { if (ShouldQuickDelete(e)) From 6a7a83415199b17a1371a9c6c791246e075f7221 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 12 Mar 2025 16:52:51 +0900 Subject: [PATCH 5/7] Fix new combo being toggled when selection is made --- osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index ee386aa366..8917a68efa 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -358,8 +358,12 @@ namespace osu.Game.Rulesets.Osu.Edit { var osuSelectionHandler = (OsuSelectionHandler)BlueprintContainer.SelectionHandler; - osuSelectionHandler.SelectionNewComboState.Value = - osuSelectionHandler.SelectionNewComboState.Value == TernaryState.False ? TernaryState.True : TernaryState.False; + if (!osuSelectionHandler.SelectedItems.Any()) + { + osuSelectionHandler.SelectionNewComboState.Value = + osuSelectionHandler.SelectionNewComboState.Value == TernaryState.False ? TernaryState.True : TernaryState.False; + return true; + } } return base.OnMouseDown(e); From c2de43f6777126e57034a4e02f07408e0aa93d1d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 12 Mar 2025 16:56:16 +0900 Subject: [PATCH 6/7] Add explanation of why the logic is in such a bad place --- osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 8917a68efa..ed3fc34d94 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -354,6 +354,18 @@ namespace osu.Game.Rulesets.Osu.Edit protected override bool OnMouseDown(MouseDownEvent e) { + // Why is this logic here and not in `OsuSelectionHandler`? + // Because we only want to handle this toggle after all other right-click handling completes. + // + // Consider that input is handled from the most nested child first: + // + // ComposeScreen + // |- OsuContextMenuContainer // right click for context + // |- TimelineBlueprintContainer + // |- TimelineSelectionHandler + // |- (Osu)HitObjectComposer // right click for toggle new combo + // |- (Osu)EditorBlueprintContainer // right click for select + // |- (Osu)EditorSelectionHandler // right click for delete if (e.Button == MouseButton.Right) { var osuSelectionHandler = (OsuSelectionHandler)BlueprintContainer.SelectionHandler; From 5b911ad8d0d8a72d58d01dedf052b9378c0f6271 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 12 Mar 2025 18:25:56 +0900 Subject: [PATCH 7/7] Fix context menu not working when selection hasn't changed --- .../Screens/Edit/Compose/Components/BlueprintContainer.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 872c4c2465..b49dee279e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -115,14 +115,12 @@ namespace osu.Game.Screens.Edit.Compose.Components protected override bool OnMouseDown(MouseDownEvent e) { - var selectionBefore = SelectionHandler.SelectedItems.ToArray(); bool handled = performMouseDownActions(e); - bool selectionChanged = !SelectionHandler.SelectedItems.SequenceEqual(selectionBefore); bool movementPossible = prepareSelectionMovement(e); - if (selectionChanged) + if (SelectedItems.Any()) { - // if the selection changed and there are no modifiers pressed, don't block so the context menu still shows. + // if there is a selection and there are no modifiers pressed, don't block so the context menu still shows. bool shouldShowContextMenu = e.Button == MouseButton.Right && !e.ShiftPressed && !e.AltPressed && !e.SuperPressed; return !shouldShowContextMenu; }