Skip to content

Commit fa3831d

Browse files
authored
Merge pull request #92 from winnerspiros/timing-screen-selection-retention-17106411480944945514
Retain control point selection over undo/redo operations
2 parents 5909cf1 + 01d1033 commit fa3831d

2 files changed

Lines changed: 35 additions & 48 deletions

File tree

osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs

Lines changed: 16 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,8 @@ public void SetUpSteps()
7575
AddUntilStep("Wait for rows to load", () => Child.ChildrenOfType<EffectRowAttribute>().Any());
7676
}
7777

78-
// TODO: this is best-effort for now, but the comment out test below should probably be how things should work.
79-
// Was originally working as of https://github.com/ppy/osu/pull/26141; Regressed at some point.
8078
[Test]
81-
public void TestSelectionDismissedOnUndo()
79+
public void TestSelectedRetainedOverUndo()
8280
{
8381
AddStep("Select first timing point", () =>
8482
{
@@ -97,54 +95,26 @@ public void TestSelectionDismissedOnUndo()
9795

9896
AddUntilStep("wait for offset changed", () =>
9997
{
100-
return timingScreen.SelectedGroup.Value.ControlPoints.Any(c => c is TimingControlPoint) && timingScreen.SelectedGroup.Value?.Time > 2170;
98+
return timingScreen.SelectedGroup.Value?.ControlPoints.Any(c => c is TimingControlPoint) == true && timingScreen.SelectedGroup.Value?.Time > 2170;
10199
});
102100

103101
AddStep("undo", () => changeHandler?.RestoreState(-1));
104102

105-
AddUntilStep("selection dismissed", () => timingScreen.SelectedGroup.Value, () => Is.Null);
106-
}
103+
AddUntilStep("selection retained", () =>
104+
{
105+
return timingScreen.SelectedGroup.Value?.ControlPoints.Any(c => c is TimingControlPoint) == true && timingScreen.SelectedGroup.Value?.Time == 2170;
106+
});
107107

108-
// [Test]
109-
// public void TestSelectedRetainedOverUndo()
110-
// {
111-
// AddStep("Select first timing point", () =>
112-
// {
113-
// InputManager.MoveMouseTo(Child.ChildrenOfType<TimingRowAttribute>().First());
114-
// InputManager.Click(MouseButton.Left);
115-
// });
116-
//
117-
// AddUntilStep("Selection changed", () => timingScreen.SelectedGroup.Value?.Time == 2170);
118-
// AddUntilStep("Ensure seeked to correct time", () => EditorClock.CurrentTimeAccurate == 2170);
119-
//
120-
// AddStep("Adjust offset", () =>
121-
// {
122-
// InputManager.MoveMouseTo(timingScreen.ChildrenOfType<TimingAdjustButton>().First().ScreenSpaceDrawQuad.Centre + new Vector2(20, 0));
123-
// InputManager.Click(MouseButton.Left);
124-
// });
125-
//
126-
// AddUntilStep("wait for offset changed", () =>
127-
// {
128-
// return timingScreen.SelectedGroup.Value.ControlPoints.Any(c => c is TimingControlPoint) && timingScreen.SelectedGroup.Value?.Time > 2170;
129-
// });
130-
//
131-
// AddStep("undo", () => changeHandler?.RestoreState(-1));
132-
//
133-
// AddUntilStep("selection retained", () =>
134-
// {
135-
// return timingScreen.SelectedGroup.Value.ControlPoints.Any(c => c is TimingControlPoint) && timingScreen.SelectedGroup.Value?.Time > 2170;
136-
// });
137-
//
138-
// AddAssert("check group count", () => editorBeatmap.ControlPointInfo.Groups.Count, () => Is.EqualTo(10));
139-
//
140-
// AddStep("Adjust offset", () =>
141-
// {
142-
// InputManager.MoveMouseTo(timingScreen.ChildrenOfType<TimingAdjustButton>().First().ScreenSpaceDrawQuad.Centre + new Vector2(20, 0));
143-
// InputManager.Click(MouseButton.Left);
144-
// });
145-
//
146-
// AddAssert("check group count", () => editorBeatmap.ControlPointInfo.Groups.Count, () => Is.EqualTo(10));
147-
// }
108+
AddAssert("check group count", () => editorBeatmap.ControlPointInfo.Groups.Count, () => Is.EqualTo(9));
109+
110+
AddStep("Adjust offset", () =>
111+
{
112+
InputManager.MoveMouseTo(timingScreen.ChildrenOfType<TimingAdjustButton>().First().ScreenSpaceDrawQuad.Centre + new Vector2(20, 0));
113+
InputManager.Click(MouseButton.Left);
114+
});
115+
116+
AddAssert("check group count", () => editorBeatmap.ControlPointInfo.Groups.Count, () => Is.EqualTo(9));
117+
}
148118

149119
[Test]
150120
public void TestScrollControlGroupIntoView()

osu.Game/Screens/Edit/Timing/ControlPointList.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,25 @@ private void onUndoRedo()
187187
{
188188
// Best effort. We have no tracking of control points through undo/redo changes.
189189
// If we don't deselect, things like offset changes could spawn groups to be added from previous states (see https://github.com/ppy/osu/issues/31098).
190-
if (selectedGroup.Value != null && !Beatmap.ControlPointInfo.Groups.Contains(selectedGroup.Value))
191-
selectedGroup.Value = null;
190+
var lastSelected = selectedGroup.Value;
191+
192+
if (lastSelected == null)
193+
{
194+
SelectClosestTimingPoint?.Invoke();
195+
196+
return;
197+
}
198+
199+
// Always clear the old (potentially orphaned) reference.
200+
selectedGroup.Value = null;
201+
202+
// Try and find a group at the exact same time.
203+
var matchingGroup = Beatmap.ControlPointInfo.GroupAt(lastSelected.Time);
204+
205+
if (matchingGroup != null)
206+
selectedGroup.Value = matchingGroup;
207+
else
208+
SelectClosestTimingPoint?.Invoke();
192209
}
193210

194211
protected override void Dispose(bool isDisposing)

0 commit comments

Comments
 (0)