mirror of
https://github.com/ppy/osu.git
synced 2025-03-11 03:37:20 +08:00
Closes https://github.com/ppy/osu/issues/28791. The reason why nudging was not changing hyperdash state in catch was that `EditorBeatmap.Update()` was not being called on the objects that were being modified, therefore postprocessing was not performed, therefore hyperdash state was not being recomputed. Looking at the usage sites of `EditorBeatmap.PerformOnSelection()`, about two-thirds of callers called `Update()` themselves on the objects they mutated, and the rest didn't. I'd say that's the failure of the abstraction and it should be `PerformOnSelection()`'s responsibility to call `Update()` there. Yes in some of the cases here this will cause extraneous calls that weren't done before, but the method is already heavily disclaimed as 'expensive', so I'd say usability should come first.
116 lines
4.0 KiB
C#
116 lines
4.0 KiB
C#
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
// See the LICENCE file in the repository root for full licence text.
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using osu.Framework.Allocation;
|
|
using osu.Framework.Bindables;
|
|
using osu.Framework.Graphics.UserInterface;
|
|
using osu.Framework.Input.Bindings;
|
|
using osu.Game.Graphics.UserInterface;
|
|
using osu.Game.Rulesets.Edit;
|
|
using osu.Game.Rulesets.Objects;
|
|
using osu.Game.Rulesets.Taiko.Objects;
|
|
using osu.Game.Screens.Edit.Compose.Components;
|
|
|
|
namespace osu.Game.Rulesets.Taiko.Edit
|
|
{
|
|
public partial class TaikoSelectionHandler : EditorSelectionHandler
|
|
{
|
|
private readonly Bindable<TernaryState> selectionRimState = new Bindable<TernaryState>();
|
|
private readonly Bindable<TernaryState> selectionStrongState = new Bindable<TernaryState>();
|
|
|
|
[BackgroundDependencyLoader]
|
|
private void load()
|
|
{
|
|
selectionStrongState.ValueChanged += state =>
|
|
{
|
|
switch (state.NewValue)
|
|
{
|
|
case TernaryState.False:
|
|
SetStrongState(false);
|
|
break;
|
|
|
|
case TernaryState.True:
|
|
SetStrongState(true);
|
|
break;
|
|
}
|
|
};
|
|
|
|
selectionRimState.ValueChanged += state =>
|
|
{
|
|
switch (state.NewValue)
|
|
{
|
|
case TernaryState.False:
|
|
SetRimState(false);
|
|
break;
|
|
|
|
case TernaryState.True:
|
|
SetRimState(true);
|
|
break;
|
|
}
|
|
};
|
|
}
|
|
|
|
public void SetStrongState(bool state)
|
|
{
|
|
if (SelectedItems.OfType<TaikoStrongableHitObject>().All(h => h.IsStrong == state))
|
|
return;
|
|
|
|
EditorBeatmap.PerformOnSelection(h =>
|
|
{
|
|
if (h is not TaikoStrongableHitObject strongable) return;
|
|
|
|
if (strongable.IsStrong != state)
|
|
strongable.IsStrong = state;
|
|
});
|
|
}
|
|
|
|
public void SetRimState(bool state)
|
|
{
|
|
if (SelectedItems.OfType<Hit>().All(h => h.Type == (state ? HitType.Rim : HitType.Centre)))
|
|
return;
|
|
|
|
EditorBeatmap.PerformOnSelection(h =>
|
|
{
|
|
if (h is Hit taikoHit)
|
|
taikoHit.Type = state ? HitType.Rim : HitType.Centre;
|
|
});
|
|
}
|
|
|
|
protected override IEnumerable<MenuItem> GetContextMenuItemsForSelection(IEnumerable<SelectionBlueprint<HitObject>> selection)
|
|
{
|
|
if (selection.All(s => s.Item is Hit))
|
|
{
|
|
yield return new TernaryStateToggleMenuItem("Rim")
|
|
{
|
|
State = { BindTarget = selectionRimState },
|
|
Hotkey = new Hotkey(new KeyCombination(InputKey.W), new KeyCombination(InputKey.R)),
|
|
};
|
|
}
|
|
|
|
if (selection.All(s => s.Item is TaikoHitObject))
|
|
{
|
|
yield return new TernaryStateToggleMenuItem("Strong")
|
|
{
|
|
State = { BindTarget = selectionStrongState },
|
|
Hotkey = new Hotkey(new KeyCombination(InputKey.E)),
|
|
};
|
|
}
|
|
|
|
foreach (var item in base.GetContextMenuItemsForSelection(selection))
|
|
yield return item;
|
|
}
|
|
|
|
public override bool HandleMovement(MoveSelectionEvent<HitObject> moveEvent) => true;
|
|
|
|
protected override void UpdateTernaryStates()
|
|
{
|
|
base.UpdateTernaryStates();
|
|
|
|
selectionRimState.Value = GetStateFromSelection(EditorBeatmap.SelectedHitObjects.OfType<Hit>(), h => h.Type == HitType.Rim);
|
|
selectionStrongState.Value = GetStateFromSelection(EditorBeatmap.SelectedHitObjects.OfType<TaikoStrongableHitObject>(), h => h.IsStrong);
|
|
}
|
|
}
|
|
}
|