diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs index dfe950c01e0f..fd711e543cf8 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs @@ -34,7 +34,7 @@ public void TestSimpleMerge() }); moveMouseToHitObject(1); - AddAssert("merge option available", () => selectionHandler.ContextMenuItems?.Any(o => o.Text.Value == "Merge selection") == true); + AddAssert("merge option available", () => selectionHandler.ContextMenuItems.Any(o => o.Text.Value == "Merge selection")); mergeSelection(); @@ -198,7 +198,7 @@ public void TestIllegalMerge() }); moveMouseToHitObject(1); - AddAssert("merge option not available", () => selectionHandler.ContextMenuItems?.Length > 0 && selectionHandler.ContextMenuItems.All(o => o.Text.Value != "Merge selection")); + AddAssert("merge option not available", () => selectionHandler.ContextMenuItems.Length > 0 && selectionHandler.ContextMenuItems.All(o => o.Text.Value != "Merge selection")); mergeSelection(); AddAssert("circles not merged", () => circle1 is not null && circle2 is not null && EditorBeatmap.HitObjects.Contains(circle1) && EditorBeatmap.HitObjects.Contains(circle2)); @@ -222,7 +222,7 @@ public void TestSameStartTimeMerge() }); moveMouseToHitObject(1); - AddAssert("merge option available", () => selectionHandler.ContextMenuItems?.Any(o => o.Text.Value == "Merge selection") == true); + AddAssert("merge option available", () => selectionHandler.ContextMenuItems.Any(o => o.Text.Value == "Merge selection")); mergeSelection(); diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index 12b7dbbf126e..cf8c3c6ef10f 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -52,10 +52,7 @@ public TestSceneHitObjectComposerDistanceSnapping() [SetUp] public void Setup() => Schedule(() => { - Children = new Drawable[] - { - composer = new TestHitObjectComposer() - }; + Child = composer = new TestHitObjectComposer(); BeatDivisor.Value = 1; diff --git a/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs b/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs index c5bcfcd2df0e..7b21a413f7a2 100644 --- a/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs +++ b/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs @@ -8,16 +8,24 @@ namespace osu.Game.Graphics.Cursor { + [Cached(typeof(OsuContextMenuContainer))] public partial class OsuContextMenuContainer : ContextMenuContainer { [Cached] private OsuContextMenuSamples samples = new OsuContextMenuSamples(); + private OsuContextMenu menu = null!; + public OsuContextMenuContainer() { AddInternal(samples); } - protected override Menu CreateMenu() => new OsuContextMenu(true); + protected override Menu CreateMenu() => menu = new OsuContextMenu(true); + + public void CloseMenu() + { + menu.Close(); + } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index 16d11ccd1afe..d3461038bfa3 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -16,6 +14,7 @@ using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; +using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using osu.Game.Input.Bindings; using osu.Game.Resources.Localisation.Web; @@ -50,14 +49,17 @@ public abstract partial class SelectionHandler : CompositeDrawable, IKeyBindi private readonly List> selectedBlueprints; - protected SelectionBox SelectionBox { get; private set; } + protected SelectionBox SelectionBox { get; private set; } = null!; [Resolved(CanBeNull = true)] - protected IEditorChangeHandler ChangeHandler { get; private set; } + protected IEditorChangeHandler? ChangeHandler { get; private set; } + + public SelectionRotationHandler RotationHandler { get; private set; } = null!; - public SelectionRotationHandler RotationHandler { get; private set; } + public SelectionScaleHandler ScaleHandler { get; private set; } = null!; - public SelectionScaleHandler ScaleHandler { get; private set; } + [Resolved(CanBeNull = true)] + protected OsuContextMenuContainer? ContextMenuContainer { get; private set; } protected SelectionHandler() { @@ -230,7 +232,11 @@ public void OnReleased(KeyBindingReleaseEvent e) /// /// Deselect all selected items. /// - protected void DeselectAll() => SelectedItems.Clear(); + protected void DeselectAll() + { + SelectedItems.Clear(); + ContextMenuContainer?.CloseMenu(); + } /// /// Handle a blueprint becoming selected. @@ -243,6 +249,8 @@ internal virtual void HandleSelected(SelectionBlueprint blueprint) SelectedItems.Add(blueprint.Item); selectedBlueprints.Add(blueprint); + + ContextMenuContainer?.CloseMenu(); } /// diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index d40db329ec15..71d4693ac603 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; using osu.Framework; @@ -159,7 +160,7 @@ public bool ReadyForUse private string lastSavedHash; - private Container screenContainer; + private ScreenContainer screenContainer; [CanBeNull] private readonly EditorLoader loader; @@ -329,7 +330,7 @@ private void load(OsuConfigManager config) Name = "Screen container", RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = 40, Bottom = 50 }, - Child = screenContainer = new Container + Child = screenContainer = new ScreenContainer { RelativeSizeAxes = Axes.Both, } @@ -422,6 +423,7 @@ private void load(OsuConfigManager config) MutationTracker, } }); + changeHandler?.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true); changeHandler?.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true); @@ -1007,7 +1009,7 @@ private void onModeChanged(ValueChangedEvent e) throw new InvalidOperationException("Editor menu bar switched to an unsupported mode"); } - LoadComponentAsync(currentScreen, newScreen => + screenContainer.LoadComponentAsync(currentScreen, newScreen => { if (newScreen == currentScreen) { @@ -1385,5 +1387,12 @@ public BeatmapEditorToast(LocalisableString value, string beatmapDisplayName) { } } + + private partial class ScreenContainer : Container + { + public new Task LoadComponentAsync([NotNull] TLoadable component, Action onLoaded = null, CancellationToken cancellation = default, Scheduler scheduler = null) + where TLoadable : Drawable + => base.LoadComponentAsync(component, onLoaded, cancellation, scheduler); + } } }