Skip to content

Commit

Permalink
Merge branch 'master' into auto-addition2
Browse files Browse the repository at this point in the history
  • Loading branch information
peppy authored Oct 24, 2024
2 parents 77bd0e8 + 7b2ca2f commit 787d3dc
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,45 @@ public void TestOffScreenObjectsRemainSelectedOnColumnChange()
AddAssert("all objects in last column", () => EditorBeatmap.HitObjects.All(ho => ((ManiaHitObject)ho).Column == 3));
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()));
}
}
}
18 changes: 12 additions & 6 deletions osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,8 @@ public override bool HandleFlip(Direction direction, bool flipOverOrigin)
int firstColumn = flipOverOrigin ? 0 : selectedObjects.Min(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);
maniaObject.Column = firstColumn + (lastColumn - maniaObject.Column);
maniaPlayfield.Add(maniaObject);
Expand All @@ -71,7 +70,7 @@ public override bool HandleFlip(Direction direction, bool flipOverOrigin)
double selectionStartTime = selectedObjects.Min(ho => ho.StartTime);
double selectionEndTime = selectedObjects.Max(ho => ho.GetEndTime());

EditorBeatmap.PerformOnSelection(hitObject =>
performOnSelection(hitObject =>
{
hitObject.StartTime = selectionStartTime + (selectionEndTime - hitObject.GetEndTime());
});
Expand Down Expand Up @@ -117,14 +116,21 @@ private void performColumnMovement(int lastColumn, MoveSelectionEvent<HitObject>

columnDelta = Math.Clamp(columnDelta, -minColumn, maniaPlayfield.TotalColumns - 1 - maxColumn);

EditorBeatmap.PerformOnSelection(h =>
performOnSelection(h =>
{
maniaPlayfield.Remove(h);
((ManiaHitObject)h).Column += columnDelta;
h.Column += columnDelta;
maniaPlayfield.Add(h);
});
}

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 this operation's usage pattern,
// `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
// (check blame for detailed explanation).
// thus, ensure that selection is preserved manually.
Expand Down
55 changes: 55 additions & 0 deletions osu.Game.Rulesets.Osu.Tests/Editor/TestSceneToolSwitching.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// 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.Linq;
using NUnit.Framework;
using osu.Framework.Testing;
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Tests.Visual;
using osuTK;
using osuTK.Input;

namespace osu.Game.Rulesets.Osu.Tests.Editor
{
public partial class TestSceneToolSwitching : EditorTestScene
{
protected override Ruleset CreateEditorRuleset() => new OsuRuleset();

[Test]
public void TestSliderAnchorMoveOperationEndsOnSwitchingTool()
{
var initialPosition = Vector2.Zero;

AddStep("store original anchor position", () => initialPosition = EditorBeatmap.HitObjects.OfType<Slider>().First().Path.ControlPoints.ElementAt(1).Position);
AddStep("select first slider", () => EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects.OfType<Slider>().First()));
AddStep("move to second anchor", () => InputManager.MoveMouseTo(this.ChildrenOfType<PathControlPointPiece<Slider>>().ElementAt(1)));
AddStep("start dragging", () => InputManager.PressButton(MouseButton.Left));
AddStep("drag away", () => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(0, -200)));
AddStep("switch tool", () => InputManager.PressButton(MouseButton.Button1));
AddStep("undo", () => Editor.Undo());
AddAssert("anchor back at original position",
() => EditorBeatmap.HitObjects.OfType<Slider>().First().Path.ControlPoints.ElementAt(1).Position,
() => Is.EqualTo(initialPosition));
}

[Test]
public void TestSliderAnchorCreationOperationEndsOnSwitchingTool()
{
AddStep("select first slider", () => EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects.OfType<Slider>().First()));
AddStep("move to second anchor", () => InputManager.MoveMouseTo(this.ChildrenOfType<PathControlPointPiece<Slider>>().ElementAt(1), new Vector2(-50, 0)));
AddStep("quick-create anchor", () =>
{
InputManager.PressKey(Key.ControlLeft);
InputManager.PressButton(MouseButton.Left);
InputManager.ReleaseKey(Key.ControlLeft);
});
AddStep("drag away", () => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(0, -200)));
AddStep("switch tool", () => InputManager.PressKey(Key.Number3));
AddStep("drag away further", () => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(0, -200)));
AddStep("select first slider", () => EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects.OfType<Slider>().First()));
AddStep("undo", () => Editor.Undo());
AddAssert("slider has three anchors again", () => EditorBeatmap.HitObjects.OfType<Slider>().First().Path.ControlPoints, () => Has.Count.EqualTo(3));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,9 @@ protected override void Dispose(bool isDisposing)
base.Dispose(isDisposing);
foreach (var p in Pieces)
p.ControlPoint.Changed -= controlPointChanged;

if (draggedControlPointIndex >= 0)
DragEnded();
}

private void selectionRequested(PathControlPointPiece<T> piece, MouseButtonEvent e)
Expand Down Expand Up @@ -392,7 +395,7 @@ private void updatePathTypeOfSelectedPieces(PathType? type)

private Vector2[] dragStartPositions;
private PathType?[] dragPathTypes;
private int draggedControlPointIndex;
private int draggedControlPointIndex = -1;
private HashSet<PathControlPoint> selectedControlPoints;

private List<MenuItem> curveTypeItems;
Expand Down Expand Up @@ -473,7 +476,11 @@ public void DragInProgress(DragEvent e)
EnsureValidPathTypes();
}

public void DragEnded() => changeHandler?.EndChange();
public void DragEnded()
{
changeHandler?.EndChange();
draggedControlPointIndex = -1;
}

#endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ protected override void OnDeselected()
{
base.OnDeselected();

if (placementControlPoint != null)
endControlPointPlacement();

updateVisualDefinition();
BodyPiece.RecyclePath();
}
Expand Down Expand Up @@ -377,13 +380,16 @@ protected override void OnDrag(DragEvent e)
protected override void OnMouseUp(MouseUpEvent e)
{
if (placementControlPoint != null)
{
if (IsDragged)
ControlPointVisualiser?.DragEnded();
endControlPointPlacement();
}

placementControlPoint = null;
changeHandler?.EndChange();
}
private void endControlPointPlacement()
{
if (IsDragged)
ControlPointVisualiser?.DragEnded();

placementControlPoint = null;
changeHandler?.EndChange();
}

protected override bool OnKeyDown(KeyDownEvent e)
Expand Down
15 changes: 15 additions & 0 deletions osu.Game.Rulesets.Osu/Edit/PreciseRotationPopover.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Screens.Edit.Components.RadioButtons;
using osu.Game.Screens.Edit.Compose.Components;
Expand Down Expand Up @@ -55,6 +58,7 @@ private void load()
MaxValue = 360,
Precision = 1
},
KeyboardStep = 1f,
Instantaneous = true
},
rotationOrigin = new EditorRadioButtonCollection
Expand Down Expand Up @@ -126,6 +130,17 @@ protected override void PopOut()
if (IsLoaded)
rotationHandler.Commit();
}

public override bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
{
if (e.Action == GlobalAction.Select && !e.Repeat)
{
this.HidePopover();
return true;
}

return base.OnPressed(e);
}
}

public enum RotationOrigin
Expand Down
15 changes: 15 additions & 0 deletions osu.Game.Rulesets.Osu/Edit/PreciseScalePopover.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.UI;
Expand Down Expand Up @@ -70,6 +73,7 @@ private void load(EditorBeatmap editorBeatmap)
Value = 1,
Default = 1,
},
KeyboardStep = 0.01f,
Instantaneous = true
},
scaleOrigin = new EditorRadioButtonCollection
Expand Down Expand Up @@ -282,6 +286,17 @@ protected override void PopOut()

if (IsLoaded) scaleHandler.Commit();
}

public override bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
{
if (e.Action == GlobalAction.Select && !e.Repeat)
{
this.HidePopover();
return true;
}

return base.OnPressed(e);
}
}

public enum ScaleOrigin
Expand Down
1 change: 1 addition & 0 deletions osu.Game.Tests/NonVisual/FirstAvailableHitWindowsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public override event Action<JudgementResult> RevertResult

public override IAdjustableAudioComponent Audio { get; }
public override Playfield Playfield { get; }
public override PlayfieldAdjustmentContainer PlayfieldAdjustmentContainer { get; }
public override Container Overlays { get; }
public override Container FrameStableComponents { get; }
public override IFrameStableClock FrameStableClock { get; }
Expand Down
1 change: 1 addition & 0 deletions osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ public override event Action<JudgementResult> RevertResult

public override IAdjustableAudioComponent Audio { get; }
public override Playfield Playfield { get; }
public override PlayfieldAdjustmentContainer PlayfieldAdjustmentContainer { get; }
public override Container Overlays { get; }
public override Container FrameStableComponents { get; }
public override IFrameStableClock FrameStableClock { get; }
Expand Down
4 changes: 2 additions & 2 deletions osu.Game/Overlays/BeatmapSet/MetadataSectionSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ public MetadataSectionSource(Action<string>? searchAction = null)
protected override void AddMetadata(string metadata, LinkFlowContainer loaded)
{
if (SearchAction != null)
loaded.AddLink(metadata, () => SearchAction(metadata));
loaded.AddLink(metadata, () => SearchAction($@"source=""""{metadata}"""""));
else
loaded.AddLink(metadata, LinkAction.SearchBeatmapSet, metadata);
loaded.AddLink(metadata, LinkAction.SearchBeatmapSet, $@"source=""""{metadata}""""");
}
}
}
20 changes: 12 additions & 8 deletions osu.Game/Rulesets/UI/DrawableRuleset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,20 @@ public abstract partial class DrawableRuleset<TObject> : DrawableRuleset, IProvi
/// </summary>
public override Playfield Playfield => playfield.Value;

public override PlayfieldAdjustmentContainer PlayfieldAdjustmentContainer => playfieldAdjustmentContainer;

public override Container Overlays { get; } = new Container { RelativeSizeAxes = Axes.Both };

public override IAdjustableAudioComponent Audio => audioContainer;

private readonly AudioContainer audioContainer = new AudioContainer { RelativeSizeAxes = Axes.Both };

/// <summary>
/// A container which encapsulates the <see cref="Playfield"/> and provides any adjustments to
/// ensure correct scale and position.
/// </summary>
public virtual PlayfieldAdjustmentContainer PlayfieldAdjustmentContainer { get; private set; }

public override Container FrameStableComponents { get; } = new Container { RelativeSizeAxes = Axes.Both };

public override IFrameStableClock FrameStableClock => frameStabilityContainer;

private readonly PlayfieldAdjustmentContainer playfieldAdjustmentContainer;

private bool allowBackwardsSeeks;

public override bool AllowBackwardsSeeks
Expand Down Expand Up @@ -146,6 +144,7 @@ protected DrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList<Mod>
RelativeSizeAxes = Axes.Both;

KeyBindingInputManager = CreateInputManager();
playfieldAdjustmentContainer = CreatePlayfieldAdjustmentContainer();
playfield = new Lazy<Playfield>(() => CreatePlayfield().With(p =>
{
p.NewResult += (_, r) => NewResult?.Invoke(r);
Expand Down Expand Up @@ -197,8 +196,7 @@ private void load(CancellationToken? cancellationToken)
audioContainer.WithChild(KeyBindingInputManager
.WithChildren(new Drawable[]
{
PlayfieldAdjustmentContainer = CreatePlayfieldAdjustmentContainer()
.WithChild(Playfield),
playfieldAdjustmentContainer.WithChild(Playfield),
Overlays
})),
}
Expand Down Expand Up @@ -456,6 +454,12 @@ public abstract partial class DrawableRuleset : CompositeDrawable
/// </summary>
public abstract Playfield Playfield { get; }

/// <summary>
/// A container which encapsulates the <see cref="Playfield"/> and provides any adjustments to
/// ensure correct scale and position.
/// </summary>
public abstract PlayfieldAdjustmentContainer PlayfieldAdjustmentContainer { get; }

/// <summary>
/// Content to be placed above hitobjects. Will be affected by frame stability and adjustments applied to <see cref="Audio"/>.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion osu.Game/Screens/Play/HUDOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ protected override void Update()
PlayfieldSkinLayer.Position = ToLocalSpace(playfieldScreenSpaceDrawQuad.TopLeft);
PlayfieldSkinLayer.Width = (ToLocalSpace(playfieldScreenSpaceDrawQuad.TopRight) - ToLocalSpace(playfieldScreenSpaceDrawQuad.TopLeft)).Length;
PlayfieldSkinLayer.Height = (ToLocalSpace(playfieldScreenSpaceDrawQuad.BottomLeft) - ToLocalSpace(playfieldScreenSpaceDrawQuad.TopLeft)).Length;
PlayfieldSkinLayer.Rotation = drawableRuleset.Playfield.Rotation;
PlayfieldSkinLayer.Rotation = drawableRuleset.PlayfieldAdjustmentContainer.Rotation;
}

float? lowestTopScreenSpaceLeft = null;
Expand Down
3 changes: 3 additions & 0 deletions osu.Game/Skinning/SkinnableSound.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ private void updateSamples()
{
bool wasPlaying = IsPlaying;

if (wasPlaying && Looping)
Stop();

// Remove all pooled samples (return them to the pool), and dispose the rest.
samplesContainer.RemoveAll(s => s.IsInPool, false);
samplesContainer.Clear();
Expand Down

0 comments on commit 787d3dc

Please sign in to comment.