Merge pull request #30284 from bdach/mania-selection-preservation-again

Fix flip operations sometimes not preserving selection in mania editor
This commit is contained in:
Dean Herbert 2024-10-23 16:13:20 +09:00 committed by GitHub
commit 7df3976d1c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 6 deletions

View File

@ -118,5 +118,45 @@ public void TestOffScreenObjectsRemainSelectedOnColumnChange()
AddAssert("all objects in last column", () => EditorBeatmap.HitObjects.All(ho => ((ManiaHitObject)ho).Column == 3)); AddAssert("all objects in last column", () => EditorBeatmap.HitObjects.All(ho => ((ManiaHitObject)ho).Column == 3));
AddAssert("all objects remain selected", () => EditorBeatmap.SelectedHitObjects.SequenceEqual(EditorBeatmap.HitObjects)); AddAssert("all objects remain selected", () => EditorBeatmap.SelectedHitObjects.SequenceEqual(EditorBeatmap.HitObjects));
} }
[Test]
public void TestOffScreenObjectsRemainSelectedOnHorizontalFlip()
{
AddStep("create objects", () =>
{
for (int i = 0; i < 20; ++i)
EditorBeatmap.Add(new Note { StartTime = 1000 * i, Column = i % 4 });
});
AddStep("select everything", () => EditorBeatmap.SelectedHitObjects.AddRange(EditorBeatmap.HitObjects));
AddStep("flip", () =>
{
InputManager.PressKey(Key.ControlLeft);
InputManager.Key(Key.H);
InputManager.ReleaseKey(Key.ControlLeft);
});
AddAssert("all objects remain selected", () => EditorBeatmap.SelectedHitObjects.SequenceEqual(EditorBeatmap.HitObjects));
}
[Test]
public void TestOffScreenObjectsRemainSelectedOnVerticalFlip()
{
AddStep("create objects", () =>
{
for (int i = 0; i < 20; ++i)
EditorBeatmap.Add(new Note { StartTime = 1000 * i, Column = i % 4 });
});
AddStep("select everything", () => EditorBeatmap.SelectedHitObjects.AddRange(EditorBeatmap.HitObjects));
AddStep("flip", () =>
{
InputManager.PressKey(Key.ControlLeft);
InputManager.Key(Key.J);
InputManager.ReleaseKey(Key.ControlLeft);
});
AddAssert("all objects remain selected", () => EditorBeatmap.SelectedHitObjects.SequenceEqual(EditorBeatmap.HitObjects.Reverse()));
}
} }
} }

View File

@ -54,9 +54,8 @@ public override bool HandleFlip(Direction direction, bool flipOverOrigin)
int firstColumn = flipOverOrigin ? 0 : selectedObjects.Min(ho => ho.Column); int firstColumn = flipOverOrigin ? 0 : selectedObjects.Min(ho => ho.Column);
int lastColumn = flipOverOrigin ? (int)EditorBeatmap.BeatmapInfo.Difficulty.CircleSize - 1 : selectedObjects.Max(ho => ho.Column); int lastColumn = flipOverOrigin ? (int)EditorBeatmap.BeatmapInfo.Difficulty.CircleSize - 1 : selectedObjects.Max(ho => ho.Column);
EditorBeatmap.PerformOnSelection(hitObject => performOnSelection(maniaObject =>
{ {
var maniaObject = (ManiaHitObject)hitObject;
maniaPlayfield.Remove(maniaObject); maniaPlayfield.Remove(maniaObject);
maniaObject.Column = firstColumn + (lastColumn - maniaObject.Column); maniaObject.Column = firstColumn + (lastColumn - maniaObject.Column);
maniaPlayfield.Add(maniaObject); maniaPlayfield.Add(maniaObject);
@ -71,7 +70,7 @@ public override bool HandleFlip(Direction direction, bool flipOverOrigin)
double selectionStartTime = selectedObjects.Min(ho => ho.StartTime); double selectionStartTime = selectedObjects.Min(ho => ho.StartTime);
double selectionEndTime = selectedObjects.Max(ho => ho.GetEndTime()); double selectionEndTime = selectedObjects.Max(ho => ho.GetEndTime());
EditorBeatmap.PerformOnSelection(hitObject => performOnSelection(hitObject =>
{ {
hitObject.StartTime = selectionStartTime + (selectionEndTime - hitObject.GetEndTime()); hitObject.StartTime = selectionStartTime + (selectionEndTime - hitObject.GetEndTime());
}); });
@ -117,14 +116,21 @@ private void performColumnMovement(int lastColumn, MoveSelectionEvent<HitObject>
columnDelta = Math.Clamp(columnDelta, -minColumn, maniaPlayfield.TotalColumns - 1 - maxColumn); columnDelta = Math.Clamp(columnDelta, -minColumn, maniaPlayfield.TotalColumns - 1 - maxColumn);
EditorBeatmap.PerformOnSelection(h => performOnSelection(h =>
{ {
maniaPlayfield.Remove(h); maniaPlayfield.Remove(h);
((ManiaHitObject)h).Column += columnDelta; h.Column += columnDelta;
maniaPlayfield.Add(h); maniaPlayfield.Add(h);
}); });
}
// `HitObjectUsageEventBuffer`'s usage transferal flows and the playfield's `SetKeepAlive()` functionality do not combine well with this operation's usage pattern, private void performOnSelection(Action<ManiaHitObject> action)
{
var selectedObjects = EditorBeatmap.SelectedHitObjects.OfType<ManiaHitObject>().ToArray();
EditorBeatmap.PerformOnSelection(h => action.Invoke((ManiaHitObject)h));
// `HitObjectUsageEventBuffer`'s usage transferal flows and the playfield's `SetKeepAlive()` functionality do not combine well with mania's usage patterns,
// leading to selections being sometimes partially dropped if some of the objects being moved are off screen // leading to selections being sometimes partially dropped if some of the objects being moved are off screen
// (check blame for detailed explanation). // (check blame for detailed explanation).
// thus, ensure that selection is preserved manually. // thus, ensure that selection is preserved manually.