mirror of
https://github.com/osukey/osukey.git
synced 2025-08-03 06:36:31 +09:00
Add grouping of visual tests
This commit is contained in:
29
osu.Game.Tests/Visual/Editor/TestCaseBeatDivisorControl.cs
Normal file
29
osu.Game.Tests/Visual/Editor/TestCaseBeatDivisorControl.cs
Normal file
@ -0,0 +1,29 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Screens.Edit;
|
||||
using osu.Game.Screens.Edit.Compose.Components;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
{
|
||||
public class TestCaseBeatDivisorControl : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(BindableBeatDivisor) };
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Child = new BeatDivisorControl(new BindableBeatDivisor())
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(90, 90)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
26
osu.Game.Tests/Visual/Editor/TestCaseEditorCompose.cs
Normal file
26
osu.Game.Tests/Visual/Editor/TestCaseEditorCompose.cs
Normal file
@ -0,0 +1,26 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Edit.Compose;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseEditorCompose : EditorClockTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(ComposeScreen) };
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo, Clock);
|
||||
Child = new ComposeScreen();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Screens.Edit.Components.RadioButtons;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseEditorComposeRadioButtons : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(DrawableRadioButton) };
|
||||
|
||||
public TestCaseEditorComposeRadioButtons()
|
||||
{
|
||||
RadioButtonCollection collection;
|
||||
Add(collection = new RadioButtonCollection
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Width = 150,
|
||||
Items = new[]
|
||||
{
|
||||
new RadioButton("Item 1", () => { }),
|
||||
new RadioButton("Item 2", () => { }),
|
||||
new RadioButton("Item 3", () => { }),
|
||||
new RadioButton("Item 4", () => { }),
|
||||
new RadioButton("Item 5", () => { })
|
||||
}
|
||||
});
|
||||
|
||||
for (int i = 0; i < collection.Items.Count; i++)
|
||||
{
|
||||
int l = i;
|
||||
AddStep($"Select item {l + 1}", () => collection.Items[l].Select());
|
||||
AddStep($"Deselect item {l + 1}", () => collection.Items[l].Deselect());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
140
osu.Game.Tests/Visual/Editor/TestCaseEditorComposeTimeline.cs
Normal file
140
osu.Game.Tests/Visual/Editor/TestCaseEditorComposeTimeline.cs
Normal file
@ -0,0 +1,140 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseEditorComposeTimeline : EditorClockTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(TimelineArea),
|
||||
typeof(Timeline),
|
||||
typeof(TimelineButton),
|
||||
typeof(CentreMarker)
|
||||
};
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Beatmap.Value = new WaveformTestBeatmap();
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new StartStopButton(),
|
||||
new AudioVisualiser(),
|
||||
}
|
||||
},
|
||||
new TimelineArea
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Size = new Vector2(0.8f, 100)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private class AudioVisualiser : CompositeDrawable
|
||||
{
|
||||
private readonly Drawable marker;
|
||||
|
||||
private readonly IBindable<WorkingBeatmap> beatmap = new Bindable<WorkingBeatmap>();
|
||||
private IAdjustableClock adjustableClock;
|
||||
|
||||
public AudioVisualiser()
|
||||
{
|
||||
Size = new Vector2(250, 25);
|
||||
|
||||
InternalChildren = new[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Alpha = 0.25f,
|
||||
},
|
||||
marker = new Box
|
||||
{
|
||||
RelativePositionAxes = Axes.X,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Width = 2,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IAdjustableClock adjustableClock, IBindable<WorkingBeatmap> beatmap)
|
||||
{
|
||||
this.adjustableClock = adjustableClock;
|
||||
this.beatmap.BindTo(beatmap);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (beatmap.Value.Track.IsLoaded)
|
||||
marker.X = (float)(adjustableClock.CurrentTime / beatmap.Value.Track.Length);
|
||||
}
|
||||
}
|
||||
|
||||
private class StartStopButton : Button
|
||||
{
|
||||
private IAdjustableClock adjustableClock;
|
||||
private bool started;
|
||||
|
||||
public StartStopButton()
|
||||
{
|
||||
BackgroundColour = Color4.SlateGray;
|
||||
Size = new Vector2(100, 50);
|
||||
Text = "Start";
|
||||
|
||||
Action = onClick;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IAdjustableClock adjustableClock)
|
||||
{
|
||||
this.adjustableClock = adjustableClock;
|
||||
}
|
||||
|
||||
private void onClick()
|
||||
{
|
||||
if (started)
|
||||
{
|
||||
adjustableClock.Stop();
|
||||
Text = "Start";
|
||||
}
|
||||
else
|
||||
{
|
||||
adjustableClock.Start();
|
||||
Text = "Stop";
|
||||
}
|
||||
|
||||
started = !started;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
98
osu.Game.Tests/Visual/Editor/TestCaseEditorMenuBar.cs
Normal file
98
osu.Game.Tests/Visual/Editor/TestCaseEditorMenuBar.cs
Normal file
@ -0,0 +1,98 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Screens.Edit.Components.Menus;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseEditorMenuBar : OsuTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(EditorMenuBar), typeof(ScreenSelectionTabControl) };
|
||||
|
||||
public TestCaseEditorMenuBar()
|
||||
{
|
||||
Add(new Container
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 50,
|
||||
Y = 50,
|
||||
Child = new EditorMenuBar
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Items = new[]
|
||||
{
|
||||
new MenuItem("File")
|
||||
{
|
||||
Items = new[]
|
||||
{
|
||||
new EditorMenuItem("Clear All Notes"),
|
||||
new EditorMenuItem("Open Difficulty..."),
|
||||
new EditorMenuItem("Save"),
|
||||
new EditorMenuItem("Create a new Difficulty..."),
|
||||
new EditorMenuItemSpacer(),
|
||||
new EditorMenuItem("Revert to Saved"),
|
||||
new EditorMenuItem("Revert to Saved (Full)"),
|
||||
new EditorMenuItemSpacer(),
|
||||
new EditorMenuItem("Test Beatmap"),
|
||||
new EditorMenuItem("Open AiMod"),
|
||||
new EditorMenuItemSpacer(),
|
||||
new EditorMenuItem("Upload Beatmap..."),
|
||||
new EditorMenuItem("Export Package"),
|
||||
new EditorMenuItem("Export Map Package"),
|
||||
new EditorMenuItem("Import from..."),
|
||||
new EditorMenuItemSpacer(),
|
||||
new EditorMenuItem("Open Song Folder"),
|
||||
new EditorMenuItem("Open .osu in Notepad"),
|
||||
new EditorMenuItem("Open .osb in Notepad"),
|
||||
new EditorMenuItemSpacer(),
|
||||
new EditorMenuItem("Exit"),
|
||||
}
|
||||
},
|
||||
new MenuItem("Timing")
|
||||
{
|
||||
Items = new[]
|
||||
{
|
||||
new EditorMenuItem("Time Signature"),
|
||||
new EditorMenuItem("Metronome Clicks"),
|
||||
new EditorMenuItemSpacer(),
|
||||
new EditorMenuItem("Add Timing Section"),
|
||||
new EditorMenuItem("Add Inheriting Section"),
|
||||
new EditorMenuItem("Reset Current Section"),
|
||||
new EditorMenuItem("Delete Timing Section"),
|
||||
new EditorMenuItem("Resnap Current Section"),
|
||||
new EditorMenuItemSpacer(),
|
||||
new EditorMenuItem("Timing Setup"),
|
||||
new EditorMenuItemSpacer(),
|
||||
new EditorMenuItem("Resnap All Notes", MenuItemType.Destructive),
|
||||
new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive),
|
||||
new EditorMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive),
|
||||
new EditorMenuItem("Delete All Timing Sections", MenuItemType.Destructive),
|
||||
new EditorMenuItemSpacer(),
|
||||
new EditorMenuItem("Set Current Position as Preview Point"),
|
||||
}
|
||||
},
|
||||
new MenuItem("Testing")
|
||||
{
|
||||
Items = new[]
|
||||
{
|
||||
new EditorMenuItem("Item 1"),
|
||||
new EditorMenuItem("Item 2"),
|
||||
new EditorMenuItem("Item 3"),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
419
osu.Game.Tests/Visual/Editor/TestCaseEditorSeekSnapping.cs
Normal file
419
osu.Game.Tests/Visual/Editor/TestCaseEditorSeekSnapping.cs
Normal file
@ -0,0 +1,419 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseEditorSeekSnapping : EditorClockTestCase
|
||||
{
|
||||
public TestCaseEditorSeekSnapping()
|
||||
{
|
||||
BeatDivisor.Value = 4;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
var testBeatmap = new Beatmap
|
||||
{
|
||||
ControlPointInfo = new ControlPointInfo
|
||||
{
|
||||
TimingPoints =
|
||||
{
|
||||
new TimingControlPoint { Time = 0, BeatLength = 200 },
|
||||
new TimingControlPoint { Time = 100, BeatLength = 400 },
|
||||
new TimingControlPoint { Time = 175, BeatLength = 800 },
|
||||
new TimingControlPoint { Time = 350, BeatLength = 200 },
|
||||
new TimingControlPoint { Time = 450, BeatLength = 100 },
|
||||
new TimingControlPoint { Time = 500, BeatLength = 307.69230769230802 }
|
||||
}
|
||||
},
|
||||
HitObjects =
|
||||
{
|
||||
new HitCircle { StartTime = 0 },
|
||||
new HitCircle { StartTime = 5000 }
|
||||
}
|
||||
};
|
||||
|
||||
Beatmap.Value = new TestWorkingBeatmap(testBeatmap, Clock);
|
||||
|
||||
Child = new TimingPointVisualiser(testBeatmap, 5000) { Clock = Clock };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests whether time is correctly seeked without snapping.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSeekNoSnapping()
|
||||
{
|
||||
reset();
|
||||
|
||||
// Forwards
|
||||
AddStep("Seek(0)", () => Clock.Seek(0));
|
||||
AddAssert("Time = 0", () => Clock.CurrentTime == 0);
|
||||
AddStep("Seek(33)", () => Clock.Seek(33));
|
||||
AddAssert("Time = 33", () => Clock.CurrentTime == 33);
|
||||
AddStep("Seek(89)", () => Clock.Seek(89));
|
||||
AddAssert("Time = 89", () => Clock.CurrentTime == 89);
|
||||
|
||||
// Backwards
|
||||
AddStep("Seek(25)", () => Clock.Seek(25));
|
||||
AddAssert("Time = 25", () => Clock.CurrentTime == 25);
|
||||
AddStep("Seek(0)", () => Clock.Seek(0));
|
||||
AddAssert("Time = 0", () => Clock.CurrentTime == 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests whether seeking to exact beat times puts us on the beat time.
|
||||
/// These are the white/yellow ticks on the graph.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSeekSnappingOnBeat()
|
||||
{
|
||||
reset();
|
||||
|
||||
AddStep("Seek(0), Snap", () => Clock.SeekSnapped(0));
|
||||
AddAssert("Time = 0", () => Clock.CurrentTime == 0);
|
||||
AddStep("Seek(50), Snap", () => Clock.SeekSnapped(50));
|
||||
AddAssert("Time = 50", () => Clock.CurrentTime == 50);
|
||||
AddStep("Seek(100), Snap", () => Clock.SeekSnapped(100));
|
||||
AddAssert("Time = 100", () => Clock.CurrentTime == 100);
|
||||
AddStep("Seek(175), Snap", () => Clock.SeekSnapped(175));
|
||||
AddAssert("Time = 175", () => Clock.CurrentTime == 175);
|
||||
AddStep("Seek(350), Snap", () => Clock.SeekSnapped(350));
|
||||
AddAssert("Time = 350", () => Clock.CurrentTime == 350);
|
||||
AddStep("Seek(400), Snap", () => Clock.SeekSnapped(400));
|
||||
AddAssert("Time = 400", () => Clock.CurrentTime == 400);
|
||||
AddStep("Seek(450), Snap", () => Clock.SeekSnapped(450));
|
||||
AddAssert("Time = 450", () => Clock.CurrentTime == 450);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests whether seeking to somewhere in the middle between beats puts us on the expected beats.
|
||||
/// For example, snapping between a white/yellow beat should put us on either the yellow or white, depending on which one we're closer too.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSeekSnappingInBetweenBeat()
|
||||
{
|
||||
reset();
|
||||
|
||||
AddStep("Seek(24), Snap", () => Clock.SeekSnapped(24));
|
||||
AddAssert("Time = 0", () => Clock.CurrentTime == 0);
|
||||
AddStep("Seek(26), Snap", () => Clock.SeekSnapped(26));
|
||||
AddAssert("Time = 50", () => Clock.CurrentTime == 50);
|
||||
AddStep("Seek(150), Snap", () => Clock.SeekSnapped(150));
|
||||
AddAssert("Time = 100", () => Clock.CurrentTime == 100);
|
||||
AddStep("Seek(170), Snap", () => Clock.SeekSnapped(170));
|
||||
AddAssert("Time = 175", () => Clock.CurrentTime == 175);
|
||||
AddStep("Seek(274), Snap", () => Clock.SeekSnapped(274));
|
||||
AddAssert("Time = 175", () => Clock.CurrentTime == 175);
|
||||
AddStep("Seek(276), Snap", () => Clock.SeekSnapped(276));
|
||||
AddAssert("Time = 350", () => Clock.CurrentTime == 350);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that when seeking forward with no beat snapping, beats are never explicitly snapped to, nor the next timing point (if we've skipped it).
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSeekForwardNoSnapping()
|
||||
{
|
||||
reset();
|
||||
|
||||
AddStep("SeekForward", () => Clock.SeekForward());
|
||||
AddAssert("Time = 50", () => Clock.CurrentTime == 50);
|
||||
AddStep("SeekForward", () => Clock.SeekForward());
|
||||
AddAssert("Time = 100", () => Clock.CurrentTime == 100);
|
||||
AddStep("SeekForward", () => Clock.SeekForward());
|
||||
AddAssert("Time = 200", () => Clock.CurrentTime == 200);
|
||||
AddStep("SeekForward", () => Clock.SeekForward());
|
||||
AddAssert("Time = 400", () => Clock.CurrentTime == 400);
|
||||
AddStep("SeekForward", () => Clock.SeekForward());
|
||||
AddAssert("Time = 450", () => Clock.CurrentTime == 450);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that when seeking forward with beat snapping, all beats are snapped to and timing points are never skipped.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSeekForwardSnappingOnBeat()
|
||||
{
|
||||
reset();
|
||||
|
||||
AddStep("SeekForward, Snap", () => Clock.SeekForward(true));
|
||||
AddAssert("Time = 50", () => Clock.CurrentTime == 50);
|
||||
AddStep("SeekForward, Snap", () => Clock.SeekForward(true));
|
||||
AddAssert("Time = 100", () => Clock.CurrentTime == 100);
|
||||
AddStep("SeekForward, Snap", () => Clock.SeekForward(true));
|
||||
AddAssert("Time = 175", () => Clock.CurrentTime == 175);
|
||||
AddStep("SeekForward, Snap", () => Clock.SeekForward(true));
|
||||
AddAssert("Time = 350", () => Clock.CurrentTime == 350);
|
||||
AddStep("SeekForward, Snap", () => Clock.SeekForward(true));
|
||||
AddAssert("Time = 400", () => Clock.CurrentTime == 400);
|
||||
AddStep("SeekForward, Snap", () => Clock.SeekForward(true));
|
||||
AddAssert("Time = 450", () => Clock.CurrentTime == 450);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that when seeking forward from in-between two beats, the next beat or timing point is snapped to, and no beats are skipped.
|
||||
/// This will also test being extremely close to the next beat/timing point, to ensure rounding is not an issue.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSeekForwardSnappingFromInBetweenBeat()
|
||||
{
|
||||
reset();
|
||||
|
||||
AddStep("Seek(49)", () => Clock.Seek(49));
|
||||
AddStep("SeekForward, Snap", () => Clock.SeekForward(true));
|
||||
AddAssert("Time = 50", () => Clock.CurrentTime == 50);
|
||||
AddStep("Seek(49.999)", () => Clock.Seek(49.999));
|
||||
AddStep("SeekForward, Snap", () => Clock.SeekForward(true));
|
||||
AddAssert("Time = 50", () => Clock.CurrentTime == 50);
|
||||
AddStep("Seek(99)", () => Clock.Seek(99));
|
||||
AddStep("SeekForward, Snap", () => Clock.SeekForward(true));
|
||||
AddAssert("Time = 100", () => Clock.CurrentTime == 100);
|
||||
AddStep("Seek(99.999)", () => Clock.Seek(99.999));
|
||||
AddStep("SeekForward, Snap", () => Clock.SeekForward(true));
|
||||
AddAssert("Time = 100", () => Clock.CurrentTime == 100);
|
||||
AddStep("Seek(174)", () => Clock.Seek(174));
|
||||
AddStep("SeekForward, Snap", () => Clock.SeekForward(true));
|
||||
AddAssert("Time = 175", () => Clock.CurrentTime == 175);
|
||||
AddStep("Seek(349)", () => Clock.Seek(349));
|
||||
AddStep("SeekForward, Snap", () => Clock.SeekForward(true));
|
||||
AddAssert("Time = 350", () => Clock.CurrentTime == 350);
|
||||
AddStep("Seek(399)", () => Clock.Seek(399));
|
||||
AddStep("SeekForward, Snap", () => Clock.SeekForward(true));
|
||||
AddAssert("Time = 400", () => Clock.CurrentTime == 400);
|
||||
AddStep("Seek(449)", () => Clock.Seek(449));
|
||||
AddStep("SeekForward, Snap", () => Clock.SeekForward(true));
|
||||
AddAssert("Time = 450", () => Clock.CurrentTime == 450);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that when seeking backward with no beat snapping, beats are never explicitly snapped to, nor the next timing point (if we've skipped it).
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSeekBackwardNoSnapping()
|
||||
{
|
||||
reset();
|
||||
|
||||
AddStep("Seek(450)", () => Clock.Seek(450));
|
||||
AddStep("SeekBackward", () => Clock.SeekBackward());
|
||||
AddAssert("Time = 400", () => Clock.CurrentTime == 400);
|
||||
AddStep("SeekBackward", () => Clock.SeekBackward());
|
||||
AddAssert("Time = 350", () => Clock.CurrentTime == 350);
|
||||
AddStep("SeekBackward", () => Clock.SeekBackward());
|
||||
AddAssert("Time = 150", () => Clock.CurrentTime == 150);
|
||||
AddStep("SeekBackward", () => Clock.SeekBackward());
|
||||
AddAssert("Time = 50", () => Clock.CurrentTime == 50);
|
||||
AddStep("SeekBackward", () => Clock.SeekBackward());
|
||||
AddAssert("Time = 0", () => Clock.CurrentTime == 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that when seeking backward with beat snapping, all beats are snapped to and timing points are never skipped.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSeekBackwardSnappingOnBeat()
|
||||
{
|
||||
reset();
|
||||
|
||||
AddStep("Seek(450)", () => Clock.Seek(450));
|
||||
AddStep("SeekBackward, Snap", () => Clock.SeekBackward(true));
|
||||
AddAssert("Time = 400", () => Clock.CurrentTime == 400);
|
||||
AddStep("SeekBackward, Snap", () => Clock.SeekBackward(true));
|
||||
AddAssert("Time = 350", () => Clock.CurrentTime == 350);
|
||||
AddStep("SeekBackward, Snap", () => Clock.SeekBackward(true));
|
||||
AddAssert("Time = 175", () => Clock.CurrentTime == 175);
|
||||
AddStep("SeekBackward, Snap", () => Clock.SeekBackward(true));
|
||||
AddAssert("Time = 100", () => Clock.CurrentTime == 100);
|
||||
AddStep("SeekBackward, Snap", () => Clock.SeekBackward(true));
|
||||
AddAssert("Time = 50", () => Clock.CurrentTime == 50);
|
||||
AddStep("SeekBackward, Snap", () => Clock.SeekBackward(true));
|
||||
AddAssert("Time = 0", () => Clock.CurrentTime == 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that when seeking backward from in-between two beats, the previous beat or timing point is snapped to, and no beats are skipped.
|
||||
/// This will also test being extremely close to the previous beat/timing point, to ensure rounding is not an issue.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSeekBackwardSnappingFromInBetweenBeat()
|
||||
{
|
||||
reset();
|
||||
|
||||
AddStep("Seek(451)", () => Clock.Seek(451));
|
||||
AddStep("SeekBackward, Snap", () => Clock.SeekBackward(true));
|
||||
AddAssert("Time = 450", () => Clock.CurrentTime == 450);
|
||||
AddStep("Seek(450.999)", () => Clock.Seek(450.999));
|
||||
AddStep("SeekBackward, Snap", () => Clock.SeekBackward(true));
|
||||
AddAssert("Time = 450", () => Clock.CurrentTime == 450);
|
||||
AddStep("Seek(401)", () => Clock.Seek(401));
|
||||
AddStep("SeekBackward, Snap", () => Clock.SeekBackward(true));
|
||||
AddAssert("Time = 400", () => Clock.CurrentTime == 400);
|
||||
AddStep("Seek(401.999)", () => Clock.Seek(401.999));
|
||||
AddStep("SeekBackward, Snap", () => Clock.SeekBackward(true));
|
||||
AddAssert("Time = 400", () => Clock.CurrentTime == 400);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests that there are no rounding issues when snapping to beats within a timing point with a floating-point beatlength.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSeekingWithFloatingPointBeatLength()
|
||||
{
|
||||
reset();
|
||||
|
||||
double lastTime = 0;
|
||||
|
||||
AddStep("Seek(0)", () => Clock.Seek(0));
|
||||
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
AddStep("SeekForward, Snap", () =>
|
||||
{
|
||||
lastTime = Clock.CurrentTime;
|
||||
Clock.SeekForward(true);
|
||||
});
|
||||
AddAssert("Time > lastTime", () => Clock.CurrentTime > lastTime);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
AddStep("SeekBackward, Snap", () =>
|
||||
{
|
||||
lastTime = Clock.CurrentTime;
|
||||
Clock.SeekBackward(true);
|
||||
});
|
||||
AddAssert("Time < lastTime", () => Clock.CurrentTime < lastTime);
|
||||
}
|
||||
|
||||
AddAssert("Time = 0", () => Clock.CurrentTime == 0);
|
||||
}
|
||||
|
||||
private void reset()
|
||||
{
|
||||
AddStep("Reset", () => Clock.Seek(0));
|
||||
}
|
||||
|
||||
private class TimingPointVisualiser : CompositeDrawable
|
||||
{
|
||||
private readonly double length;
|
||||
|
||||
private readonly Drawable tracker;
|
||||
|
||||
public TimingPointVisualiser(IBeatmap beatmap, double length)
|
||||
{
|
||||
this.length = length;
|
||||
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
Width = 0.75f;
|
||||
|
||||
FillFlowContainer timelineContainer;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Name = "Background",
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black.Opacity(85f)
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Name = "Tracks",
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding(15),
|
||||
Children = new[]
|
||||
{
|
||||
tracker = new Box
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
RelativePositionAxes = Axes.X,
|
||||
Width = 2,
|
||||
Colour = Color4.Red,
|
||||
},
|
||||
timelineContainer = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Spacing = new Vector2(0, 5)
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var timingPoints = beatmap.ControlPointInfo.TimingPoints;
|
||||
|
||||
for (int i = 0; i < timingPoints.Count; i++)
|
||||
{
|
||||
TimingControlPoint next = i == timingPoints.Count - 1 ? null : timingPoints[i + 1];
|
||||
timelineContainer.Add(new TimingPointTimeline(timingPoints[i], next?.Time ?? length, length));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
tracker.X = (float)(Time.Current / length);
|
||||
}
|
||||
|
||||
private class TimingPointTimeline : CompositeDrawable
|
||||
{
|
||||
public TimingPointTimeline(TimingControlPoint timingPoint, double endTime, double fullDuration)
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
|
||||
Box createMainTick(double time) => new Box
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomCentre,
|
||||
RelativePositionAxes = Axes.X,
|
||||
X = (float)(time / fullDuration),
|
||||
Height = 10,
|
||||
Width = 2
|
||||
};
|
||||
|
||||
Box createBeatTick(double time) => new Box
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomCentre,
|
||||
RelativePositionAxes = Axes.X,
|
||||
X = (float)(time / fullDuration),
|
||||
Height = 5,
|
||||
Width = 2,
|
||||
Colour = time > endTime ? Color4.Gray : Color4.Yellow
|
||||
};
|
||||
|
||||
AddInternal(createMainTick(timingPoint.Time));
|
||||
AddInternal(createMainTick(endTime));
|
||||
|
||||
for (double t = timingPoint.Time + timingPoint.BeatLength / 4; t < fullDuration; t += timingPoint.BeatLength / 4)
|
||||
AddInternal(createBeatTick(t));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.Edit.Components.Timelines.Summary;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseEditorSummaryTimeline : EditorClockTestCase
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(SummaryTimeline) };
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo, null);
|
||||
|
||||
Add(new SummaryTimeline
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(500, 50)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
82
osu.Game.Tests/Visual/Editor/TestCaseHitObjectComposer.cs
Normal file
82
osu.Game.Tests/Visual/Editor/TestCaseHitObjectComposer.cs
Normal file
@ -0,0 +1,82 @@
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Edit;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Edit;
|
||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles;
|
||||
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Screens.Edit.Compose;
|
||||
using osu.Game.Screens.Edit.Compose.Components;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
{
|
||||
[TestFixture]
|
||||
[Cached(Type = typeof(IPlacementHandler))]
|
||||
public class TestCaseHitObjectComposer : OsuTestCase, IPlacementHandler
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(SelectionHandler),
|
||||
typeof(DragBox),
|
||||
typeof(HitObjectComposer),
|
||||
typeof(OsuHitObjectComposer),
|
||||
typeof(BlueprintContainer),
|
||||
typeof(NotNullAttribute),
|
||||
typeof(HitCirclePiece),
|
||||
typeof(HitCircleSelectionBlueprint),
|
||||
typeof(HitCirclePlacementBlueprint),
|
||||
};
|
||||
|
||||
private HitObjectComposer composer;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Beatmap.Value = new TestWorkingBeatmap(new Beatmap
|
||||
{
|
||||
HitObjects = new List<HitObject>
|
||||
{
|
||||
new HitCircle { Position = new Vector2(256, 192), Scale = 0.5f },
|
||||
new HitCircle { Position = new Vector2(344, 148), Scale = 0.5f },
|
||||
new Slider
|
||||
{
|
||||
Position = new Vector2(128, 256),
|
||||
Path = new SliderPath(PathType.Linear, new[]
|
||||
{
|
||||
Vector2.Zero,
|
||||
new Vector2(216, 0),
|
||||
}),
|
||||
Scale = 0.5f,
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
|
||||
Dependencies.CacheAs<IAdjustableClock>(clock);
|
||||
Dependencies.CacheAs<IFrameBasedClock>(clock);
|
||||
|
||||
Child = composer = new OsuHitObjectComposer(new OsuRuleset());
|
||||
}
|
||||
|
||||
public void BeginPlacement(HitObject hitObject)
|
||||
{
|
||||
}
|
||||
|
||||
public void EndPlacement(HitObject hitObject) => composer.Add(hitObject);
|
||||
|
||||
public void Delete(HitObject hitObject) => composer.Remove(hitObject);
|
||||
}
|
||||
}
|
37
osu.Game.Tests/Visual/Editor/TestCasePlaybackControl.cs
Normal file
37
osu.Game.Tests/Visual/Editor/TestCasePlaybackControl.cs
Normal file
@ -0,0 +1,37 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Screens.Edit.Components;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCasePlaybackControl : OsuTestCase
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
|
||||
Dependencies.CacheAs<IAdjustableClock>(clock);
|
||||
Dependencies.CacheAs<IFrameBasedClock>(clock);
|
||||
|
||||
var playback = new PlaybackControl
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(200, 100)
|
||||
};
|
||||
|
||||
Beatmap.Value = new TestWorkingBeatmap(new Beatmap(), Clock);
|
||||
|
||||
Child = playback;
|
||||
}
|
||||
}
|
||||
}
|
54
osu.Game.Tests/Visual/Editor/TestCaseWaveContainer.cs
Normal file
54
osu.Game.Tests/Visual/Editor/TestCaseWaveContainer.cs
Normal file
@ -0,0 +1,54 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseWaveContainer : OsuTestCase
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
WaveContainer container;
|
||||
Add(container = new WaveContainer
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Size = new Vector2(400),
|
||||
FirstWaveColour = colours.Red,
|
||||
SecondWaveColour = colours.Green,
|
||||
ThirdWaveColour = colours.Blue,
|
||||
FourthWaveColour = colours.Pink,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black.Opacity(0.5f),
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Font = OsuFont.GetFont(size: 20),
|
||||
Text = @"Wave Container",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
AddStep(@"show", container.Show);
|
||||
AddStep(@"hide", container.Hide);
|
||||
}
|
||||
}
|
||||
}
|
74
osu.Game.Tests/Visual/Editor/TestCaseWaveform.cs
Normal file
74
osu.Game.Tests/Visual/Editor/TestCaseWaveform.cs
Normal file
@ -0,0 +1,74 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Audio;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseWaveform : OsuTestCase
|
||||
{
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Beatmap.Value = new WaveformTestBeatmap();
|
||||
|
||||
FillFlowContainer flow;
|
||||
Child = flow = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 10),
|
||||
};
|
||||
|
||||
for (int i = 1; i <= 16; i *= 2)
|
||||
{
|
||||
var newDisplay = new WaveformGraph
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Resolution = 1f / i,
|
||||
Waveform = Beatmap.Value.Waveform,
|
||||
};
|
||||
|
||||
flow.Add(new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 100,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
newDisplay,
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
Alpha = 0.75f
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Text = $"Resolution: {1f / i:0.00}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
129
osu.Game.Tests/Visual/Editor/TestCaseZoomableScrollContainer.cs
Normal file
129
osu.Game.Tests/Visual/Editor/TestCaseZoomableScrollContainer.cs
Normal file
@ -0,0 +1,129 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Screens.Edit.Compose.Components.Timeline;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
{
|
||||
public class TestCaseZoomableScrollContainer : ManualInputManagerTestCase
|
||||
{
|
||||
private readonly ZoomableScrollContainer scrollContainer;
|
||||
private readonly Drawable innerBox;
|
||||
|
||||
public TestCaseZoomableScrollContainer()
|
||||
{
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 250,
|
||||
Width = 0.75f,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = OsuColour.Gray(30)
|
||||
},
|
||||
scrollContainer = new ZoomableScrollContainer { RelativeSizeAxes = Axes.Both }
|
||||
}
|
||||
},
|
||||
new MenuCursor()
|
||||
};
|
||||
|
||||
scrollContainer.Add(innerBox = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = ColourInfo.GradientHorizontal(new Color4(0.8f, 0.6f, 0.4f, 1f), new Color4(0.4f, 0.6f, 0.8f, 1f))
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestZoom0()
|
||||
{
|
||||
reset();
|
||||
AddAssert("Box at 0", () => Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft));
|
||||
AddAssert("Box width = 1x", () => Precision.AlmostEquals(boxQuad.Size, scrollQuad.Size));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestZoom10()
|
||||
{
|
||||
reset();
|
||||
AddStep("Set zoom = 10", () => scrollContainer.Zoom = 10);
|
||||
AddAssert("Box at 1/2", () => Precision.AlmostEquals(boxQuad.Centre, scrollQuad.Centre, 1));
|
||||
AddAssert("Box width = 10x", () => Precision.AlmostEquals(boxQuad.Size.X, 10 * scrollQuad.Size.X));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMouseZoomInOnceOutOnce()
|
||||
{
|
||||
reset();
|
||||
|
||||
// Scroll in at 0.25
|
||||
AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y)));
|
||||
AddStep("Scroll by 3", () => InputManager.ScrollBy(new Vector2(0, 3)));
|
||||
AddAssert("Box not at 0", () => !Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft));
|
||||
AddAssert("Box 1/4 at 1/4", () => Precision.AlmostEquals(boxQuad.TopLeft.X + 0.25f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X));
|
||||
|
||||
// Scroll out at 0.25
|
||||
AddStep("Scroll by -3", () => InputManager.ScrollBy(new Vector2(0, -3)));
|
||||
AddAssert("Box at 0", () => Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft));
|
||||
AddAssert("Box 1/4 at 1/4", () => Precision.AlmostEquals(boxQuad.TopLeft.X + 0.25f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMouseZoomInTwiceOutTwice()
|
||||
{
|
||||
reset();
|
||||
|
||||
// Scroll in at 0.25
|
||||
AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y)));
|
||||
AddStep("Scroll by 1", () => InputManager.ScrollBy(new Vector2(0, 1)));
|
||||
|
||||
// Scroll in at 0.6
|
||||
AddStep("Move mouse to 0.75x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.75f * scrollQuad.Size.X, scrollQuad.Centre.Y)));
|
||||
AddStep("Scroll by 1", () => InputManager.ScrollBy(new Vector2(0, 1)));
|
||||
AddAssert("Box not at 0", () => !Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft));
|
||||
|
||||
// Very hard to determine actual position, so approximate
|
||||
AddAssert("Box at correct position (1)", () => Precision.DefinitelyBigger(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, boxQuad.TopLeft.X + 0.25f * boxQuad.Size.X));
|
||||
AddAssert("Box at correct position (2)", () => Precision.DefinitelyBigger(scrollQuad.TopLeft.X + 0.6f * scrollQuad.Size.X, boxQuad.TopLeft.X + 0.3f * boxQuad.Size.X));
|
||||
AddAssert("Box at correct position (3)", () => Precision.DefinitelyBigger(boxQuad.TopLeft.X + 0.6f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.6f * scrollQuad.Size.X));
|
||||
|
||||
// Scroll out at 0.6
|
||||
AddStep("Scroll by -1", () => InputManager.ScrollBy(new Vector2(0, -1)));
|
||||
|
||||
// Scroll out at 0.25
|
||||
AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y)));
|
||||
AddStep("Scroll by -1", () => InputManager.ScrollBy(new Vector2(0, -1)));
|
||||
AddAssert("Box at 0", () => Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft));
|
||||
}
|
||||
|
||||
private void reset()
|
||||
{
|
||||
AddStep("Reset", () =>
|
||||
{
|
||||
scrollContainer.Zoom = 0;
|
||||
scrollContainer.ScrollTo(0, false);
|
||||
});
|
||||
}
|
||||
|
||||
private Quad scrollQuad => scrollContainer.ScreenSpaceDrawQuad;
|
||||
private Quad boxQuad => innerBox.ScreenSpaceDrawQuad;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user