From a1ec167982705b3802c75dad79a1d032f918a4a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Sep 2020 16:38:16 +0900 Subject: [PATCH 1/3] Add the ability to toggle new combo state from composer context menu --- .../TestSceneHitObjectAccentColour.cs | 2 +- .../Objects/Types/IHasComboInformation.cs | 5 ++ .../Compose/Components/SelectionHandler.cs | 57 +++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs index 2d5e4b911e..58cc324233 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs @@ -81,7 +81,7 @@ namespace osu.Game.Tests.Gameplay private class TestHitObjectWithCombo : ConvertHitObject, IHasComboInformation { - public bool NewCombo { get; } = false; + public bool NewCombo { get; set; } = false; public int ComboOffset { get; } = 0; public Bindable IndexInCurrentComboBindable { get; } = new Bindable(); diff --git a/osu.Game/Rulesets/Objects/Types/IHasComboInformation.cs b/osu.Game/Rulesets/Objects/Types/IHasComboInformation.cs index 4e3de04278..211c077d4f 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasComboInformation.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasComboInformation.cs @@ -24,6 +24,11 @@ namespace osu.Game.Rulesets.Objects.Types /// int ComboIndex { get; set; } + /// + /// Whether the HitObject starts a new combo. + /// + new bool NewCombo { get; set; } + Bindable LastInComboBindable { get; } /// diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index f95bf350b6..c33c755940 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -20,6 +20,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Objects.Types; using osuTK; namespace osu.Game.Screens.Edit.Compose.Components @@ -268,6 +269,24 @@ namespace osu.Game.Screens.Edit.Compose.Components changeHandler?.EndChange(); } + public void SetNewCombo(bool state) + { + changeHandler?.BeginChange(); + + foreach (var h in SelectedHitObjects) + { + var comboInfo = h as IHasComboInformation; + + if (comboInfo == null) + throw new InvalidOperationException($"Tried to change combo state of a {h.GetType()}, which doesn't implement {nameof(IHasComboInformation)}"); + + comboInfo.NewCombo = state; + EditorBeatmap?.UpdateHitObject(h); + } + + changeHandler?.EndChange(); + } + /// /// Removes a hit sample from all selected s. /// @@ -297,6 +316,9 @@ namespace osu.Game.Screens.Edit.Compose.Components items.AddRange(GetContextMenuItemsForSelection(selectedBlueprints)); + if (selectedBlueprints.All(b => b.HitObject is IHasComboInformation)) + items.Add(createNewComboMenuItem()); + if (selectedBlueprints.Count == 1) items.AddRange(selectedBlueprints[0].ContextMenuItems); @@ -326,6 +348,41 @@ namespace osu.Game.Screens.Edit.Compose.Components protected virtual IEnumerable GetContextMenuItemsForSelection(IEnumerable selection) => Enumerable.Empty(); + private MenuItem createNewComboMenuItem() + { + return new TernaryStateMenuItem("New combo", MenuItemType.Standard, setNewComboState) + { + State = { Value = getHitSampleState() } + }; + + void setNewComboState(TernaryState state) + { + switch (state) + { + case TernaryState.False: + SetNewCombo(false); + break; + + case TernaryState.True: + SetNewCombo(true); + break; + } + } + + TernaryState getHitSampleState() + { + int countExisting = selectedBlueprints.Select(b => b.HitObject as IHasComboInformation).Count(h => h.NewCombo); + + if (countExisting == 0) + return TernaryState.False; + + if (countExisting < SelectedHitObjects.Count()) + return TernaryState.Indeterminate; + + return TernaryState.True; + } + } + private MenuItem createHitSampleMenuItem(string name, string sampleName) { return new TernaryStateMenuItem(name, MenuItemType.Standard, setHitSampleState) From 2d67faeb7250687ccf2457502452fffce705c839 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Sep 2020 16:40:56 +0900 Subject: [PATCH 2/3] Add xmldoc --- osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index c33c755940..71177fe3e4 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -269,6 +269,11 @@ namespace osu.Game.Screens.Edit.Compose.Components changeHandler?.EndChange(); } + /// + /// Set the new combo state of all selected s. + /// + /// Whether to set or unset. + /// Throws if any selected object doesn't implement public void SetNewCombo(bool state) { changeHandler?.BeginChange(); From 02201d0ec66a23dbfa05001397bc216667e610e8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Sep 2020 17:08:25 +0900 Subject: [PATCH 3/3] Fix incorrect cast logic --- osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index 71177fe3e4..e85dbee6d9 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -376,7 +376,7 @@ namespace osu.Game.Screens.Edit.Compose.Components TernaryState getHitSampleState() { - int countExisting = selectedBlueprints.Select(b => b.HitObject as IHasComboInformation).Count(h => h.NewCombo); + int countExisting = selectedBlueprints.Select(b => (IHasComboInformation)b.HitObject).Count(h => h.NewCombo); if (countExisting == 0) return TernaryState.False;