1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 18:23:04 +08:00

Merge branch 'master' into hyperdash-full-catch-width

This commit is contained in:
Dean Herbert 2020-08-22 19:55:45 +09:00 committed by GitHub
commit b98d4d9cff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 208 additions and 77 deletions

View File

@ -1,7 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Game.Audio;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Catch.UI;
@ -38,7 +40,11 @@ namespace osu.Game.Rulesets.Catch.Tests
new Vector2(width, 0) new Vector2(width, 0)
}), }),
StartTime = i * 2000, StartTime = i * 2000,
NewCombo = i % 8 == 0 NewCombo = i % 8 == 0,
Samples = new List<HitSampleInfo>(new[]
{
new HitSampleInfo { Bank = "normal", Name = "hitnormal", Volume = 100 }
})
}); });
} }

View File

@ -20,19 +20,19 @@ namespace osu.Game.Rulesets.Catch.Tests
foreach (FruitVisualRepresentation rep in Enum.GetValues(typeof(FruitVisualRepresentation))) foreach (FruitVisualRepresentation rep in Enum.GetValues(typeof(FruitVisualRepresentation)))
AddStep($"show {rep}", () => SetContents(() => createDrawable(rep))); AddStep($"show {rep}", () => SetContents(() => createDrawable(rep)));
AddStep("show droplet", () => SetContents(createDrawableDroplet)); AddStep("show droplet", () => SetContents(() => createDrawableDroplet()));
AddStep("show tiny droplet", () => SetContents(createDrawableTinyDroplet)); AddStep("show tiny droplet", () => SetContents(createDrawableTinyDroplet));
foreach (FruitVisualRepresentation rep in Enum.GetValues(typeof(FruitVisualRepresentation))) foreach (FruitVisualRepresentation rep in Enum.GetValues(typeof(FruitVisualRepresentation)))
AddStep($"show hyperdash {rep}", () => SetContents(() => createDrawable(rep, true))); AddStep($"show hyperdash {rep}", () => SetContents(() => createDrawable(rep, true)));
AddStep("show hyperdash droplet", () => SetContents(() => createDrawableDroplet(true)));
} }
private Drawable createDrawableTinyDroplet() private Drawable createDrawableTinyDroplet()
{ {
var droplet = new TinyDroplet var droplet = new TestCatchTinyDroplet
{ {
StartTime = Clock.CurrentTime,
Scale = 1.5f, Scale = 1.5f,
}; };
@ -47,12 +47,12 @@ namespace osu.Game.Rulesets.Catch.Tests
}; };
} }
private Drawable createDrawableDroplet() private Drawable createDrawableDroplet(bool hyperdash = false)
{ {
var droplet = new Droplet var droplet = new TestCatchDroplet
{ {
StartTime = Clock.CurrentTime,
Scale = 1.5f, Scale = 1.5f,
HyperDashTarget = hyperdash ? new Banana() : null
}; };
return new DrawableDroplet(droplet) return new DrawableDroplet(droplet)
@ -95,5 +95,21 @@ namespace osu.Game.Rulesets.Catch.Tests
public override FruitVisualRepresentation VisualRepresentation { get; } public override FruitVisualRepresentation VisualRepresentation { get; }
} }
public class TestCatchDroplet : Droplet
{
public TestCatchDroplet()
{
StartTime = 1000000000000;
}
}
public class TestCatchTinyDroplet : TinyDroplet
{
public TestCatchTinyDroplet()
{
StartTime = 1000000000000;
}
}
} }
} }

View File

@ -6,6 +6,7 @@ using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Testing; using osu.Framework.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
@ -31,6 +32,8 @@ namespace osu.Game.Rulesets.Catch.Tests
AddUntilStep("wait for right hyperdash", () => getCatcher().Scale.X > 0 && getCatcher().HyperDashing); AddUntilStep("wait for right hyperdash", () => getCatcher().Scale.X > 0 && getCatcher().HyperDashing);
AddUntilStep("wait for left hyperdash", () => getCatcher().Scale.X < 0 && getCatcher().HyperDashing); AddUntilStep("wait for left hyperdash", () => getCatcher().Scale.X < 0 && getCatcher().HyperDashing);
} }
AddUntilStep("wait for right hyperdash", () => getCatcher().Scale.X > 0 && getCatcher().HyperDashing);
} }
private Catcher getCatcher() => Player.ChildrenOfType<CatcherArea>().First().MovableCatcher; private Catcher getCatcher() => Player.ChildrenOfType<CatcherArea>().First().MovableCatcher;
@ -46,6 +49,8 @@ namespace osu.Game.Rulesets.Catch.Tests
} }
}; };
beatmap.ControlPointInfo.Add(0, new TimingControlPoint());
// Should produce a hyper-dash (edge case test) // Should produce a hyper-dash (edge case test)
beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 56, NewCombo = true }); beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 56, NewCombo = true });
beatmap.HitObjects.Add(new Fruit { StartTime = 2008, X = 308, NewCombo = true }); beatmap.HitObjects.Add(new Fruit { StartTime = 2008, X = 308, NewCombo = true });
@ -63,6 +68,20 @@ namespace osu.Game.Rulesets.Catch.Tests
createObjects(() => new Fruit { X = right_x }); createObjects(() => new Fruit { X = right_x });
createObjects(() => new TestJuiceStream(left_x), 1); createObjects(() => new TestJuiceStream(left_x), 1);
beatmap.ControlPointInfo.Add(startTime, new TimingControlPoint
{
BeatLength = 50
});
createObjects(() => new TestJuiceStream(left_x)
{
Path = new SliderPath(new[]
{
new PathControlPoint(Vector2.Zero),
new PathControlPoint(new Vector2(512, 0))
})
}, 1);
return beatmap; return beatmap;
void createObjects(Func<CatchHitObject> createObject, int count = 3) void createObjects(Func<CatchHitObject> createObject, int count = 3)

View File

@ -27,6 +27,11 @@ namespace osu.Game.Rulesets.Catch.Objects
set => x = value; set => x = value;
} }
/// <summary>
/// Whether this object can be placed on the catcher's plate.
/// </summary>
public virtual bool CanBePlated => false;
/// <summary> /// <summary>
/// A random offset applied to <see cref="X"/>, set by the <see cref="CatchBeatmapProcessor"/>. /// A random offset applied to <see cref="X"/>, set by the <see cref="CatchBeatmapProcessor"/>.
/// </summary> /// </summary>
@ -100,6 +105,14 @@ namespace osu.Game.Rulesets.Catch.Objects
protected override HitWindows CreateHitWindows() => HitWindows.Empty; protected override HitWindows CreateHitWindows() => HitWindows.Empty;
} }
/// <summary>
/// Represents a single object that can be caught by the catcher.
/// </summary>
public abstract class PalpableCatchHitObject : CatchHitObject
{
public override bool CanBePlated => true;
}
public enum FruitVisualRepresentation public enum FruitVisualRepresentation
{ {
Pear, Pear,

View File

@ -15,14 +15,12 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Catch.Objects.Drawables namespace osu.Game.Rulesets.Catch.Objects.Drawables
{ {
public abstract class PalpableCatchHitObject<TObject> : DrawableCatchHitObject<TObject> public abstract class PalpableDrawableCatchHitObject<TObject> : DrawableCatchHitObject<TObject>
where TObject : CatchHitObject where TObject : PalpableCatchHitObject
{ {
public override bool CanBePlated => true;
protected Container ScaleContainer { get; private set; } protected Container ScaleContainer { get; private set; }
protected PalpableCatchHitObject(TObject hitObject) protected PalpableDrawableCatchHitObject(TObject hitObject)
: base(hitObject) : base(hitObject)
{ {
Origin = Anchor.Centre; Origin = Anchor.Centre;
@ -65,9 +63,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
public abstract class DrawableCatchHitObject : DrawableHitObject<CatchHitObject> public abstract class DrawableCatchHitObject : DrawableHitObject<CatchHitObject>
{ {
public virtual bool CanBePlated => false; public virtual bool StaysOnPlate => HitObject.CanBePlated;
public virtual bool StaysOnPlate => CanBePlated;
public float DisplayRadius => DrawSize.X / 2 * Scale.X * HitObject.Scale; public float DisplayRadius => DrawSize.X / 2 * Scale.X * HitObject.Scale;

View File

@ -4,12 +4,11 @@
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces;
using osu.Game.Skinning; using osu.Game.Skinning;
namespace osu.Game.Rulesets.Catch.Objects.Drawables namespace osu.Game.Rulesets.Catch.Objects.Drawables
{ {
public class DrawableDroplet : PalpableCatchHitObject<Droplet> public class DrawableDroplet : PalpableDrawableCatchHitObject<Droplet>
{ {
public override bool StaysOnPlate => false; public override bool StaysOnPlate => false;
@ -21,11 +20,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
ScaleContainer.Child = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.Droplet), _ => new Pulp ScaleContainer.Child = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.Droplet), _ => new DropletPiece());
{
Size = Size / 4,
AccentColour = { BindTarget = AccentColour }
});
} }
protected override void UpdateInitialTransforms() protected override void UpdateInitialTransforms()

View File

@ -8,7 +8,7 @@ using osu.Game.Skinning;
namespace osu.Game.Rulesets.Catch.Objects.Drawables namespace osu.Game.Rulesets.Catch.Objects.Drawables
{ {
public class DrawableFruit : PalpableCatchHitObject<Fruit> public class DrawableFruit : PalpableDrawableCatchHitObject<Fruit>
{ {
public DrawableFruit(Fruit h) public DrawableFruit(Fruit h)
: base(h) : base(h)

View File

@ -0,0 +1,69 @@
// 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 osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Objects.Drawables;
using osuTK;
namespace osu.Game.Rulesets.Catch.Objects.Drawables
{
public class DropletPiece : CompositeDrawable
{
public DropletPiece()
{
Size = new Vector2(CatchHitObject.OBJECT_RADIUS / 2);
}
[BackgroundDependencyLoader]
private void load(DrawableHitObject drawableObject)
{
DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject;
var hitObject = drawableCatchObject.HitObject;
InternalChild = new Pulp
{
RelativeSizeAxes = Axes.Both,
AccentColour = { BindTarget = drawableObject.AccentColour }
};
if (hitObject.HyperDash)
{
AddInternal(new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Size = new Vector2(2f),
Depth = 1,
Children = new Drawable[]
{
new Circle
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
BorderColour = Catcher.DEFAULT_HYPER_DASH_COLOUR,
BorderThickness = 6,
Children = new Drawable[]
{
new Box
{
AlwaysPresent = true,
Alpha = 0.3f,
Blending = BlendingParameters.Additive,
RelativeSizeAxes = Axes.Both,
Colour = Catcher.DEFAULT_HYPER_DASH_COLOUR,
}
}
}
}
});
}
}
}
}

View File

@ -3,7 +3,6 @@
using System; using System;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
@ -21,11 +20,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
public const float RADIUS_ADJUST = 1.1f; public const float RADIUS_ADJUST = 1.1f;
private Circle border; private Circle border;
private CatchHitObject hitObject; private CatchHitObject hitObject;
private readonly IBindable<Color4> accentColour = new Bindable<Color4>();
public FruitPiece() public FruitPiece()
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
@ -37,8 +33,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject; DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject;
hitObject = drawableCatchObject.HitObject; hitObject = drawableCatchObject.HitObject;
accentColour.BindTo(drawableCatchObject.AccentColour);
AddRangeInternal(new[] AddRangeInternal(new[]
{ {
getFruitFor(drawableCatchObject.HitObject.VisualRepresentation), getFruitFor(drawableCatchObject.HitObject.VisualRepresentation),

View File

@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables.Pieces
EdgeEffect = new EdgeEffectParameters EdgeEffect = new EdgeEffectParameters
{ {
Type = EdgeEffectType.Glow, Type = EdgeEffectType.Glow,
Radius = Size.X / 2, Radius = DrawWidth / 2,
Colour = colour.NewValue.Darken(0.2f).Opacity(0.75f) Colour = colour.NewValue.Darken(0.2f).Opacity(0.75f)
}; };
} }

View File

@ -6,7 +6,7 @@ using osu.Game.Rulesets.Judgements;
namespace osu.Game.Rulesets.Catch.Objects namespace osu.Game.Rulesets.Catch.Objects
{ {
public class Droplet : CatchHitObject public class Droplet : PalpableCatchHitObject
{ {
public override Judgement CreateJudgement() => new CatchDropletJudgement(); public override Judgement CreateJudgement() => new CatchDropletJudgement();
} }

View File

@ -6,7 +6,7 @@ using osu.Game.Rulesets.Judgements;
namespace osu.Game.Rulesets.Catch.Objects namespace osu.Game.Rulesets.Catch.Objects
{ {
public class Fruit : CatchHitObject public class Fruit : PalpableCatchHitObject
{ {
public override Judgement CreateJudgement() => new CatchJudgement(); public override Judgement CreateJudgement() => new CatchJudgement();
} }

View File

@ -216,6 +216,9 @@ namespace osu.Game.Rulesets.Catch.UI
/// <returns>Whether the catch is possible.</returns> /// <returns>Whether the catch is possible.</returns>
public bool AttemptCatch(CatchHitObject fruit) public bool AttemptCatch(CatchHitObject fruit)
{ {
if (!fruit.CanBePlated)
return false;
var halfCatchWidth = catchWidth * 0.5f; var halfCatchWidth = catchWidth * 0.5f;
// this stuff wil disappear once we move fruit to non-relative coordinate space in the future. // this stuff wil disappear once we move fruit to non-relative coordinate space in the future.
@ -226,9 +229,8 @@ namespace osu.Game.Rulesets.Catch.UI
catchObjectPosition >= catcherPosition - halfCatchWidth && catchObjectPosition >= catcherPosition - halfCatchWidth &&
catchObjectPosition <= catcherPosition + halfCatchWidth; catchObjectPosition <= catcherPosition + halfCatchWidth;
// only update hyperdash state if we are catching a fruit. // only update hyperdash state if we are not catching a tiny droplet.
// exceptions are Droplets and JuiceStreams. if (fruit is TinyDroplet) return validCatch;
if (!(fruit is Fruit)) return validCatch;
if (validCatch && fruit.HyperDash) if (validCatch && fruit.HyperDash)
{ {

View File

@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.UI
lastPlateableFruit.OnLoadComplete += _ => action(); lastPlateableFruit.OnLoadComplete += _ => action();
} }
if (result.IsHit && fruit.CanBePlated) if (result.IsHit && fruit.HitObject.CanBePlated)
{ {
// create a new (cloned) fruit to stay on the plate. the original is faded out immediately. // create a new (cloned) fruit to stay on the plate. the original is faded out immediately.
var caughtFruit = (DrawableCatchHitObject)CreateDrawableRepresentation?.Invoke(fruit.HitObject); var caughtFruit = (DrawableCatchHitObject)CreateDrawableRepresentation?.Invoke(fruit.HitObject);

View File

@ -60,12 +60,7 @@ namespace osu.Game.Rulesets.Mania.Mods
Column = column.Key, Column = column.Key,
StartTime = locations[i].startTime, StartTime = locations[i].startTime,
Duration = duration, Duration = duration,
Samples = locations[i].samples, NodeSamples = new List<IList<HitSampleInfo>> { locations[i].samples, Array.Empty<HitSampleInfo>() }
NodeSamples = new List<IList<HitSampleInfo>>
{
locations[i].samples,
locations[i + 1].samples
}
}); });
} }

View File

@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Skinning; using osu.Game.Skinning;
using osuTK; using osuTK;
@ -20,9 +21,12 @@ namespace osu.Game.Rulesets.Mania.Skinning
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>(); private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
private readonly bool isLastColumn; private readonly bool isLastColumn;
private Container borderLineContainer;
private Container lightContainer; private Container lightContainer;
private Sprite light; private Sprite light;
private float hitPosition;
public LegacyColumnBackground(bool isLastColumn) public LegacyColumnBackground(bool isLastColumn)
{ {
this.isLastColumn = isLastColumn; this.isLastColumn = isLastColumn;
@ -44,6 +48,9 @@ namespace osu.Game.Rulesets.Mania.Skinning
bool hasRightLine = rightLineWidth > 0 && skin.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value >= 2.4m bool hasRightLine = rightLineWidth > 0 && skin.GetConfig<LegacySkinConfiguration.LegacySetting, decimal>(LegacySkinConfiguration.LegacySetting.Version)?.Value >= 2.4m
|| isLastColumn; || isLastColumn;
hitPosition = GetColumnSkinConfig<float>(skin, LegacyManiaSkinConfigurationLookups.HitPosition)?.Value
?? Stage.HIT_TARGET_POSITION;
float lightPosition = GetColumnSkinConfig<float>(skin, LegacyManiaSkinConfigurationLookups.LightPosition)?.Value float lightPosition = GetColumnSkinConfig<float>(skin, LegacyManiaSkinConfigurationLookups.LightPosition)?.Value
?? 0; ?? 0;
@ -63,23 +70,30 @@ namespace osu.Game.Rulesets.Mania.Skinning
RelativeSizeAxes = Axes.Both, RelativeSizeAxes = Axes.Both,
Colour = backgroundColour Colour = backgroundColour
}, },
new Box borderLineContainer = new Container
{ {
RelativeSizeAxes = Axes.Y, RelativeSizeAxes = Axes.Both,
Width = leftLineWidth, Children = new[]
Scale = new Vector2(0.740f, 1), {
Colour = lineColour, new Box
Alpha = hasLeftLine ? 1 : 0 {
}, RelativeSizeAxes = Axes.Y,
new Box Width = leftLineWidth,
{ Scale = new Vector2(0.740f, 1),
Anchor = Anchor.TopRight, Colour = lineColour,
Origin = Anchor.TopRight, Alpha = hasLeftLine ? 1 : 0
RelativeSizeAxes = Axes.Y, },
Width = rightLineWidth, new Box
Scale = new Vector2(0.740f, 1), {
Colour = lineColour, Anchor = Anchor.TopRight,
Alpha = hasRightLine ? 1 : 0 Origin = Anchor.TopRight,
RelativeSizeAxes = Axes.Y,
Width = rightLineWidth,
Scale = new Vector2(0.740f, 1),
Colour = lineColour,
Alpha = hasRightLine ? 1 : 0
}
}
}, },
lightContainer = new Container lightContainer = new Container
{ {
@ -109,11 +123,15 @@ namespace osu.Game.Rulesets.Mania.Skinning
{ {
lightContainer.Anchor = Anchor.TopCentre; lightContainer.Anchor = Anchor.TopCentre;
lightContainer.Scale = new Vector2(1, -1); lightContainer.Scale = new Vector2(1, -1);
borderLineContainer.Padding = new MarginPadding { Top = hitPosition };
} }
else else
{ {
lightContainer.Anchor = Anchor.BottomCentre; lightContainer.Anchor = Anchor.BottomCentre;
lightContainer.Scale = Vector2.One; lightContainer.Scale = Vector2.One;
borderLineContainer.Padding = new MarginPadding { Bottom = hitPosition };
} }
} }

View File

@ -2,6 +2,8 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Game.Overlays;
namespace osu.Game.Tests.Visual.Multiplayer namespace osu.Game.Tests.Visual.Multiplayer
{ {
@ -10,11 +12,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
{ {
protected override bool UseOnlineAPI => true; protected override bool UseOnlineAPI => true;
[Cached]
private MusicController musicController { get; set; } = new MusicController();
public TestSceneMultiScreen() public TestSceneMultiScreen()
{ {
Screens.Multi.Multiplayer multi = new Screens.Multi.Multiplayer(); Screens.Multi.Multiplayer multi = new Screens.Multi.Multiplayer();
AddStep(@"show", () => LoadScreen(multi)); AddStep("show", () => LoadScreen(multi));
AddUntilStep("wait for loaded", () => multi.IsLoaded);
} }
} }
} }

View File

@ -68,22 +68,22 @@ namespace osu.Game.Tests.Visual.Settings
[Test] [Test]
public void TestClearButtonOnBindings() public void TestClearButtonOnBindings()
{ {
KeyBindingRow backBindingRow = null; KeyBindingRow multiBindingRow = null;
AddStep("click back binding row", () => AddStep("click first row with two bindings", () =>
{ {
backBindingRow = panel.ChildrenOfType<KeyBindingRow>().ElementAt(10); multiBindingRow = panel.ChildrenOfType<KeyBindingRow>().First(row => row.Defaults.Count() > 1);
InputManager.MoveMouseTo(backBindingRow); InputManager.MoveMouseTo(multiBindingRow);
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
clickClearButton(); clickClearButton();
AddAssert("first binding cleared", () => string.IsNullOrEmpty(backBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().First().Text.Text)); AddAssert("first binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().First().Text.Text));
AddStep("click second binding", () => AddStep("click second binding", () =>
{ {
var target = backBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(1); var target = multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(1);
InputManager.MoveMouseTo(target); InputManager.MoveMouseTo(target);
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
@ -91,13 +91,13 @@ namespace osu.Game.Tests.Visual.Settings
clickClearButton(); clickClearButton();
AddAssert("second binding cleared", () => string.IsNullOrEmpty(backBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(1).Text.Text)); AddAssert("second binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(1).Text.Text));
void clickClearButton() void clickClearButton()
{ {
AddStep("click clear button", () => AddStep("click clear button", () =>
{ {
var clearButton = backBindingRow.ChildrenOfType<KeyBindingRow.ClearButton>().Single(); var clearButton = multiBindingRow.ChildrenOfType<KeyBindingRow.ClearButton>().Single();
InputManager.MoveMouseTo(clearButton); InputManager.MoveMouseTo(clearButton);
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
@ -108,20 +108,20 @@ namespace osu.Game.Tests.Visual.Settings
[Test] [Test]
public void TestClickRowSelectsFirstBinding() public void TestClickRowSelectsFirstBinding()
{ {
KeyBindingRow backBindingRow = null; KeyBindingRow multiBindingRow = null;
AddStep("click back binding row", () => AddStep("click first row with two bindings", () =>
{ {
backBindingRow = panel.ChildrenOfType<KeyBindingRow>().ElementAt(10); multiBindingRow = panel.ChildrenOfType<KeyBindingRow>().First(row => row.Defaults.Count() > 1);
InputManager.MoveMouseTo(backBindingRow); InputManager.MoveMouseTo(multiBindingRow);
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
AddAssert("first binding selected", () => backBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().First().IsBinding); AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().First().IsBinding);
AddStep("click second binding", () => AddStep("click second binding", () =>
{ {
var target = backBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(1); var target = multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(1);
InputManager.MoveMouseTo(target); InputManager.MoveMouseTo(target);
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
@ -129,12 +129,12 @@ namespace osu.Game.Tests.Visual.Settings
AddStep("click back binding row", () => AddStep("click back binding row", () =>
{ {
backBindingRow = panel.ChildrenOfType<KeyBindingRow>().ElementAt(10); multiBindingRow = panel.ChildrenOfType<KeyBindingRow>().ElementAt(10);
InputManager.MoveMouseTo(backBindingRow); InputManager.MoveMouseTo(multiBindingRow);
InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left);
}); });
AddAssert("first binding selected", () => backBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().First().IsBinding); AddAssert("first binding selected", () => multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().First().IsBinding);
} }
} }
} }

View File

@ -76,6 +76,8 @@ namespace osu.Game.Storyboards.Drawables
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)
{ {
Channel?.Stop(); Channel?.Stop();
Channel = null;
base.Dispose(isDisposing); base.Dispose(isDisposing);
} }
} }