mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 11:37:28 +08:00
Merge branch 'master' into localise-beatmap-set-overlay
This commit is contained in:
commit
9b1720bd6c
@ -51,8 +51,8 @@
|
|||||||
<Reference Include="Java.Interop" />
|
<Reference Include="Java.Interop" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.813.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.820.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.813.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.819.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Transitive Dependencies">
|
<ItemGroup Label="Transitive Dependencies">
|
||||||
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
||||||
|
@ -5,23 +5,23 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game;
|
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
namespace osu.Desktop.Windows
|
namespace osu.Desktop.Windows
|
||||||
{
|
{
|
||||||
public class GameplayWinKeyBlocker : Component
|
public class GameplayWinKeyBlocker : Component
|
||||||
{
|
{
|
||||||
private Bindable<bool> disableWinKey;
|
private Bindable<bool> disableWinKey;
|
||||||
private Bindable<bool> localUserPlaying;
|
private IBindable<bool> localUserPlaying;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private GameHost host { get; set; }
|
private GameHost host { get; set; }
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGame game, OsuConfigManager config)
|
private void load(ILocalUserPlayInfo localUserInfo, OsuConfigManager config)
|
||||||
{
|
{
|
||||||
localUserPlaying = game.LocalUserPlaying.GetBoundCopy();
|
localUserPlaying = localUserInfo.IsPlaying.GetBoundCopy();
|
||||||
localUserPlaying.BindValueChanged(_ => updateBlocking());
|
localUserPlaying.BindValueChanged(_ => updateBlocking());
|
||||||
|
|
||||||
disableWinKey = config.GetBindable<bool>(OsuSetting.GameplayDisableWinKey);
|
disableWinKey = config.GetBindable<bool>(OsuSetting.GameplayDisableWinKey);
|
||||||
|
34
osu.Game.Benchmarks/BenchmarkMod.cs
Normal file
34
osu.Game.Benchmarks/BenchmarkMod.cs
Normal file
@ -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 BenchmarkDotNet.Attributes;
|
||||||
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Benchmarks
|
||||||
|
{
|
||||||
|
public class BenchmarkMod : BenchmarkTest
|
||||||
|
{
|
||||||
|
private OsuModDoubleTime mod;
|
||||||
|
|
||||||
|
[Params(1, 10, 100)]
|
||||||
|
public int Times { get; set; }
|
||||||
|
|
||||||
|
[GlobalSetup]
|
||||||
|
public void GlobalSetup()
|
||||||
|
{
|
||||||
|
mod = new OsuModDoubleTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public int ModHashCode()
|
||||||
|
{
|
||||||
|
var hashCode = new HashCode();
|
||||||
|
|
||||||
|
for (int i = 0; i < Times; i++)
|
||||||
|
hashCode.Add(mod);
|
||||||
|
|
||||||
|
return hashCode.ToHashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ using osu.Game.Rulesets.Mods;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Difficulty.Skills
|
namespace osu.Game.Rulesets.Catch.Difficulty.Skills
|
||||||
{
|
{
|
||||||
public class Movement : StrainSkill
|
public class Movement : StrainDecaySkill
|
||||||
{
|
{
|
||||||
private const float absolute_player_positioning_error = 16f;
|
private const float absolute_player_positioning_error = 16f;
|
||||||
private const float normalized_hitobject_radius = 41.0f;
|
private const float normalized_hitobject_radius = 41.0f;
|
||||||
|
@ -10,7 +10,7 @@ using osu.Game.Rulesets.Mods;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Difficulty.Skills
|
namespace osu.Game.Rulesets.Mania.Difficulty.Skills
|
||||||
{
|
{
|
||||||
public class Strain : StrainSkill
|
public class Strain : StrainDecaySkill
|
||||||
{
|
{
|
||||||
private const double individual_decay_base = 0.125;
|
private const double individual_decay_base = 0.125;
|
||||||
private const double overall_decay_base = 0.30;
|
private const double overall_decay_base = 0.30;
|
||||||
@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty.Skills
|
|||||||
return individualStrain + overallStrain - CurrentStrain;
|
return individualStrain + overallStrain - CurrentStrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override double GetPeakStrain(double offset)
|
protected override double CalculateInitialStrain(double offset)
|
||||||
=> applyDecay(individualStrain, offset - Previous[0].StartTime, individual_decay_base)
|
=> applyDecay(individualStrain, offset - Previous[0].StartTime, individual_decay_base)
|
||||||
+ applyDecay(overallStrain, offset - Previous[0].StartTime, overall_decay_base);
|
+ applyDecay(overallStrain, offset - Previous[0].StartTime, overall_decay_base);
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ using osu.Framework.Utils;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
||||||
{
|
{
|
||||||
public abstract class OsuStrainSkill : StrainSkill
|
public abstract class OsuStrainSkill : StrainDecaySkill
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The number of sections with the highest strains, which the peak strain reductions will apply to.
|
/// The number of sections with the highest strains, which the peak strain reductions will apply to.
|
||||||
|
@ -64,11 +64,14 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
|
|
||||||
if (hitObject is DrawableHitCircle circle)
|
if (hitObject is DrawableHitCircle circle)
|
||||||
{
|
{
|
||||||
circle.ApproachCircle
|
using (circle.BeginAbsoluteSequence(circle.HitStateUpdateTime))
|
||||||
.FadeOutFromOne(EDITOR_HIT_OBJECT_FADE_OUT_EXTENSION * 4)
|
{
|
||||||
.Expire();
|
circle.ApproachCircle
|
||||||
|
.FadeOutFromOne(EDITOR_HIT_OBJECT_FADE_OUT_EXTENSION * 4)
|
||||||
|
.Expire();
|
||||||
|
|
||||||
circle.ApproachCircle.ScaleTo(1.1f, 300, Easing.OutQuint);
|
circle.ApproachCircle.ScaleTo(1.1f, 300, Easing.OutQuint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hitObject is IHasMainCirclePiece mainPieceContainer)
|
if (hitObject is IHasMainCirclePiece mainPieceContainer)
|
||||||
|
@ -62,6 +62,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
protected override bool InterpolateMovements => !disjointTrail;
|
protected override bool InterpolateMovements => !disjointTrail;
|
||||||
|
|
||||||
protected override float IntervalMultiplier => 1 / Math.Max(cursorSize.Value, 1);
|
protected override float IntervalMultiplier => 1 / Math.Max(cursorSize.Value, 1);
|
||||||
|
protected override bool AvoidDrawingNearCursor => !disjointTrail;
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
|
@ -138,6 +138,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
protected virtual bool InterpolateMovements => true;
|
protected virtual bool InterpolateMovements => true;
|
||||||
|
|
||||||
protected virtual float IntervalMultiplier => 1.0f;
|
protected virtual float IntervalMultiplier => 1.0f;
|
||||||
|
protected virtual bool AvoidDrawingNearCursor => false;
|
||||||
|
|
||||||
private Vector2? lastPosition;
|
private Vector2? lastPosition;
|
||||||
private readonly InputResampler resampler = new InputResampler();
|
private readonly InputResampler resampler = new InputResampler();
|
||||||
@ -171,8 +172,9 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
Vector2 direction = diff / distance;
|
Vector2 direction = diff / distance;
|
||||||
|
|
||||||
float interval = partSize.X / 2.5f * IntervalMultiplier;
|
float interval = partSize.X / 2.5f * IntervalMultiplier;
|
||||||
|
float stopAt = distance - (AvoidDrawingNearCursor ? interval : 0);
|
||||||
|
|
||||||
for (float d = interval; d < distance; d += interval)
|
for (float d = interval; d < stopAt; d += interval)
|
||||||
{
|
{
|
||||||
lastPosition = pos1 + direction * d;
|
lastPosition = pos1 + direction * d;
|
||||||
addPart(lastPosition.Value);
|
addPart(lastPosition.Value);
|
||||||
|
@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Calculates the colour coefficient of taiko difficulty.
|
/// Calculates the colour coefficient of taiko difficulty.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Colour : StrainSkill
|
public class Colour : StrainDecaySkill
|
||||||
{
|
{
|
||||||
protected override double SkillMultiplier => 1;
|
protected override double SkillMultiplier => 1;
|
||||||
protected override double StrainDecayBase => 0.4;
|
protected override double StrainDecayBase => 0.4;
|
||||||
|
@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Calculates the rhythm coefficient of taiko difficulty.
|
/// Calculates the rhythm coefficient of taiko difficulty.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Rhythm : StrainSkill
|
public class Rhythm : StrainDecaySkill
|
||||||
{
|
{
|
||||||
protected override double SkillMultiplier => 10;
|
protected override double SkillMultiplier => 10;
|
||||||
protected override double StrainDecayBase => 0;
|
protected override double StrainDecayBase => 0;
|
||||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
|
|||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// The reference play style chosen uses two hands, with full alternating (the hand changes after every hit).
|
/// The reference play style chosen uses two hands, with full alternating (the hand changes after every hit).
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class Stamina : StrainSkill
|
public class Stamina : StrainDecaySkill
|
||||||
{
|
{
|
||||||
protected override double SkillMultiplier => 1;
|
protected override double SkillMultiplier => 1;
|
||||||
protected override double StrainDecayBase => 0.4;
|
protected override double StrainDecayBase => 0.4;
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
// 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.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Beatmaps
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class BeatmapDifficultyCacheTest
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void TestKeyEqualsWithDifferentModInstances()
|
|
||||||
{
|
|
||||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
|
||||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
|
||||||
|
|
||||||
Assert.That(key1, Is.EqualTo(key2));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestKeyEqualsWithDifferentModOrder()
|
|
||||||
{
|
|
||||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
|
||||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHidden(), new OsuModHardRock() });
|
|
||||||
|
|
||||||
Assert.That(key1, Is.EqualTo(key2));
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase(1.3, DifficultyRating.Easy)]
|
|
||||||
[TestCase(1.993, DifficultyRating.Easy)]
|
|
||||||
[TestCase(1.998, DifficultyRating.Normal)]
|
|
||||||
[TestCase(2.4, DifficultyRating.Normal)]
|
|
||||||
[TestCase(2.693, DifficultyRating.Normal)]
|
|
||||||
[TestCase(2.698, DifficultyRating.Hard)]
|
|
||||||
[TestCase(3.5, DifficultyRating.Hard)]
|
|
||||||
[TestCase(3.993, DifficultyRating.Hard)]
|
|
||||||
[TestCase(3.997, DifficultyRating.Insane)]
|
|
||||||
[TestCase(5.0, DifficultyRating.Insane)]
|
|
||||||
[TestCase(5.292, DifficultyRating.Insane)]
|
|
||||||
[TestCase(5.297, DifficultyRating.Expert)]
|
|
||||||
[TestCase(6.2, DifficultyRating.Expert)]
|
|
||||||
[TestCase(6.493, DifficultyRating.Expert)]
|
|
||||||
[TestCase(6.498, DifficultyRating.ExpertPlus)]
|
|
||||||
[TestCase(8.3, DifficultyRating.ExpertPlus)]
|
|
||||||
public void TestDifficultyRatingMapping(double starRating, DifficultyRating expectedBracket)
|
|
||||||
{
|
|
||||||
var actualBracket = BeatmapDifficultyCache.GetDifficultyRating(starRating);
|
|
||||||
|
|
||||||
Assert.AreEqual(expectedBracket, actualBracket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
146
osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs
Normal file
146
osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
// 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.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
|
using osu.Game.Tests.Beatmaps.IO;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Beatmaps
|
||||||
|
{
|
||||||
|
[HeadlessTest]
|
||||||
|
public class TestSceneBeatmapDifficultyCache : OsuTestScene
|
||||||
|
{
|
||||||
|
public const double BASE_STARS = 5.55;
|
||||||
|
|
||||||
|
private BeatmapSetInfo importedSet;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private BeatmapManager beatmaps { get; set; }
|
||||||
|
|
||||||
|
private TestBeatmapDifficultyCache difficultyCache;
|
||||||
|
|
||||||
|
private IBindable<StarDifficulty?> starDifficultyBindable;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuGameBase osu)
|
||||||
|
{
|
||||||
|
importedSet = ImportBeatmapTest.LoadQuickOszIntoOsu(osu).Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public void SetUpSteps()
|
||||||
|
{
|
||||||
|
AddStep("setup difficulty cache", () =>
|
||||||
|
{
|
||||||
|
SelectedMods.Value = Array.Empty<Mod>();
|
||||||
|
|
||||||
|
Child = difficultyCache = new TestBeatmapDifficultyCache();
|
||||||
|
|
||||||
|
starDifficultyBindable = difficultyCache.GetBindableDifficulty(importedSet.Beatmaps.First());
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep($"star difficulty -> {BASE_STARS}", () => starDifficultyBindable.Value?.Stars == BASE_STARS);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestStarDifficultyChangesOnModSettings()
|
||||||
|
{
|
||||||
|
OsuModDoubleTime dt = null;
|
||||||
|
|
||||||
|
AddStep("change selected mod to DT", () => SelectedMods.Value = new[] { dt = new OsuModDoubleTime { SpeedChange = { Value = 1.5 } } });
|
||||||
|
AddUntilStep($"star difficulty -> {BASE_STARS + 1.5}", () => starDifficultyBindable.Value?.Stars == BASE_STARS + 1.5);
|
||||||
|
|
||||||
|
AddStep("change DT speed to 1.25", () => dt.SpeedChange.Value = 1.25);
|
||||||
|
AddUntilStep($"star difficulty -> {BASE_STARS + 1.25}", () => starDifficultyBindable.Value?.Stars == BASE_STARS + 1.25);
|
||||||
|
|
||||||
|
AddStep("change selected mod to NC", () => SelectedMods.Value = new[] { new OsuModNightcore { SpeedChange = { Value = 1.75 } } });
|
||||||
|
AddUntilStep($"star difficulty -> {BASE_STARS + 1.75}", () => starDifficultyBindable.Value?.Stars == BASE_STARS + 1.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestKeyEqualsWithDifferentModInstances()
|
||||||
|
{
|
||||||
|
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
||||||
|
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
||||||
|
|
||||||
|
Assert.That(key1, Is.EqualTo(key2));
|
||||||
|
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestKeyEqualsWithDifferentModOrder()
|
||||||
|
{
|
||||||
|
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() });
|
||||||
|
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHidden(), new OsuModHardRock() });
|
||||||
|
|
||||||
|
Assert.That(key1, Is.EqualTo(key2));
|
||||||
|
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestKeyDoesntEqualWithDifferentModSettings()
|
||||||
|
{
|
||||||
|
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.1 } } });
|
||||||
|
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.9 } } });
|
||||||
|
|
||||||
|
Assert.That(key1, Is.Not.EqualTo(key2));
|
||||||
|
Assert.That(key1.GetHashCode(), Is.Not.EqualTo(key2.GetHashCode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestKeyEqualWithMatchingModSettings()
|
||||||
|
{
|
||||||
|
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
||||||
|
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
||||||
|
|
||||||
|
Assert.That(key1, Is.EqualTo(key2));
|
||||||
|
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(1.3, DifficultyRating.Easy)]
|
||||||
|
[TestCase(1.993, DifficultyRating.Easy)]
|
||||||
|
[TestCase(1.998, DifficultyRating.Normal)]
|
||||||
|
[TestCase(2.4, DifficultyRating.Normal)]
|
||||||
|
[TestCase(2.693, DifficultyRating.Normal)]
|
||||||
|
[TestCase(2.698, DifficultyRating.Hard)]
|
||||||
|
[TestCase(3.5, DifficultyRating.Hard)]
|
||||||
|
[TestCase(3.993, DifficultyRating.Hard)]
|
||||||
|
[TestCase(3.997, DifficultyRating.Insane)]
|
||||||
|
[TestCase(5.0, DifficultyRating.Insane)]
|
||||||
|
[TestCase(5.292, DifficultyRating.Insane)]
|
||||||
|
[TestCase(5.297, DifficultyRating.Expert)]
|
||||||
|
[TestCase(6.2, DifficultyRating.Expert)]
|
||||||
|
[TestCase(6.493, DifficultyRating.Expert)]
|
||||||
|
[TestCase(6.498, DifficultyRating.ExpertPlus)]
|
||||||
|
[TestCase(8.3, DifficultyRating.ExpertPlus)]
|
||||||
|
public void TestDifficultyRatingMapping(double starRating, DifficultyRating expectedBracket)
|
||||||
|
{
|
||||||
|
var actualBracket = BeatmapDifficultyCache.GetDifficultyRating(starRating);
|
||||||
|
|
||||||
|
Assert.AreEqual(expectedBracket, actualBracket);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestBeatmapDifficultyCache : BeatmapDifficultyCache
|
||||||
|
{
|
||||||
|
protected override Task<StarDifficulty> ComputeValueAsync(DifficultyCacheLookup lookup, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
var rateAdjust = lookup.OrderedMods.OfType<ModRateAdjust>().SingleOrDefault();
|
||||||
|
if (rateAdjust != null)
|
||||||
|
return Task.FromResult(new StarDifficulty(BASE_STARS + rateAdjust.SpeedChange.Value, 0));
|
||||||
|
|
||||||
|
return Task.FromResult(new StarDifficulty(BASE_STARS, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Tests.Resources;
|
using osu.Game.Tests.Resources;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Collections.IO
|
namespace osu.Game.Tests.Collections.IO
|
||||||
@ -127,7 +128,7 @@ namespace osu.Game.Tests.Collections.IO
|
|||||||
[Test]
|
[Test]
|
||||||
public async Task TestSaveAndReload()
|
public async Task TestSaveAndReload()
|
||||||
{
|
{
|
||||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
|
using (HeadlessGameHost host = new TestRunHeadlessGameHost("TestSaveAndReload", bypassCleanup: true))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -148,7 +149,7 @@ namespace osu.Game.Tests.Collections.IO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (HeadlessGameHost host = new HeadlessGameHost("TestSaveAndReload"))
|
using (HeadlessGameHost host = new TestRunHeadlessGameHost("TestSaveAndReload"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,7 @@ using osu.Framework.Input;
|
|||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Input;
|
using osu.Game.Input;
|
||||||
using osu.Game.Tests.Visual.Navigation;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Input
|
namespace osu.Game.Tests.Input
|
||||||
{
|
{
|
||||||
|
@ -6,10 +6,10 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
|
|
||||||
@ -278,7 +278,7 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
|
|
||||||
private static string getDefaultLocationFor(string testTypeName)
|
private static string getDefaultLocationFor(string testTypeName)
|
||||||
{
|
{
|
||||||
string path = Path.Combine(RuntimeInfo.StartupDirectory, "headless", testTypeName);
|
string path = Path.Combine(TestRunHeadlessGameHost.TemporaryTestDirectory, testTypeName);
|
||||||
|
|
||||||
if (Directory.Exists(path))
|
if (Directory.Exists(path))
|
||||||
Directory.Delete(path, true);
|
Directory.Delete(path, true);
|
||||||
@ -288,7 +288,7 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
|
|
||||||
private string prepareCustomPath(string suffix = "")
|
private string prepareCustomPath(string suffix = "")
|
||||||
{
|
{
|
||||||
string path = Path.Combine(RuntimeInfo.StartupDirectory, $"custom-path{suffix}");
|
string path = Path.Combine(TestRunHeadlessGameHost.TemporaryTestDirectory, $"custom-path{suffix}");
|
||||||
|
|
||||||
if (Directory.Exists(path))
|
if (Directory.Exists(path))
|
||||||
Directory.Delete(path, true);
|
Directory.Delete(path, true);
|
||||||
@ -308,6 +308,19 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
InitialStorage = new DesktopStorage(defaultStorageLocation, this);
|
InitialStorage = new DesktopStorage(defaultStorageLocation, this);
|
||||||
InitialStorage.DeleteDirectory(string.Empty);
|
InitialStorage.DeleteDirectory(string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// the storage may have changed from the initial location.
|
||||||
|
// this handles cleanup of the initial location.
|
||||||
|
InitialStorage.DeleteDirectory(string.Empty);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
// 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 MessagePack;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Game.Online;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Online
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestMultiplayerMessagePackSerialization
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestSerialiseRoom()
|
||||||
|
{
|
||||||
|
var room = new MultiplayerRoom(1)
|
||||||
|
{
|
||||||
|
MatchState = new TeamVersusRoomState()
|
||||||
|
};
|
||||||
|
|
||||||
|
var serialized = MessagePackSerializer.Serialize(room);
|
||||||
|
|
||||||
|
var deserialized = MessagePackSerializer.Deserialize<MultiplayerRoom>(serialized);
|
||||||
|
|
||||||
|
Assert.IsTrue(deserialized.MatchState is TeamVersusRoomState);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSerialiseUserStateExpected()
|
||||||
|
{
|
||||||
|
var state = new TeamVersusUserState();
|
||||||
|
|
||||||
|
var serialized = MessagePackSerializer.Serialize(typeof(MatchUserState), state);
|
||||||
|
var deserialized = MessagePackSerializer.Deserialize<MatchUserState>(serialized);
|
||||||
|
|
||||||
|
Assert.IsTrue(deserialized is TeamVersusUserState);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSerialiseUnionFailsWithSingalR()
|
||||||
|
{
|
||||||
|
var state = new TeamVersusUserState();
|
||||||
|
|
||||||
|
// SignalR serialises using the actual type, rather than a base specification.
|
||||||
|
var serialized = MessagePackSerializer.Serialize(typeof(TeamVersusUserState), state);
|
||||||
|
|
||||||
|
// works with explicit type specified.
|
||||||
|
MessagePackSerializer.Deserialize<TeamVersusUserState>(serialized);
|
||||||
|
|
||||||
|
// fails with base (union) type.
|
||||||
|
Assert.Throws<MessagePackSerializationException>(() => MessagePackSerializer.Deserialize<MatchUserState>(serialized));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSerialiseUnionSucceedsWithWorkaround()
|
||||||
|
{
|
||||||
|
var state = new TeamVersusUserState();
|
||||||
|
|
||||||
|
// SignalR serialises using the actual type, rather than a base specification.
|
||||||
|
var serialized = MessagePackSerializer.Serialize(typeof(TeamVersusUserState), state, SignalRUnionWorkaroundResolver.OPTIONS);
|
||||||
|
|
||||||
|
// works with explicit type specified.
|
||||||
|
MessagePackSerializer.Deserialize<TeamVersusUserState>(serialized);
|
||||||
|
|
||||||
|
// works with custom resolver.
|
||||||
|
var deserialized = MessagePackSerializer.Deserialize<MatchUserState>(serialized, SignalRUnionWorkaroundResolver.OPTIONS);
|
||||||
|
Assert.IsTrue(deserialized is TeamVersusUserState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -50,10 +50,10 @@ namespace osu.Game.Tests.Skins.IO
|
|||||||
var imported2 = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk("test skin", "skinner"), "skin2.osk"));
|
var imported2 = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk("test skin", "skinner"), "skin2.osk"));
|
||||||
|
|
||||||
Assert.That(imported2.ID, Is.Not.EqualTo(imported.ID));
|
Assert.That(imported2.ID, Is.Not.EqualTo(imported.ID));
|
||||||
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().Count, Is.EqualTo(1));
|
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins(true).Count, Is.EqualTo(1));
|
||||||
|
|
||||||
// the first should be overwritten by the second import.
|
// the first should be overwritten by the second import.
|
||||||
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().First().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID));
|
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins(true).First().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -76,10 +76,10 @@ namespace osu.Game.Tests.Skins.IO
|
|||||||
var imported2 = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk(string.Empty, string.Empty), "download.osk"));
|
var imported2 = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk(string.Empty, string.Empty), "download.osk"));
|
||||||
|
|
||||||
Assert.That(imported2.ID, Is.Not.EqualTo(imported.ID));
|
Assert.That(imported2.ID, Is.Not.EqualTo(imported.ID));
|
||||||
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().Count, Is.EqualTo(2));
|
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins(true).Count, Is.EqualTo(2));
|
||||||
|
|
||||||
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().First().Files.First().FileInfoID, Is.EqualTo(imported.Files.First().FileInfoID));
|
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins(true).First().Files.First().FileInfoID, Is.EqualTo(imported.Files.First().FileInfoID));
|
||||||
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().Last().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID));
|
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins(true).Last().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -101,10 +101,10 @@ namespace osu.Game.Tests.Skins.IO
|
|||||||
var imported2 = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk("test skin v2.1", "skinner"), "skin2.osk"));
|
var imported2 = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk("test skin v2.1", "skinner"), "skin2.osk"));
|
||||||
|
|
||||||
Assert.That(imported2.ID, Is.Not.EqualTo(imported.ID));
|
Assert.That(imported2.ID, Is.Not.EqualTo(imported.ID));
|
||||||
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().Count, Is.EqualTo(2));
|
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins(true).Count, Is.EqualTo(2));
|
||||||
|
|
||||||
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().First().Files.First().FileInfoID, Is.EqualTo(imported.Files.First().FileInfoID));
|
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins(true).First().Files.First().FileInfoID, Is.EqualTo(imported.Files.First().FileInfoID));
|
||||||
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins().Last().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID));
|
Assert.That(osu.Dependencies.Get<SkinManager>().GetAllUserSkins(true).Last().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -78,6 +78,24 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
AddAssert("clock looped to start", () => Clock.IsRunning && Clock.CurrentTime < 500);
|
AddAssert("clock looped to start", () => Clock.IsRunning && Clock.CurrentTime < 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestClampWhenSeekOutsideBeatmapBounds()
|
||||||
|
{
|
||||||
|
AddStep("stop clock", Clock.Stop);
|
||||||
|
|
||||||
|
AddStep("seek before start time", () => Clock.Seek(-1000));
|
||||||
|
AddAssert("time is clamped to 0", () => Clock.CurrentTime == 0);
|
||||||
|
|
||||||
|
AddStep("seek beyond track length", () => Clock.Seek(Clock.TrackLength + 1000));
|
||||||
|
AddAssert("time is clamped to track length", () => Clock.CurrentTime == Clock.TrackLength);
|
||||||
|
|
||||||
|
AddStep("seek smoothly before start time", () => Clock.SeekSmoothlyTo(-1000));
|
||||||
|
AddAssert("time is clamped to 0", () => Clock.CurrentTime == 0);
|
||||||
|
|
||||||
|
AddStep("seek smoothly beyond track length", () => Clock.SeekSmoothlyTo(Clock.TrackLength + 1000));
|
||||||
|
AddAssert("time is clamped to track length", () => Clock.CurrentTime == Clock.TrackLength);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
Beatmap.Disabled = false;
|
Beatmap.Disabled = false;
|
||||||
|
@ -19,6 +19,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
public class TestSceneHUDOverlay : OsuManualInputManagerTestScene
|
public class TestSceneHUDOverlay : OsuManualInputManagerTestScene
|
||||||
{
|
{
|
||||||
|
private OsuConfigManager localConfig;
|
||||||
|
|
||||||
private HUDOverlay hudOverlay;
|
private HUDOverlay hudOverlay;
|
||||||
|
|
||||||
[Cached]
|
[Cached]
|
||||||
@ -31,8 +33,14 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
private Drawable hideTarget => hudOverlay.KeyCounter;
|
private Drawable hideTarget => hudOverlay.KeyCounter;
|
||||||
private FillFlowContainer<KeyCounter> keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType<FillFlowContainer<KeyCounter>>().First();
|
private FillFlowContainer<KeyCounter> keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType<FillFlowContainer<KeyCounter>>().First();
|
||||||
|
|
||||||
[Resolved]
|
[BackgroundDependencyLoader]
|
||||||
private OsuConfigManager config { get; set; }
|
private void load()
|
||||||
|
{
|
||||||
|
Dependencies.Cache(localConfig = new OsuConfigManager(LocalStorage));
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp() => Schedule(() => localConfig.SetValue(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Always));
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestComboCounterIncrementing()
|
public void TestComboCounterIncrementing()
|
||||||
@ -85,11 +93,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
createNew();
|
createNew();
|
||||||
|
|
||||||
HUDVisibilityMode originalConfigValue = HUDVisibilityMode.HideDuringGameplay;
|
AddStep("set hud to never show", () => localConfig.SetValue(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Never));
|
||||||
|
|
||||||
AddStep("get original config value", () => originalConfigValue = config.Get<HUDVisibilityMode>(OsuSetting.HUDVisibilityMode));
|
|
||||||
|
|
||||||
AddStep("set hud to never show", () => config.SetValue(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Never));
|
|
||||||
|
|
||||||
AddUntilStep("wait for fade", () => !hideTarget.IsPresent);
|
AddUntilStep("wait for fade", () => !hideTarget.IsPresent);
|
||||||
|
|
||||||
@ -98,37 +102,28 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
AddStep("stop trigering", () => InputManager.ReleaseKey(Key.ControlLeft));
|
AddStep("stop trigering", () => InputManager.ReleaseKey(Key.ControlLeft));
|
||||||
AddUntilStep("wait for fade", () => !hideTarget.IsPresent);
|
AddUntilStep("wait for fade", () => !hideTarget.IsPresent);
|
||||||
|
|
||||||
AddStep("set original config value", () => config.SetValue(OsuSetting.HUDVisibilityMode, originalConfigValue));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestExternalHideDoesntAffectConfig()
|
public void TestExternalHideDoesntAffectConfig()
|
||||||
{
|
{
|
||||||
HUDVisibilityMode originalConfigValue = HUDVisibilityMode.HideDuringGameplay;
|
|
||||||
|
|
||||||
createNew();
|
createNew();
|
||||||
|
|
||||||
AddStep("get original config value", () => originalConfigValue = config.Get<HUDVisibilityMode>(OsuSetting.HUDVisibilityMode));
|
|
||||||
|
|
||||||
AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false);
|
AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false);
|
||||||
AddAssert("config unchanged", () => originalConfigValue == config.Get<HUDVisibilityMode>(OsuSetting.HUDVisibilityMode));
|
AddAssert("config unchanged", () => localConfig.GetBindable<HUDVisibilityMode>(OsuSetting.HUDVisibilityMode).IsDefault);
|
||||||
|
|
||||||
AddStep("set showhud true", () => hudOverlay.ShowHud.Value = true);
|
AddStep("set showhud true", () => hudOverlay.ShowHud.Value = true);
|
||||||
AddAssert("config unchanged", () => originalConfigValue == config.Get<HUDVisibilityMode>(OsuSetting.HUDVisibilityMode));
|
AddAssert("config unchanged", () => localConfig.GetBindable<HUDVisibilityMode>(OsuSetting.HUDVisibilityMode).IsDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestChangeHUDVisibilityOnHiddenKeyCounter()
|
public void TestChangeHUDVisibilityOnHiddenKeyCounter()
|
||||||
{
|
{
|
||||||
bool keyCounterVisibleValue = false;
|
|
||||||
|
|
||||||
createNew();
|
createNew();
|
||||||
AddStep("save keycounter visible value", () => keyCounterVisibleValue = config.Get<bool>(OsuSetting.KeyOverlay));
|
|
||||||
|
|
||||||
AddStep("set keycounter visible false", () =>
|
AddStep("hide key overlay", () =>
|
||||||
{
|
{
|
||||||
config.SetValue(OsuSetting.KeyOverlay, false);
|
localConfig.SetValue(OsuSetting.KeyOverlay, false);
|
||||||
hudOverlay.KeyCounter.AlwaysVisible.Value = false;
|
hudOverlay.KeyCounter.AlwaysVisible.Value = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -139,24 +134,16 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddStep("set showhud true", () => hudOverlay.ShowHud.Value = true);
|
AddStep("set showhud true", () => hudOverlay.ShowHud.Value = true);
|
||||||
AddUntilStep("hidetarget is visible", () => hideTarget.IsPresent);
|
AddUntilStep("hidetarget is visible", () => hideTarget.IsPresent);
|
||||||
AddAssert("key counters still hidden", () => !keyCounterFlow.IsPresent);
|
AddAssert("key counters still hidden", () => !keyCounterFlow.IsPresent);
|
||||||
|
|
||||||
AddStep("return value", () => config.SetValue(OsuSetting.KeyOverlay, keyCounterVisibleValue));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestHiddenHUDDoesntBlockSkinnableComponentsLoad()
|
public void TestHiddenHUDDoesntBlockSkinnableComponentsLoad()
|
||||||
{
|
{
|
||||||
HUDVisibilityMode originalConfigValue = default;
|
AddStep("set hud to never show", () => localConfig.SetValue(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Never));
|
||||||
|
|
||||||
AddStep("get original config value", () => originalConfigValue = config.Get<HUDVisibilityMode>(OsuSetting.HUDVisibilityMode));
|
|
||||||
|
|
||||||
AddStep("set hud to never show", () => config.SetValue(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Never));
|
|
||||||
|
|
||||||
createNew();
|
createNew();
|
||||||
AddUntilStep("wait for hud load", () => hudOverlay.IsLoaded);
|
AddUntilStep("wait for hud load", () => hudOverlay.IsLoaded);
|
||||||
AddUntilStep("skinnable components loaded", () => hudOverlay.ChildrenOfType<SkinnableTargetContainer>().Single().ComponentsLoaded);
|
AddUntilStep("skinnable components loaded", () => hudOverlay.ChildrenOfType<SkinnableTargetContainer>().Single().ComponentsLoaded);
|
||||||
|
|
||||||
AddStep("set original config value", () => config.SetValue(OsuSetting.HUDVisibilityMode, originalConfigValue));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createNew(Action<HUDOverlay> action = null)
|
private void createNew(Action<HUDOverlay> action = null)
|
||||||
@ -175,5 +162,11 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
Child = hudOverlay;
|
Child = hudOverlay;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
localConfig?.Dispose();
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
@ -66,7 +65,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
protected class OverlayTestPlayer : TestPlayer
|
protected class OverlayTestPlayer : TestPlayer
|
||||||
{
|
{
|
||||||
public new OverlayActivation OverlayActivationMode => base.OverlayActivationMode.Value;
|
public new OverlayActivation OverlayActivationMode => base.OverlayActivationMode.Value;
|
||||||
public new Bindable<bool> LocalUserPlaying => base.LocalUserPlaying;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ using osu.Game.Database;
|
|||||||
using osu.Game.Input.Bindings;
|
using osu.Game.Input.Bindings;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Tests.Resources;
|
using osu.Game.Tests.Resources;
|
||||||
using osu.Game.Tests.Visual.Navigation;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Menus
|
namespace osu.Game.Tests.Visual.Menus
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
// 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;
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
|
using osu.Framework.Utils;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Tests.Visual.Navigation;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Menus
|
namespace osu.Game.Tests.Visual.Menus
|
||||||
{
|
{
|
||||||
@ -22,21 +25,48 @@ namespace osu.Game.Tests.Visual.Menus
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestScreenOffsettingOnSettingsOverlay()
|
public void TestScreenOffsettingOnSettingsOverlay()
|
||||||
{
|
{
|
||||||
AddStep("open settings", () => Game.Settings.Show());
|
foreach (var scalingMode in Enum.GetValues(typeof(ScalingMode)).Cast<ScalingMode>())
|
||||||
AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * TestOsuGame.SIDE_OVERLAY_OFFSET_RATIO);
|
{
|
||||||
|
AddStep($"set scaling mode to {scalingMode}", () =>
|
||||||
|
{
|
||||||
|
Game.LocalConfig.SetValue(OsuSetting.Scaling, scalingMode);
|
||||||
|
|
||||||
AddStep("hide settings", () => Game.Settings.Hide());
|
if (scalingMode != ScalingMode.Off)
|
||||||
AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f);
|
{
|
||||||
|
Game.LocalConfig.SetValue(OsuSetting.ScalingSizeX, 0.5f);
|
||||||
|
Game.LocalConfig.SetValue(OsuSetting.ScalingSizeY, 0.5f);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("open settings", () => Game.Settings.Show());
|
||||||
|
AddUntilStep("right screen offset applied", () => Precision.AlmostEquals(Game.ScreenOffsetContainer.X, SettingsPanel.WIDTH * TestOsuGame.SIDE_OVERLAY_OFFSET_RATIO));
|
||||||
|
|
||||||
|
AddStep("hide settings", () => Game.Settings.Hide());
|
||||||
|
AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestScreenOffsettingOnNotificationOverlay()
|
public void TestScreenOffsettingOnNotificationOverlay()
|
||||||
{
|
{
|
||||||
AddStep("open notifications", () => Game.Notifications.Show());
|
foreach (var scalingMode in Enum.GetValues(typeof(ScalingMode)).Cast<ScalingMode>())
|
||||||
AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == -NotificationOverlay.WIDTH * TestOsuGame.SIDE_OVERLAY_OFFSET_RATIO);
|
{
|
||||||
|
if (scalingMode != ScalingMode.Off)
|
||||||
|
{
|
||||||
|
AddStep($"set scaling mode to {scalingMode}", () =>
|
||||||
|
{
|
||||||
|
Game.LocalConfig.SetValue(OsuSetting.Scaling, scalingMode);
|
||||||
|
Game.LocalConfig.SetValue(OsuSetting.ScalingSizeX, 0.5f);
|
||||||
|
Game.LocalConfig.SetValue(OsuSetting.ScalingSizeY, 0.5f);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
AddStep("hide notifications", () => Game.Notifications.Hide());
|
AddStep("open notifications", () => Game.Notifications.Show());
|
||||||
AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f);
|
AddUntilStep("right screen offset applied", () => Precision.AlmostEquals(Game.ScreenOffsetContainer.X, -NotificationOverlay.WIDTH * TestOsuGame.SIDE_OVERLAY_OFFSET_RATIO));
|
||||||
|
|
||||||
|
AddStep("hide notifications", () => Game.Notifications.Hide());
|
||||||
|
AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,11 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Online.Rooms.RoomStatuses;
|
using osu.Game.Online.Rooms.RoomStatuses;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Screens.OnlinePlay.Lounge;
|
||||||
using osu.Game.Screens.OnlinePlay.Lounge.Components;
|
using osu.Game.Screens.OnlinePlay.Lounge.Components;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
@ -108,12 +108,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
EndDate = { Value = DateTimeOffset.Now },
|
EndDate = { Value = DateTimeOffset.Now },
|
||||||
}),
|
}),
|
||||||
createDrawableRoom(new Room
|
createDrawableRoom(new Room
|
||||||
{
|
|
||||||
Name = { Value = "Room 4 (realtime)" },
|
|
||||||
Status = { Value = new RoomStatusOpen() },
|
|
||||||
Category = { Value = RoomCategory.Realtime },
|
|
||||||
}),
|
|
||||||
createDrawableRoom(new Room
|
|
||||||
{
|
{
|
||||||
Name = { Value = "Room 4 (spotlight)" },
|
Name = { Value = "Room 4 (spotlight)" },
|
||||||
Status = { Value = new RoomStatusOpen() },
|
Status = { Value = new RoomStatusOpen() },
|
||||||
@ -134,7 +128,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
Name = { Value = "Room with password" },
|
Name = { Value = "Room with password" },
|
||||||
Status = { Value = new RoomStatusOpen() },
|
Status = { Value = new RoomStatusOpen() },
|
||||||
Category = { Value = RoomCategory.Realtime },
|
Type = { Value = MatchType.HeadToHead },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
AddAssert("password icon hidden", () => Precision.AlmostEquals(0, drawableRoom.ChildrenOfType<DrawableRoom.PasswordProtectedIcon>().Single().Alpha));
|
AddAssert("password icon hidden", () => Precision.AlmostEquals(0, drawableRoom.ChildrenOfType<DrawableRoom.PasswordProtectedIcon>().Single().Alpha));
|
||||||
@ -159,10 +153,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
var drawableRoom = new DrawableRoom(room) { MatchingFilter = true };
|
return new DrawableLoungeRoom(room) { MatchingFilter = true };
|
||||||
drawableRoom.Action = () => drawableRoom.State = drawableRoom.State == SelectionState.Selected ? SelectionState.NotSelected : SelectionState.Selected;
|
|
||||||
|
|
||||||
return drawableRoom;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,131 @@
|
|||||||
|
// 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 Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Multiplayer
|
||||||
|
{
|
||||||
|
public class TestSceneGameplayChatDisplay : MultiplayerTestScene
|
||||||
|
{
|
||||||
|
private GameplayChatDisplay chatDisplay;
|
||||||
|
|
||||||
|
[Cached(typeof(ILocalUserPlayInfo))]
|
||||||
|
private ILocalUserPlayInfo localUserInfo;
|
||||||
|
|
||||||
|
private readonly Bindable<bool> localUserPlaying = new Bindable<bool>();
|
||||||
|
|
||||||
|
private TextBox textBox => chatDisplay.ChildrenOfType<TextBox>().First();
|
||||||
|
|
||||||
|
public TestSceneGameplayChatDisplay()
|
||||||
|
{
|
||||||
|
var mockLocalUserInfo = new Mock<ILocalUserPlayInfo>();
|
||||||
|
mockLocalUserInfo.SetupGet(i => i.IsPlaying).Returns(localUserPlaying);
|
||||||
|
|
||||||
|
localUserInfo = mockLocalUserInfo.Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public override void SetUpSteps()
|
||||||
|
{
|
||||||
|
base.SetUpSteps();
|
||||||
|
|
||||||
|
AddStep("load chat display", () => Child = chatDisplay = new GameplayChatDisplay
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Width = 0.5f,
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("expand", () => chatDisplay.Expanded.Value = true);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCantClickWhenPlaying()
|
||||||
|
{
|
||||||
|
setLocalUserPlaying(true);
|
||||||
|
|
||||||
|
AddStep("attempt focus chat", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(textBox);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
|
||||||
|
assertChatFocused(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestFocusDroppedWhenPlaying()
|
||||||
|
{
|
||||||
|
assertChatFocused(false);
|
||||||
|
|
||||||
|
AddStep("focus chat", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(textBox);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
|
||||||
|
setLocalUserPlaying(true);
|
||||||
|
assertChatFocused(false);
|
||||||
|
|
||||||
|
// should still stay non-focused even after entering a new break section.
|
||||||
|
setLocalUserPlaying(false);
|
||||||
|
assertChatFocused(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestFocusOnTabKeyWhenExpanded()
|
||||||
|
{
|
||||||
|
setLocalUserPlaying(true);
|
||||||
|
|
||||||
|
assertChatFocused(false);
|
||||||
|
AddStep("press tab", () => InputManager.Key(Key.Tab));
|
||||||
|
assertChatFocused(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestFocusOnTabKeyWhenNotExpanded()
|
||||||
|
{
|
||||||
|
AddStep("set not expanded", () => chatDisplay.Expanded.Value = false);
|
||||||
|
AddUntilStep("is not visible", () => !chatDisplay.IsPresent);
|
||||||
|
|
||||||
|
AddStep("press tab", () => InputManager.Key(Key.Tab));
|
||||||
|
assertChatFocused(true);
|
||||||
|
AddUntilStep("is visible", () => chatDisplay.IsPresent);
|
||||||
|
|
||||||
|
AddStep("press enter", () => InputManager.Key(Key.Enter));
|
||||||
|
assertChatFocused(false);
|
||||||
|
AddUntilStep("is not visible", () => !chatDisplay.IsPresent);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestFocusToggleViaAction()
|
||||||
|
{
|
||||||
|
AddStep("set not expanded", () => chatDisplay.Expanded.Value = false);
|
||||||
|
AddUntilStep("is not visible", () => !chatDisplay.IsPresent);
|
||||||
|
|
||||||
|
AddStep("press tab", () => InputManager.Key(Key.Tab));
|
||||||
|
assertChatFocused(true);
|
||||||
|
AddUntilStep("is visible", () => chatDisplay.IsPresent);
|
||||||
|
|
||||||
|
AddStep("press tab", () => InputManager.Key(Key.Tab));
|
||||||
|
assertChatFocused(false);
|
||||||
|
AddUntilStep("is not visible", () => !chatDisplay.IsPresent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertChatFocused(bool isFocused) =>
|
||||||
|
AddAssert($"chat {(isFocused ? "focused" : "not focused")}", () => textBox.HasFocus == isFocused);
|
||||||
|
|
||||||
|
private void setLocalUserPlaying(bool playing) =>
|
||||||
|
AddStep($"local user {(playing ? "playing" : "not playing")}", () => localUserPlaying.Value = playing);
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@ using osu.Framework.Testing;
|
|||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Rulesets.Catch;
|
using osu.Game.Rulesets.Catch;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Screens.OnlinePlay.Lounge;
|
||||||
using osu.Game.Screens.OnlinePlay.Lounge.Components;
|
using osu.Game.Screens.OnlinePlay.Lounge.Components;
|
||||||
using osu.Game.Tests.Visual.OnlinePlay;
|
using osu.Game.Tests.Visual.OnlinePlay;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
@ -17,7 +18,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
public class TestSceneLoungeRoomsContainer : OnlinePlayTestScene
|
public class TestSceneLoungeRoomsContainer : OnlinePlayTestScene
|
||||||
{
|
{
|
||||||
protected new BasicTestRoomManager RoomManager => (BasicTestRoomManager)base.RoomManager;
|
protected new TestRequestHandlingRoomManager RoomManager => (TestRequestHandlingRoomManager)base.RoomManager;
|
||||||
|
|
||||||
private RoomsContainer container;
|
private RoomsContainer container;
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddStep("add rooms", () => RoomManager.AddRooms(3));
|
AddStep("add rooms", () => RoomManager.AddRooms(3));
|
||||||
|
|
||||||
AddAssert("has 3 rooms", () => container.Rooms.Count == 3);
|
AddAssert("has 3 rooms", () => container.Rooms.Count == 3);
|
||||||
AddStep("remove first room", () => RoomManager.Rooms.Remove(RoomManager.Rooms.FirstOrDefault()));
|
AddStep("remove first room", () => RoomManager.RemoveRoom(RoomManager.Rooms.FirstOrDefault()));
|
||||||
AddAssert("has 2 rooms", () => container.Rooms.Count == 2);
|
AddAssert("has 2 rooms", () => container.Rooms.Count == 2);
|
||||||
AddAssert("first room removed", () => container.Rooms.All(r => r.Room.RoomID.Value != 0));
|
AddAssert("first room removed", () => container.Rooms.All(r => r.Room.RoomID.Value != 0));
|
||||||
|
|
||||||
@ -74,7 +75,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
var room = RoomManager.Rooms[1];
|
var room = RoomManager.Rooms[1];
|
||||||
|
|
||||||
RoomManager.RemoveRoom(room);
|
RoomManager.RemoveRoom(room);
|
||||||
RoomManager.AddRoom(room);
|
RoomManager.AddOrUpdateRoom(room);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("no selection", () => checkRoomSelected(null));
|
AddAssert("no selection", () => checkRoomSelected(null));
|
||||||
@ -115,11 +116,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
AddUntilStep("4 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 4);
|
AddUntilStep("4 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 4);
|
||||||
|
|
||||||
AddStep("filter one room", () => container.Filter(new FilterCriteria { SearchString = "1" }));
|
AddStep("filter one room", () => container.Filter.Value = new FilterCriteria { SearchString = "1" });
|
||||||
|
|
||||||
AddUntilStep("1 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 1);
|
AddUntilStep("1 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 1);
|
||||||
|
|
||||||
AddStep("remove filter", () => container.Filter(null));
|
AddStep("remove filter", () => container.Filter.Value = null);
|
||||||
|
|
||||||
AddUntilStep("4 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 4);
|
AddUntilStep("4 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 4);
|
||||||
}
|
}
|
||||||
@ -131,13 +132,13 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddStep("add rooms", () => RoomManager.AddRooms(3, new CatchRuleset().RulesetInfo));
|
AddStep("add rooms", () => RoomManager.AddRooms(3, new CatchRuleset().RulesetInfo));
|
||||||
|
|
||||||
// Todo: What even is this case...?
|
// Todo: What even is this case...?
|
||||||
AddStep("set empty filter criteria", () => container.Filter(null));
|
AddStep("set empty filter criteria", () => container.Filter.Value = null);
|
||||||
AddUntilStep("5 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 5);
|
AddUntilStep("5 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 5);
|
||||||
|
|
||||||
AddStep("filter osu! rooms", () => container.Filter(new FilterCriteria { Ruleset = new OsuRuleset().RulesetInfo }));
|
AddStep("filter osu! rooms", () => container.Filter.Value = new FilterCriteria { Ruleset = new OsuRuleset().RulesetInfo });
|
||||||
AddUntilStep("2 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 2);
|
AddUntilStep("2 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 2);
|
||||||
|
|
||||||
AddStep("filter catch rooms", () => container.Filter(new FilterCriteria { Ruleset = new CatchRuleset().RulesetInfo }));
|
AddStep("filter catch rooms", () => container.Filter.Value = new FilterCriteria { Ruleset = new CatchRuleset().RulesetInfo });
|
||||||
AddUntilStep("3 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 3);
|
AddUntilStep("3 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,6 +151,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
private bool checkRoomSelected(Room room) => SelectedRoom.Value == room;
|
private bool checkRoomSelected(Room room) => SelectedRoom.Value == room;
|
||||||
|
|
||||||
private Room getRoomInFlow(int index) =>
|
private Room getRoomInFlow(int index) =>
|
||||||
(container.ChildrenOfType<FillFlowContainer<DrawableRoom>>().First().FlowingChildren.ElementAt(index) as DrawableRoom)?.Room;
|
(container.ChildrenOfType<FillFlowContainer<DrawableLoungeRoom>>().First().FlowingChildren.ElementAt(index) as DrawableRoom)?.Room;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
// 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.Game.Beatmaps;
|
|
||||||
using osu.Game.Online.Rooms;
|
|
||||||
using osu.Game.Rulesets.Osu;
|
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
|
||||||
using osu.Game.Screens.OnlinePlay.Match.Components;
|
|
||||||
using osu.Game.Tests.Visual.OnlinePlay;
|
|
||||||
using osu.Game.Users;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Multiplayer
|
|
||||||
{
|
|
||||||
public class TestSceneMatchHeader : OnlinePlayTestScene
|
|
||||||
{
|
|
||||||
[SetUp]
|
|
||||||
public new void Setup() => Schedule(() =>
|
|
||||||
{
|
|
||||||
SelectedRoom.Value = new Room
|
|
||||||
{
|
|
||||||
Name = { Value = "A very awesome room" },
|
|
||||||
Host = { Value = new User { Id = 2, Username = "peppy" } },
|
|
||||||
Playlist =
|
|
||||||
{
|
|
||||||
new PlaylistItem
|
|
||||||
{
|
|
||||||
Beatmap =
|
|
||||||
{
|
|
||||||
Value = new BeatmapInfo
|
|
||||||
{
|
|
||||||
Metadata = new BeatmapMetadata
|
|
||||||
{
|
|
||||||
Title = "Title",
|
|
||||||
Artist = "Artist",
|
|
||||||
AuthorString = "Author",
|
|
||||||
},
|
|
||||||
Version = "Version",
|
|
||||||
Ruleset = new OsuRuleset().RulesetInfo
|
|
||||||
}
|
|
||||||
},
|
|
||||||
RequiredMods =
|
|
||||||
{
|
|
||||||
new OsuModDoubleTime(),
|
|
||||||
new OsuModNoFail(),
|
|
||||||
new OsuModRelax(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Child = new Header();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,13 +6,17 @@ using System.Linq;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Online.Multiplayer;
|
using osu.Game.Online.Multiplayer;
|
||||||
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
|
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Screens.OnlinePlay.Multiplayer.Spectate;
|
using osu.Game.Screens.OnlinePlay.Multiplayer.Spectate;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Screens.Play.HUD;
|
||||||
|
using osu.Game.Screens.Play.PlayerSettings;
|
||||||
using osu.Game.Tests.Beatmaps.IO;
|
using osu.Game.Tests.Beatmaps.IO;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
@ -23,6 +27,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuGameBase game { get; set; }
|
private OsuGameBase game { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private OsuConfigManager config { get; set; }
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private BeatmapManager beatmapManager { get; set; }
|
private BeatmapManager beatmapManager { get; set; }
|
||||||
|
|
||||||
@ -80,6 +87,32 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddWaitStep("wait a bit", 20);
|
AddWaitStep("wait a bit", 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSpectatorPlayerInteractiveElementsHidden()
|
||||||
|
{
|
||||||
|
HUDVisibilityMode originalConfigValue = default;
|
||||||
|
|
||||||
|
AddStep("get original config hud visibility", () => originalConfigValue = config.Get<HUDVisibilityMode>(OsuSetting.HUDVisibilityMode));
|
||||||
|
AddStep("set config hud visibility to always", () => config.SetValue(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Always));
|
||||||
|
|
||||||
|
start(new[] { PLAYER_1_ID, PLAYER_2_ID });
|
||||||
|
loadSpectateScreen(false);
|
||||||
|
|
||||||
|
AddUntilStep("wait for player loaders", () => this.ChildrenOfType<PlayerLoader>().Count() == 2);
|
||||||
|
AddAssert("all player loader settings hidden", () => this.ChildrenOfType<PlayerLoader>().All(l => !l.ChildrenOfType<FillFlowContainer<PlayerSettingsGroup>>().Any()));
|
||||||
|
|
||||||
|
AddUntilStep("wait for players to load", () => spectatorScreen.AllPlayersLoaded);
|
||||||
|
|
||||||
|
// components wrapped in skinnable target containers load asynchronously, potentially taking more than one frame to load.
|
||||||
|
// therefore use until step rather than direct assert to account for that.
|
||||||
|
AddUntilStep("all interactive elements removed", () => this.ChildrenOfType<Player>().All(p =>
|
||||||
|
!p.ChildrenOfType<PlayerSettingsOverlay>().Any() &&
|
||||||
|
!p.ChildrenOfType<HoldForMenuButton>().Any() &&
|
||||||
|
p.ChildrenOfType<SongProgressBar>().SingleOrDefault()?.ShowHandle == false));
|
||||||
|
|
||||||
|
AddStep("restore config hud visibility", () => config.SetValue(OsuSetting.HUDVisibilityMode, originalConfigValue));
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestTeamDisplay()
|
public void TestTeamDisplay()
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
private TestMultiplayer multiplayerScreen;
|
private TestMultiplayer multiplayerScreen;
|
||||||
private TestMultiplayerClient client;
|
private TestMultiplayerClient client;
|
||||||
|
|
||||||
|
private TestRequestHandlingMultiplayerRoomManager roomManager => multiplayerScreen.RoomManager;
|
||||||
|
|
||||||
[Cached(typeof(UserLookupCache))]
|
[Cached(typeof(UserLookupCache))]
|
||||||
private UserLookupCache lookupCache = new TestUserLookupCache();
|
private UserLookupCache lookupCache = new TestUserLookupCache();
|
||||||
|
|
||||||
@ -68,7 +70,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
AddStep("load dependencies", () =>
|
AddStep("load dependencies", () =>
|
||||||
{
|
{
|
||||||
client = new TestMultiplayerClient(multiplayerScreen.RoomManager);
|
client = new TestMultiplayerClient(roomManager);
|
||||||
|
|
||||||
// The screen gets suspended so it stops receiving updates.
|
// The screen gets suspended so it stops receiving updates.
|
||||||
Child = client;
|
Child = client;
|
||||||
@ -132,39 +134,9 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestExitMidJoin()
|
public void TestExitMidJoin()
|
||||||
{
|
{
|
||||||
Room room = null;
|
|
||||||
|
|
||||||
AddStep("create room", () =>
|
AddStep("create room", () =>
|
||||||
{
|
{
|
||||||
room = new Room
|
roomManager.AddServerSideRoom(new Room
|
||||||
{
|
|
||||||
Name = { Value = "Test Room" },
|
|
||||||
Playlist =
|
|
||||||
{
|
|
||||||
new PlaylistItem
|
|
||||||
{
|
|
||||||
Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo },
|
|
||||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep("refresh rooms", () => multiplayerScreen.RoomManager.Filter.Value = new FilterCriteria());
|
|
||||||
AddStep("select room", () => InputManager.Key(Key.Down));
|
|
||||||
AddStep("join room and immediately exit", () =>
|
|
||||||
{
|
|
||||||
multiplayerScreen.ChildrenOfType<LoungeSubScreen>().Single().Open(room);
|
|
||||||
Schedule(() => Stack.CurrentScreen.Exit());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestJoinRoomWithoutPassword()
|
|
||||||
{
|
|
||||||
AddStep("create room", () =>
|
|
||||||
{
|
|
||||||
multiplayerScreen.RoomManager.AddRoom(new Room
|
|
||||||
{
|
{
|
||||||
Name = { Value = "Test Room" },
|
Name = { Value = "Test Room" },
|
||||||
Playlist =
|
Playlist =
|
||||||
@ -178,7 +150,39 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("refresh rooms", () => multiplayerScreen.RoomManager.Filter.Value = new FilterCriteria());
|
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
||||||
|
AddUntilStep("wait for room", () => this.ChildrenOfType<DrawableRoom>().Any());
|
||||||
|
|
||||||
|
AddStep("select room", () => InputManager.Key(Key.Down));
|
||||||
|
AddStep("join room and immediately exit select", () =>
|
||||||
|
{
|
||||||
|
InputManager.Key(Key.Enter);
|
||||||
|
Schedule(() => Stack.CurrentScreen.Exit());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestJoinRoomWithoutPassword()
|
||||||
|
{
|
||||||
|
AddStep("create room", () =>
|
||||||
|
{
|
||||||
|
roomManager.AddServerSideRoom(new Room
|
||||||
|
{
|
||||||
|
Name = { Value = "Test Room" },
|
||||||
|
Playlist =
|
||||||
|
{
|
||||||
|
new PlaylistItem
|
||||||
|
{
|
||||||
|
Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo },
|
||||||
|
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
||||||
|
AddUntilStep("wait for room", () => this.ChildrenOfType<DrawableRoom>().Any());
|
||||||
|
|
||||||
AddStep("select room", () => InputManager.Key(Key.Down));
|
AddStep("select room", () => InputManager.Key(Key.Down));
|
||||||
AddStep("join room", () => InputManager.Key(Key.Enter));
|
AddStep("join room", () => InputManager.Key(Key.Enter));
|
||||||
|
|
||||||
@ -211,7 +215,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
AddStep("create room", () =>
|
AddStep("create room", () =>
|
||||||
{
|
{
|
||||||
multiplayerScreen.RoomManager.AddRoom(new Room
|
roomManager.AddServerSideRoom(new Room
|
||||||
{
|
{
|
||||||
Name = { Value = "Test Room" },
|
Name = { Value = "Test Room" },
|
||||||
Password = { Value = "password" },
|
Password = { Value = "password" },
|
||||||
@ -226,12 +230,14 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("refresh rooms", () => multiplayerScreen.RoomManager.Filter.Value = new FilterCriteria());
|
AddStep("refresh rooms", () => this.ChildrenOfType<LoungeSubScreen>().Single().UpdateFilter());
|
||||||
|
AddUntilStep("wait for room", () => this.ChildrenOfType<DrawableRoom>().Any());
|
||||||
|
|
||||||
AddStep("select room", () => InputManager.Key(Key.Down));
|
AddStep("select room", () => InputManager.Key(Key.Down));
|
||||||
AddStep("join room", () => InputManager.Key(Key.Enter));
|
AddStep("join room", () => InputManager.Key(Key.Enter));
|
||||||
|
|
||||||
DrawableRoom.PasswordEntryPopover passwordEntryPopover = null;
|
DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null;
|
||||||
AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType<DrawableRoom.PasswordEntryPopover>().FirstOrDefault()) != null);
|
AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType<DrawableLoungeRoom.PasswordEntryPopover>().FirstOrDefault()) != null);
|
||||||
AddStep("enter password in text box", () => passwordEntryPopover.ChildrenOfType<TextBox>().First().Text = "password");
|
AddStep("enter password in text box", () => passwordEntryPopover.ChildrenOfType<TextBox>().First().Text = "password");
|
||||||
AddStep("press join room button", () => passwordEntryPopover.ChildrenOfType<OsuButton>().First().TriggerClick());
|
AddStep("press join room button", () => passwordEntryPopover.ChildrenOfType<OsuButton>().First().TriggerClick());
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ using osu.Framework.Testing;
|
|||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Screens.OnlinePlay.Lounge;
|
using osu.Game.Screens.OnlinePlay.Lounge;
|
||||||
using osu.Game.Screens.OnlinePlay.Lounge.Components;
|
|
||||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||||
using osu.Game.Tests.Visual.OnlinePlay;
|
using osu.Game.Tests.Visual.OnlinePlay;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
@ -18,7 +17,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
public class TestSceneMultiplayerLoungeSubScreen : OnlinePlayTestScene
|
public class TestSceneMultiplayerLoungeSubScreen : OnlinePlayTestScene
|
||||||
{
|
{
|
||||||
protected new BasicTestRoomManager RoomManager => (BasicTestRoomManager)base.RoomManager;
|
protected new TestRequestHandlingRoomManager RoomManager => (TestRequestHandlingRoomManager)base.RoomManager;
|
||||||
|
|
||||||
private LoungeSubScreen loungeScreen;
|
private LoungeSubScreen loungeScreen;
|
||||||
|
|
||||||
@ -59,20 +58,20 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddStep("select room", () => InputManager.Key(Key.Down));
|
AddStep("select room", () => InputManager.Key(Key.Down));
|
||||||
AddStep("attempt join room", () => InputManager.Key(Key.Enter));
|
AddStep("attempt join room", () => InputManager.Key(Key.Enter));
|
||||||
|
|
||||||
AddUntilStep("password prompt appeared", () => InputManager.ChildrenOfType<DrawableRoom.PasswordEntryPopover>().Any());
|
AddUntilStep("password prompt appeared", () => InputManager.ChildrenOfType<DrawableLoungeRoom.PasswordEntryPopover>().Any());
|
||||||
AddStep("exit screen", () => Stack.Exit());
|
AddStep("exit screen", () => Stack.Exit());
|
||||||
AddUntilStep("password prompt hidden", () => !InputManager.ChildrenOfType<DrawableRoom.PasswordEntryPopover>().Any());
|
AddUntilStep("password prompt hidden", () => !InputManager.ChildrenOfType<DrawableLoungeRoom.PasswordEntryPopover>().Any());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestJoinRoomWithPassword()
|
public void TestJoinRoomWithPassword()
|
||||||
{
|
{
|
||||||
DrawableRoom.PasswordEntryPopover passwordEntryPopover = null;
|
DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null;
|
||||||
|
|
||||||
AddStep("add room", () => RoomManager.AddRooms(1, withPassword: true));
|
AddStep("add room", () => RoomManager.AddRooms(1, withPassword: true));
|
||||||
AddStep("select room", () => InputManager.Key(Key.Down));
|
AddStep("select room", () => InputManager.Key(Key.Down));
|
||||||
AddStep("attempt join room", () => InputManager.Key(Key.Enter));
|
AddStep("attempt join room", () => InputManager.Key(Key.Enter));
|
||||||
AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType<DrawableRoom.PasswordEntryPopover>().FirstOrDefault()) != null);
|
AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType<DrawableLoungeRoom.PasswordEntryPopover>().FirstOrDefault()) != null);
|
||||||
AddStep("enter password in text box", () => passwordEntryPopover.ChildrenOfType<TextBox>().First().Text = "password");
|
AddStep("enter password in text box", () => passwordEntryPopover.ChildrenOfType<TextBox>().First().Text = "password");
|
||||||
AddStep("press join room button", () => passwordEntryPopover.ChildrenOfType<OsuButton>().First().TriggerClick());
|
AddStep("press join room button", () => passwordEntryPopover.ChildrenOfType<OsuButton>().First().TriggerClick());
|
||||||
|
|
||||||
@ -83,12 +82,12 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestJoinRoomWithPasswordViaKeyboardOnly()
|
public void TestJoinRoomWithPasswordViaKeyboardOnly()
|
||||||
{
|
{
|
||||||
DrawableRoom.PasswordEntryPopover passwordEntryPopover = null;
|
DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null;
|
||||||
|
|
||||||
AddStep("add room", () => RoomManager.AddRooms(1, withPassword: true));
|
AddStep("add room", () => RoomManager.AddRooms(1, withPassword: true));
|
||||||
AddStep("select room", () => InputManager.Key(Key.Down));
|
AddStep("select room", () => InputManager.Key(Key.Down));
|
||||||
AddStep("attempt join room", () => InputManager.Key(Key.Enter));
|
AddStep("attempt join room", () => InputManager.Key(Key.Enter));
|
||||||
AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType<DrawableRoom.PasswordEntryPopover>().FirstOrDefault()) != null);
|
AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType<DrawableLoungeRoom.PasswordEntryPopover>().FirstOrDefault()) != null);
|
||||||
AddStep("enter password in text box", () => passwordEntryPopover.ChildrenOfType<TextBox>().First().Text = "password");
|
AddStep("enter password in text box", () => passwordEntryPopover.ChildrenOfType<TextBox>().First().Text = "password");
|
||||||
AddStep("press enter", () => InputManager.Key(Key.Enter));
|
AddStep("press enter", () => InputManager.Key(Key.Enter));
|
||||||
|
|
||||||
|
@ -59,23 +59,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddUntilStep("wait for load", () => screen.IsCurrentScreen());
|
AddUntilStep("wait for load", () => screen.IsCurrentScreen());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestSettingValidity()
|
|
||||||
{
|
|
||||||
AddAssert("create button not enabled", () => !this.ChildrenOfType<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>().Single().Enabled.Value);
|
|
||||||
|
|
||||||
AddStep("set playlist", () =>
|
|
||||||
{
|
|
||||||
SelectedRoom.Value.Playlist.Add(new PlaylistItem
|
|
||||||
{
|
|
||||||
Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo },
|
|
||||||
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
AddAssert("create button enabled", () => this.ChildrenOfType<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>().Single().Enabled.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestCreatedRoom()
|
public void TestCreatedRoom()
|
||||||
{
|
{
|
||||||
@ -97,6 +80,23 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddUntilStep("wait for join", () => Client.Room != null);
|
AddUntilStep("wait for join", () => Client.Room != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSettingValidity()
|
||||||
|
{
|
||||||
|
AddAssert("create button not enabled", () => !this.ChildrenOfType<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>().Single().Enabled.Value);
|
||||||
|
|
||||||
|
AddStep("set playlist", () =>
|
||||||
|
{
|
||||||
|
SelectedRoom.Value.Playlist.Add(new PlaylistItem
|
||||||
|
{
|
||||||
|
Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo },
|
||||||
|
Ruleset = { Value = new OsuRuleset().RulesetInfo },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("create button enabled", () => this.ChildrenOfType<MultiplayerMatchSettingsOverlay.CreateOrUpdateButton>().Single().Enabled.Value);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestStartMatchWhileSpectating()
|
public void TestStartMatchWhileSpectating()
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
// 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;
|
||||||
|
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Multiplayer
|
||||||
|
{
|
||||||
|
public class TestSceneMultiplayerPlayer : MultiplayerTestScene
|
||||||
|
{
|
||||||
|
private MultiplayerPlayer player;
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public override void SetUpSteps()
|
||||||
|
{
|
||||||
|
base.SetUpSteps();
|
||||||
|
|
||||||
|
AddStep("set beatmap", () =>
|
||||||
|
{
|
||||||
|
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("initialise gameplay", () =>
|
||||||
|
{
|
||||||
|
Stack.Push(player = new MultiplayerPlayer(Client.CurrentMatchPlayingItem.Value, Client.Room?.Users.ToArray()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestGameplay()
|
||||||
|
{
|
||||||
|
AddUntilStep("wait for gameplay start", () => player.LocalUserPlaying.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,157 +0,0 @@
|
|||||||
// 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 NUnit.Framework;
|
|
||||||
using osu.Framework.Testing;
|
|
||||||
using osu.Game.Online.Rooms;
|
|
||||||
using osu.Game.Screens.OnlinePlay.Components;
|
|
||||||
using osu.Game.Tests.Beatmaps;
|
|
||||||
using osu.Game.Tests.Visual.OnlinePlay;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Multiplayer
|
|
||||||
{
|
|
||||||
[HeadlessTest]
|
|
||||||
public class TestSceneMultiplayerRoomManager : MultiplayerTestScene
|
|
||||||
{
|
|
||||||
protected override OnlinePlayTestSceneDependencies CreateOnlinePlayDependencies() => new TestDependencies();
|
|
||||||
|
|
||||||
public TestSceneMultiplayerRoomManager()
|
|
||||||
: base(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestPollsInitially()
|
|
||||||
{
|
|
||||||
AddStep("create room manager with a few rooms", () =>
|
|
||||||
{
|
|
||||||
RoomManager.CreateRoom(createRoom(r => r.Name.Value = "1"));
|
|
||||||
RoomManager.PartRoom();
|
|
||||||
RoomManager.CreateRoom(createRoom(r => r.Name.Value = "2"));
|
|
||||||
RoomManager.PartRoom();
|
|
||||||
RoomManager.ClearRooms();
|
|
||||||
});
|
|
||||||
|
|
||||||
AddAssert("manager polled for rooms", () => ((RoomManager)RoomManager).Rooms.Count == 2);
|
|
||||||
AddAssert("initial rooms received", () => RoomManager.InitialRoomsReceived.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestRoomsClearedOnDisconnection()
|
|
||||||
{
|
|
||||||
AddStep("create room manager with a few rooms", () =>
|
|
||||||
{
|
|
||||||
RoomManager.CreateRoom(createRoom());
|
|
||||||
RoomManager.PartRoom();
|
|
||||||
RoomManager.CreateRoom(createRoom());
|
|
||||||
RoomManager.PartRoom();
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep("disconnect", () => Client.Disconnect());
|
|
||||||
|
|
||||||
AddAssert("rooms cleared", () => ((RoomManager)RoomManager).Rooms.Count == 0);
|
|
||||||
AddAssert("initial rooms not received", () => !RoomManager.InitialRoomsReceived.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestRoomsPolledOnReconnect()
|
|
||||||
{
|
|
||||||
AddStep("create room manager with a few rooms", () =>
|
|
||||||
{
|
|
||||||
RoomManager.CreateRoom(createRoom());
|
|
||||||
RoomManager.PartRoom();
|
|
||||||
RoomManager.CreateRoom(createRoom());
|
|
||||||
RoomManager.PartRoom();
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep("disconnect", () => Client.Disconnect());
|
|
||||||
AddStep("connect", () => Client.Connect());
|
|
||||||
|
|
||||||
AddAssert("manager polled for rooms", () => ((RoomManager)RoomManager).Rooms.Count == 2);
|
|
||||||
AddAssert("initial rooms received", () => RoomManager.InitialRoomsReceived.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestRoomsNotPolledWhenJoined()
|
|
||||||
{
|
|
||||||
AddStep("create room manager with a room", () =>
|
|
||||||
{
|
|
||||||
RoomManager.CreateRoom(createRoom());
|
|
||||||
RoomManager.ClearRooms();
|
|
||||||
});
|
|
||||||
|
|
||||||
AddAssert("manager not polled for rooms", () => ((RoomManager)RoomManager).Rooms.Count == 0);
|
|
||||||
AddAssert("initial rooms not received", () => !RoomManager.InitialRoomsReceived.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestMultiplayerRoomJoinedWhenCreated()
|
|
||||||
{
|
|
||||||
AddStep("create room manager with a room", () =>
|
|
||||||
{
|
|
||||||
RoomManager.CreateRoom(createRoom());
|
|
||||||
});
|
|
||||||
|
|
||||||
AddUntilStep("multiplayer room joined", () => Client.Room != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestMultiplayerRoomPartedWhenAPIRoomParted()
|
|
||||||
{
|
|
||||||
AddStep("create room manager with a room", () =>
|
|
||||||
{
|
|
||||||
RoomManager.CreateRoom(createRoom());
|
|
||||||
RoomManager.PartRoom();
|
|
||||||
});
|
|
||||||
|
|
||||||
AddAssert("multiplayer room parted", () => Client.Room == null);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestMultiplayerRoomJoinedWhenAPIRoomJoined()
|
|
||||||
{
|
|
||||||
AddStep("create room manager with a room", () =>
|
|
||||||
{
|
|
||||||
var r = createRoom();
|
|
||||||
RoomManager.CreateRoom(r);
|
|
||||||
RoomManager.PartRoom();
|
|
||||||
RoomManager.JoinRoom(r);
|
|
||||||
});
|
|
||||||
|
|
||||||
AddUntilStep("multiplayer room joined", () => Client.Room != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Room createRoom(Action<Room> initFunc = null)
|
|
||||||
{
|
|
||||||
var room = new Room
|
|
||||||
{
|
|
||||||
Name =
|
|
||||||
{
|
|
||||||
Value = "test room"
|
|
||||||
},
|
|
||||||
Playlist =
|
|
||||||
{
|
|
||||||
new PlaylistItem
|
|
||||||
{
|
|
||||||
Beatmap = { Value = new TestBeatmap(Ruleset.Value).BeatmapInfo },
|
|
||||||
Ruleset = { Value = Ruleset.Value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
initFunc?.Invoke(room);
|
|
||||||
return room;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestDependencies : MultiplayerTestSceneDependencies
|
|
||||||
{
|
|
||||||
public TestDependencies()
|
|
||||||
{
|
|
||||||
// Need to set these values as early as possible.
|
|
||||||
RoomManager.TimeBetweenListingPolls.Value = 1;
|
|
||||||
RoomManager.TimeBetweenSelectionPolls.Value = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,6 +10,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
@ -88,21 +89,27 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuGameBase gameBase { get; set; }
|
private OsuGameBase gameBase { get; set; }
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[Resolved]
|
||||||
private void load(GameHost host)
|
private GameHost host { get; set; }
|
||||||
{
|
|
||||||
game = new OsuGame();
|
|
||||||
game.SetHost(host);
|
|
||||||
|
|
||||||
Children = new Drawable[]
|
[SetUpSteps]
|
||||||
|
public void SetUpSteps()
|
||||||
|
{
|
||||||
|
AddStep("create game", () =>
|
||||||
{
|
{
|
||||||
new Box
|
game = new OsuGame();
|
||||||
|
game.SetHost(host);
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
new Box
|
||||||
Colour = Color4.Black,
|
{
|
||||||
},
|
RelativeSizeAxes = Axes.Both,
|
||||||
game
|
Colour = Color4.Black,
|
||||||
};
|
},
|
||||||
|
game
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for load", () => game.IsLoaded);
|
AddUntilStep("wait for load", () => game.IsLoaded);
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,12 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
{
|
{
|
||||||
public class TestSettingsMigration : OsuGameTestScene
|
public class TestSettingsMigration : OsuGameTestScene
|
||||||
{
|
{
|
||||||
public override void RecycleLocalStorage()
|
public override void RecycleLocalStorage(bool isDisposing)
|
||||||
{
|
{
|
||||||
base.RecycleLocalStorage();
|
base.RecycleLocalStorage(isDisposing);
|
||||||
|
|
||||||
|
if (isDisposing)
|
||||||
|
return;
|
||||||
|
|
||||||
using (var config = new OsuConfigManager(LocalStorage))
|
using (var config = new OsuConfigManager(LocalStorage))
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
{
|
{
|
||||||
public class TestScenePlaylistsLoungeSubScreen : OnlinePlayTestScene
|
public class TestScenePlaylistsLoungeSubScreen : OnlinePlayTestScene
|
||||||
{
|
{
|
||||||
protected new BasicTestRoomManager RoomManager => (BasicTestRoomManager)base.RoomManager;
|
protected new TestRequestHandlingRoomManager RoomManager => (TestRequestHandlingRoomManager)base.RoomManager;
|
||||||
|
|
||||||
private LoungeSubScreen loungeScreen;
|
private LoungeSubScreen loungeScreen;
|
||||||
|
|
||||||
@ -37,6 +37,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
AddStep("reset mouse", () => InputManager.ReleaseButton(MouseButton.Left));
|
AddStep("reset mouse", () => InputManager.ReleaseButton(MouseButton.Left));
|
||||||
|
|
||||||
AddStep("add rooms", () => RoomManager.AddRooms(30));
|
AddStep("add rooms", () => RoomManager.AddRooms(30));
|
||||||
|
AddUntilStep("wait for rooms", () => roomsContainer.Rooms.Count == 30);
|
||||||
|
|
||||||
AddUntilStep("first room is not masked", () => checkRoomVisible(roomsContainer.Rooms[0]));
|
AddUntilStep("first room is not masked", () => checkRoomVisible(roomsContainer.Rooms[0]));
|
||||||
|
|
||||||
@ -53,6 +54,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
public void TestScrollSelectedIntoView()
|
public void TestScrollSelectedIntoView()
|
||||||
{
|
{
|
||||||
AddStep("add rooms", () => RoomManager.AddRooms(30));
|
AddStep("add rooms", () => RoomManager.AddRooms(30));
|
||||||
|
AddUntilStep("wait for rooms", () => roomsContainer.Rooms.Count == 30);
|
||||||
|
|
||||||
AddUntilStep("first room is not masked", () => checkRoomVisible(roomsContainer.Rooms[0]));
|
AddUntilStep("first room is not masked", () => checkRoomVisible(roomsContainer.Rooms[0]));
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
AddUntilStep("error not displayed", () => !settings.ErrorText.IsPresent);
|
AddUntilStep("error not displayed", () => !settings.ErrorText.IsPresent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestRoomSettings : PlaylistsMatchSettingsOverlay
|
private class TestRoomSettings : PlaylistsRoomSettingsOverlay
|
||||||
{
|
{
|
||||||
public TriangleButton ApplyButton => ((MatchSettings)Settings).ApplyButton;
|
public TriangleButton ApplyButton => ((MatchSettings)Settings).ApplyButton;
|
||||||
|
|
||||||
@ -141,6 +141,12 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
|
|
||||||
public IBindableList<Room> Rooms => null;
|
public IBindableList<Room> Rooms => null;
|
||||||
|
|
||||||
|
public void AddOrUpdateRoom(Room room) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public void RemoveRoom(Room room) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public void ClearRooms() => throw new NotImplementedException();
|
||||||
|
|
||||||
public void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null)
|
public void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null)
|
||||||
{
|
{
|
||||||
if (CreateRequested == null)
|
if (CreateRequested == null)
|
||||||
|
@ -11,7 +11,6 @@ using osu.Framework.Platform;
|
|||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Online.API;
|
|
||||||
using osu.Game.Online.Rooms;
|
using osu.Game.Online.Rooms;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
@ -19,7 +18,6 @@ using osu.Game.Screens.OnlinePlay.Playlists;
|
|||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
using osu.Game.Tests.Visual.OnlinePlay;
|
using osu.Game.Tests.Visual.OnlinePlay;
|
||||||
using osu.Game.Users;
|
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Playlists
|
namespace osu.Game.Tests.Visual.Playlists
|
||||||
@ -36,18 +34,6 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
{
|
{
|
||||||
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
||||||
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
|
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
|
||||||
|
|
||||||
((DummyAPIAccess)API).HandleRequest = req =>
|
|
||||||
{
|
|
||||||
switch (req)
|
|
||||||
{
|
|
||||||
case CreateRoomScoreRequest createRoomScoreRequest:
|
|
||||||
createRoomScoreRequest.TriggerSuccess(new APIScoreToken { ID = 1 });
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
@ -66,7 +52,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
{
|
{
|
||||||
SelectedRoom.Value.RoomID.Value = 1;
|
SelectedRoom.Value.RoomID.Value = 1;
|
||||||
SelectedRoom.Value.Name.Value = "my awesome room";
|
SelectedRoom.Value.Name.Value = "my awesome room";
|
||||||
SelectedRoom.Value.Host.Value = new User { Id = 2, Username = "peppy" };
|
SelectedRoom.Value.Host.Value = API.LocalUser.Value;
|
||||||
SelectedRoom.Value.RecentParticipants.Add(SelectedRoom.Value.Host.Value);
|
SelectedRoom.Value.RecentParticipants.Add(SelectedRoom.Value.Host.Value);
|
||||||
SelectedRoom.Value.EndDate.Value = DateTimeOffset.Now.AddMinutes(5);
|
SelectedRoom.Value.EndDate.Value = DateTimeOffset.Now.AddMinutes(5);
|
||||||
SelectedRoom.Value.Playlist.Add(new PlaylistItem
|
SelectedRoom.Value.Playlist.Add(new PlaylistItem
|
||||||
@ -86,7 +72,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
AddStep("set room properties", () =>
|
AddStep("set room properties", () =>
|
||||||
{
|
{
|
||||||
SelectedRoom.Value.Name.Value = "my awesome room";
|
SelectedRoom.Value.Name.Value = "my awesome room";
|
||||||
SelectedRoom.Value.Host.Value = new User { Id = 2, Username = "peppy" };
|
SelectedRoom.Value.Host.Value = API.LocalUser.Value;
|
||||||
SelectedRoom.Value.Playlist.Add(new PlaylistItem
|
SelectedRoom.Value.Playlist.Add(new PlaylistItem
|
||||||
{
|
{
|
||||||
Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo },
|
Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo },
|
||||||
@ -96,7 +82,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
|
|
||||||
AddStep("move mouse to create button", () =>
|
AddStep("move mouse to create button", () =>
|
||||||
{
|
{
|
||||||
InputManager.MoveMouseTo(this.ChildrenOfType<PlaylistsMatchSettingsOverlay.CreateRoomButton>().Single());
|
InputManager.MoveMouseTo(this.ChildrenOfType<PlaylistsRoomSettingsOverlay.CreateRoomButton>().Single());
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
||||||
@ -137,7 +123,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
AddStep("load room", () =>
|
AddStep("load room", () =>
|
||||||
{
|
{
|
||||||
SelectedRoom.Value.Name.Value = "my awesome room";
|
SelectedRoom.Value.Name.Value = "my awesome room";
|
||||||
SelectedRoom.Value.Host.Value = new User { Id = 2, Username = "peppy" };
|
SelectedRoom.Value.Host.Value = API.LocalUser.Value;
|
||||||
SelectedRoom.Value.Playlist.Add(new PlaylistItem
|
SelectedRoom.Value.Playlist.Add(new PlaylistItem
|
||||||
{
|
{
|
||||||
Beatmap = { Value = importedSet.Beatmaps[0] },
|
Beatmap = { Value = importedSet.Beatmaps[0] },
|
||||||
@ -147,7 +133,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
|
|
||||||
AddStep("create room", () =>
|
AddStep("create room", () =>
|
||||||
{
|
{
|
||||||
InputManager.MoveMouseTo(match.ChildrenOfType<PlaylistsMatchSettingsOverlay.CreateRoomButton>().Single());
|
InputManager.MoveMouseTo(match.ChildrenOfType<PlaylistsRoomSettingsOverlay.CreateRoomButton>().Single());
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
// 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.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Utils;
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Screens.Ranking.Expanded;
|
|
||||||
using osuTK;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Ranking
|
|
||||||
{
|
|
||||||
public class TestSceneStarRatingDisplay : OsuTestScene
|
|
||||||
{
|
|
||||||
[Test]
|
|
||||||
public void TestDisplay()
|
|
||||||
{
|
|
||||||
AddStep("load displays", () => Child = new FillFlowContainer
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
ChildrenEnumerable = new[]
|
|
||||||
{
|
|
||||||
1.23,
|
|
||||||
2.34,
|
|
||||||
3.45,
|
|
||||||
4.56,
|
|
||||||
5.67,
|
|
||||||
6.78,
|
|
||||||
10.11,
|
|
||||||
}.Select(starRating => new StarRatingDisplay(new StarDifficulty(starRating, 0))
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestChangingStarRatingDisplay()
|
|
||||||
{
|
|
||||||
StarRatingDisplay starRating = null;
|
|
||||||
|
|
||||||
AddStep("load display", () => Child = starRating = new StarRatingDisplay(new StarDifficulty(5.55, 1))
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
Scale = new Vector2(3f),
|
|
||||||
});
|
|
||||||
|
|
||||||
AddRepeatStep("set random value", () =>
|
|
||||||
{
|
|
||||||
starRating.Current.Value = new StarDifficulty(RNG.NextDouble(0.0, 11.0), 1);
|
|
||||||
}, 10);
|
|
||||||
|
|
||||||
AddSliderStep("set exact stars", 0.0, 11.0, 5.55, d =>
|
|
||||||
{
|
|
||||||
if (starRating != null)
|
|
||||||
starRating.Current.Value = new StarDifficulty(d, 1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -32,6 +32,7 @@ namespace osu.Game.Tests.Visual.Settings
|
|||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
public void SetUpSteps()
|
public void SetUpSteps()
|
||||||
{
|
{
|
||||||
|
AddUntilStep("wait for load", () => panel.ChildrenOfType<GlobalKeyBindingsSection>().Any());
|
||||||
AddStep("Scroll to top", () => panel.ChildrenOfType<SettingsPanel.SettingsSectionsContainer>().First().ScrollToTop());
|
AddStep("Scroll to top", () => panel.ChildrenOfType<SettingsPanel.SettingsSectionsContainer>().First().ScrollToTop());
|
||||||
AddWaitStep("wait for scroll", 5);
|
AddWaitStep("wait for scroll", 5);
|
||||||
}
|
}
|
||||||
|
@ -76,5 +76,23 @@ namespace osu.Game.Tests.Visual.Settings
|
|||||||
AddStep("restore default", () => sliderBar.Current.SetDefault());
|
AddStep("restore default", () => sliderBar.Current.SetDefault());
|
||||||
AddUntilStep("restore button hidden", () => restoreDefaultValueButton.Alpha == 0);
|
AddUntilStep("restore button hidden", () => restoreDefaultValueButton.Alpha == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestWarningTextVisibility()
|
||||||
|
{
|
||||||
|
SettingsNumberBox numberBox = null;
|
||||||
|
|
||||||
|
AddStep("create settings item", () => Child = numberBox = new SettingsNumberBox());
|
||||||
|
AddAssert("warning text not created", () => !numberBox.ChildrenOfType<SettingsNoticeText>().Any());
|
||||||
|
|
||||||
|
AddStep("set warning text", () => numberBox.WarningText = "this is a warning!");
|
||||||
|
AddAssert("warning text created", () => numberBox.ChildrenOfType<SettingsNoticeText>().Single().Alpha == 1);
|
||||||
|
|
||||||
|
AddStep("unset warning text", () => numberBox.WarningText = default);
|
||||||
|
AddAssert("warning text hidden", () => numberBox.ChildrenOfType<SettingsNoticeText>().Single().Alpha == 0);
|
||||||
|
|
||||||
|
AddStep("set warning text again", () => numberBox.WarningText = "another warning!");
|
||||||
|
AddAssert("warning text shown again", () => numberBox.ChildrenOfType<SettingsNoticeText>().Single().Alpha == 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Settings
|
namespace osu.Game.Tests.Visual.Settings
|
||||||
@ -11,27 +12,39 @@ namespace osu.Game.Tests.Visual.Settings
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneSettingsPanel : OsuTestScene
|
public class TestSceneSettingsPanel : OsuTestScene
|
||||||
{
|
{
|
||||||
private readonly SettingsPanel settings;
|
private SettingsPanel settings;
|
||||||
private readonly DialogOverlay dialogOverlay;
|
private DialogOverlay dialogOverlay;
|
||||||
|
|
||||||
public TestSceneSettingsPanel()
|
[SetUpSteps]
|
||||||
|
public void SetUpSteps()
|
||||||
{
|
{
|
||||||
settings = new SettingsOverlay
|
AddStep("create settings", () =>
|
||||||
{
|
{
|
||||||
State = { Value = Visibility.Visible }
|
settings?.Expire();
|
||||||
};
|
|
||||||
Add(dialogOverlay = new DialogOverlay
|
Add(settings = new SettingsOverlay
|
||||||
{
|
{
|
||||||
Depth = -1
|
State = { Value = Visibility.Visible }
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ToggleVisibility()
|
||||||
|
{
|
||||||
|
AddWaitStep("wait some", 5);
|
||||||
|
AddToggleStep("toggle editor visibility", visible => settings.ToggleVisibility());
|
||||||
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
Dependencies.Cache(dialogOverlay);
|
Add(dialogOverlay = new DialogOverlay
|
||||||
|
{
|
||||||
|
Depth = -1
|
||||||
|
});
|
||||||
|
|
||||||
Add(settings);
|
Dependencies.Cache(dialogOverlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
@ -65,6 +66,12 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
AddStep("show", () => { infoWedge.Show(); });
|
AddStep("show", () => { infoWedge.Show(); });
|
||||||
|
|
||||||
|
AddSliderStep("change star difficulty", 0, 11.9, 5.55, v =>
|
||||||
|
{
|
||||||
|
foreach (var hasCurrentValue in infoWedge.Info.ChildrenOfType<IHasCurrentValue<StarDifficulty>>())
|
||||||
|
hasCurrentValue.Current.Value = new StarDifficulty(v, 0);
|
||||||
|
});
|
||||||
|
|
||||||
foreach (var rulesetInfo in rulesets.AvailableRulesets)
|
foreach (var rulesetInfo in rulesets.AvailableRulesets)
|
||||||
{
|
{
|
||||||
var instance = rulesetInfo.CreateInstance();
|
var instance = rulesetInfo.CreateInstance();
|
||||||
|
@ -14,7 +14,6 @@ using osu.Game.Rulesets.Catch;
|
|||||||
using osu.Game.Rulesets.Mania;
|
using osu.Game.Rulesets.Mania;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Taiko;
|
using osu.Game.Rulesets.Taiko;
|
||||||
using osu.Game.Tests.Visual.Navigation;
|
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.SongSelect
|
namespace osu.Game.Tests.Visual.SongSelect
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
// 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 NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
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;
|
||||||
@ -174,6 +176,60 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
checkBindableAtValue("Circle Size", null);
|
checkBindableAtValue("Circle Size", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestModSettingChangeTracker()
|
||||||
|
{
|
||||||
|
ModSettingChangeTracker tracker = null;
|
||||||
|
Queue<Mod> settingsChangedQueue = null;
|
||||||
|
|
||||||
|
setBeatmapWithDifficultyParameters(5);
|
||||||
|
|
||||||
|
AddStep("add mod settings change tracker", () =>
|
||||||
|
{
|
||||||
|
settingsChangedQueue = new Queue<Mod>();
|
||||||
|
|
||||||
|
tracker = new ModSettingChangeTracker(modDifficultyAdjust.Yield())
|
||||||
|
{
|
||||||
|
SettingChanged = settingsChangedQueue.Enqueue
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("no settings changed", () => settingsChangedQueue.Count == 0);
|
||||||
|
|
||||||
|
setSliderValue("Circle Size", 3);
|
||||||
|
|
||||||
|
settingsChangedFired();
|
||||||
|
|
||||||
|
setSliderValue("Circle Size", 5);
|
||||||
|
checkBindableAtValue("Circle Size", 5);
|
||||||
|
|
||||||
|
settingsChangedFired();
|
||||||
|
|
||||||
|
AddStep("reset mod settings", () => modDifficultyAdjust.CircleSize.SetDefault());
|
||||||
|
checkBindableAtValue("Circle Size", null);
|
||||||
|
|
||||||
|
settingsChangedFired();
|
||||||
|
|
||||||
|
setExtendedLimits(true);
|
||||||
|
|
||||||
|
settingsChangedFired();
|
||||||
|
|
||||||
|
AddStep("dispose tracker", () =>
|
||||||
|
{
|
||||||
|
tracker.Dispose();
|
||||||
|
tracker = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
void settingsChangedFired()
|
||||||
|
{
|
||||||
|
AddAssert("setting changed event fired", () =>
|
||||||
|
{
|
||||||
|
settingsChangedQueue.Dequeue();
|
||||||
|
return settingsChangedQueue.Count == 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void resetToDefault(string name)
|
private void resetToDefault(string name)
|
||||||
{
|
{
|
||||||
AddStep($"Reset {name} to default", () =>
|
AddStep($"Reset {name} to default", () =>
|
||||||
|
@ -6,6 +6,7 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Colour;
|
using osu.Framework.Graphics.Colour;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -61,10 +62,12 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
));
|
));
|
||||||
AddStep("scroll up", () => triggerUserScroll(1));
|
AddStep("scroll up", () => triggerUserScroll(1));
|
||||||
AddStep("scroll down", () => triggerUserScroll(-1));
|
AddStep("scroll down", () => triggerUserScroll(-1));
|
||||||
|
AddStep("scroll up a bit", () => triggerUserScroll(0.1f));
|
||||||
|
AddStep("scroll down a bit", () => triggerUserScroll(-0.1f));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestCorrectSectionSelected()
|
public void TestCorrectSelectionAndVisibleTop()
|
||||||
{
|
{
|
||||||
const int sections_count = 11;
|
const int sections_count = 11;
|
||||||
float[] alternating = { 0.07f, 0.33f, 0.16f, 0.33f };
|
float[] alternating = { 0.07f, 0.33f, 0.16f, 0.33f };
|
||||||
@ -79,6 +82,12 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
AddStep($"scroll to section {scrollIndex + 1}", () => container.ScrollTo(container.Children[scrollIndex]));
|
AddStep($"scroll to section {scrollIndex + 1}", () => container.ScrollTo(container.Children[scrollIndex]));
|
||||||
AddUntilStep("correct section selected", () => container.SelectedSection.Value == container.Children[scrollIndex]);
|
AddUntilStep("correct section selected", () => container.SelectedSection.Value == container.Children[scrollIndex]);
|
||||||
|
AddUntilStep("section top is visible", () =>
|
||||||
|
{
|
||||||
|
float scrollPosition = container.ChildrenOfType<UserTrackingScrollContainer>().First().Current;
|
||||||
|
float sectionTop = container.Children[scrollIndex].BoundingBox.Top;
|
||||||
|
return scrollPosition < sectionTop;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i < sections_count; i++)
|
for (int i = 1; i < sections_count; i++)
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
// 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.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Utils;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.Drawables;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.UserInterface
|
||||||
|
{
|
||||||
|
public class TestSceneStarRatingDisplay : OsuTestScene
|
||||||
|
{
|
||||||
|
[TestCase(StarRatingDisplaySize.Regular)]
|
||||||
|
[TestCase(StarRatingDisplaySize.Small)]
|
||||||
|
public void TestDisplay(StarRatingDisplaySize size)
|
||||||
|
{
|
||||||
|
AddStep("load displays", () =>
|
||||||
|
{
|
||||||
|
Child = new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Spacing = new Vector2(2f),
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
ChildrenEnumerable = Enumerable.Range(0, 15).Select(i => new FillFlowContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Spacing = new Vector2(2f),
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
ChildrenEnumerable = Enumerable.Range(0, 10).Select(j => new StarRatingDisplay(new StarDifficulty(i * (i >= 11 ? 25f : 1f) + j * 0.1f, 0), size)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSpectrum()
|
||||||
|
{
|
||||||
|
StarRatingDisplay starRating = null;
|
||||||
|
|
||||||
|
AddStep("load display", () => Child = starRating = new StarRatingDisplay(new StarDifficulty(5.55, 1), animated: true)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Scale = new Vector2(3f),
|
||||||
|
});
|
||||||
|
|
||||||
|
AddRepeatStep("set random value", () =>
|
||||||
|
{
|
||||||
|
starRating.Current.Value = new StarDifficulty(RNG.NextDouble(0.0, 11.0), 1);
|
||||||
|
}, 10);
|
||||||
|
|
||||||
|
AddSliderStep("set exact stars", 0.0, 11.0, 5.55, d =>
|
||||||
|
{
|
||||||
|
if (starRating != null)
|
||||||
|
starRating.Current.Value = new StarDifficulty(d, 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ using osu.Framework.Lists;
|
|||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -56,12 +57,28 @@ namespace osu.Game.Beatmaps
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private Bindable<IReadOnlyList<Mod>> currentMods { get; set; }
|
private Bindable<IReadOnlyList<Mod>> currentMods { get; set; }
|
||||||
|
|
||||||
|
private ModSettingChangeTracker modSettingChangeTracker;
|
||||||
|
private ScheduledDelegate debouncedModSettingsChange;
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
currentRuleset.BindValueChanged(_ => updateTrackedBindables());
|
currentRuleset.BindValueChanged(_ => updateTrackedBindables());
|
||||||
currentMods.BindValueChanged(_ => updateTrackedBindables(), true);
|
|
||||||
|
currentMods.BindValueChanged(mods =>
|
||||||
|
{
|
||||||
|
modSettingChangeTracker?.Dispose();
|
||||||
|
|
||||||
|
updateTrackedBindables();
|
||||||
|
|
||||||
|
modSettingChangeTracker = new ModSettingChangeTracker(mods.NewValue);
|
||||||
|
modSettingChangeTracker.SettingChanged += _ =>
|
||||||
|
{
|
||||||
|
debouncedModSettingsChange?.Cancel();
|
||||||
|
debouncedModSettingsChange = Scheduler.AddDelayed(updateTrackedBindables, 100);
|
||||||
|
};
|
||||||
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -84,7 +101,7 @@ namespace osu.Game.Beatmaps
|
|||||||
/// Retrieves a bindable containing the star difficulty of a <see cref="BeatmapInfo"/> with a given <see cref="RulesetInfo"/> and <see cref="Mod"/> combination.
|
/// Retrieves a bindable containing the star difficulty of a <see cref="BeatmapInfo"/> with a given <see cref="RulesetInfo"/> and <see cref="Mod"/> combination.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// The bindable will not update to follow the currently-selected ruleset and mods.
|
/// The bindable will not update to follow the currently-selected ruleset and mods or its settings.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> to get the difficulty of.</param>
|
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> to get the difficulty of.</param>
|
||||||
/// <param name="rulesetInfo">The <see cref="RulesetInfo"/> to get the difficulty with. If <c>null</c>, the <paramref name="beatmapInfo"/>'s ruleset is used.</param>
|
/// <param name="rulesetInfo">The <see cref="RulesetInfo"/> to get the difficulty with. If <c>null</c>, the <paramref name="beatmapInfo"/>'s ruleset is used.</param>
|
||||||
@ -275,6 +292,8 @@ namespace osu.Game.Beatmaps
|
|||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
|
modSettingChangeTracker?.Dispose();
|
||||||
|
|
||||||
cancelTrackedBindableUpdate();
|
cancelTrackedBindableUpdate();
|
||||||
updateScheduler?.Dispose();
|
updateScheduler?.Dispose();
|
||||||
}
|
}
|
||||||
@ -297,7 +316,7 @@ namespace osu.Game.Beatmaps
|
|||||||
public bool Equals(DifficultyCacheLookup other)
|
public bool Equals(DifficultyCacheLookup other)
|
||||||
=> Beatmap.ID == other.Beatmap.ID
|
=> Beatmap.ID == other.Beatmap.ID
|
||||||
&& Ruleset.ID == other.Ruleset.ID
|
&& Ruleset.ID == other.Ruleset.ID
|
||||||
&& OrderedMods.Select(m => m.Acronym).SequenceEqual(other.OrderedMods.Select(m => m.Acronym));
|
&& OrderedMods.SequenceEqual(other.OrderedMods);
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
@ -307,7 +326,7 @@ namespace osu.Game.Beatmaps
|
|||||||
hashCode.Add(Ruleset.ID);
|
hashCode.Add(Ruleset.ID);
|
||||||
|
|
||||||
foreach (var mod in OrderedMods)
|
foreach (var mod in OrderedMods)
|
||||||
hashCode.Add(mod.Acronym);
|
hashCode.Add(mod);
|
||||||
|
|
||||||
return hashCode.ToHashCode();
|
return hashCode.ToHashCode();
|
||||||
}
|
}
|
||||||
|
@ -365,6 +365,10 @@ namespace osu.Game.Beatmaps
|
|||||||
queryable = beatmaps.BeatmapSetsOverview;
|
queryable = beatmaps.BeatmapSetsOverview;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IncludedDetails.AllButRuleset:
|
||||||
|
queryable = beatmaps.BeatmapSetsWithoutRuleset;
|
||||||
|
break;
|
||||||
|
|
||||||
case IncludedDetails.AllButFiles:
|
case IncludedDetails.AllButFiles:
|
||||||
queryable = beatmaps.BeatmapSetsWithoutFiles;
|
queryable = beatmaps.BeatmapSetsWithoutFiles;
|
||||||
break;
|
break;
|
||||||
@ -384,8 +388,33 @@ namespace osu.Game.Beatmaps
|
|||||||
/// Perform a lookup query on available <see cref="BeatmapSetInfo"/>s.
|
/// Perform a lookup query on available <see cref="BeatmapSetInfo"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="query">The query.</param>
|
/// <param name="query">The query.</param>
|
||||||
|
/// <param name="includes">The level of detail to include in the returned objects.</param>
|
||||||
/// <returns>Results from the provided query.</returns>
|
/// <returns>Results from the provided query.</returns>
|
||||||
public IEnumerable<BeatmapSetInfo> QueryBeatmapSets(Expression<Func<BeatmapSetInfo, bool>> query) => beatmaps.ConsumableItems.AsNoTracking().Where(query);
|
public IEnumerable<BeatmapSetInfo> QueryBeatmapSets(Expression<Func<BeatmapSetInfo, bool>> query, IncludedDetails includes = IncludedDetails.All)
|
||||||
|
{
|
||||||
|
IQueryable<BeatmapSetInfo> queryable;
|
||||||
|
|
||||||
|
switch (includes)
|
||||||
|
{
|
||||||
|
case IncludedDetails.Minimal:
|
||||||
|
queryable = beatmaps.BeatmapSetsOverview;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IncludedDetails.AllButRuleset:
|
||||||
|
queryable = beatmaps.BeatmapSetsWithoutRuleset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IncludedDetails.AllButFiles:
|
||||||
|
queryable = beatmaps.BeatmapSetsWithoutFiles;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
queryable = beatmaps.ConsumableItems;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryable.AsNoTracking().Where(query);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Perform a lookup query on available <see cref="BeatmapInfo"/>s.
|
/// Perform a lookup query on available <see cref="BeatmapInfo"/>s.
|
||||||
@ -554,6 +583,11 @@ namespace osu.Game.Beatmaps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
AllButFiles,
|
AllButFiles,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Include everything except ruleset. Used for cases where we aren't sure the ruleset is present but still want to consume the beatmap.
|
||||||
|
/// </summary>
|
||||||
|
AllButRuleset,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Include everything.
|
/// Include everything.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -92,6 +92,13 @@ namespace osu.Game.Beatmaps
|
|||||||
.Include(s => s.Beatmaps)
|
.Include(s => s.Beatmaps)
|
||||||
.AsNoTracking();
|
.AsNoTracking();
|
||||||
|
|
||||||
|
public IQueryable<BeatmapSetInfo> BeatmapSetsWithoutRuleset => ContextFactory.Get().BeatmapSetInfo
|
||||||
|
.Include(s => s.Metadata)
|
||||||
|
.Include(s => s.Files).ThenInclude(f => f.FileInfo)
|
||||||
|
.Include(s => s.Beatmaps).ThenInclude(b => b.BaseDifficulty)
|
||||||
|
.Include(s => s.Beatmaps).ThenInclude(b => b.Metadata)
|
||||||
|
.AsNoTracking();
|
||||||
|
|
||||||
public IQueryable<BeatmapSetInfo> BeatmapSetsWithoutFiles => ContextFactory.Get().BeatmapSetInfo
|
public IQueryable<BeatmapSetInfo> BeatmapSetsWithoutFiles => ContextFactory.Get().BeatmapSetInfo
|
||||||
.Include(s => s.Metadata)
|
.Include(s => s.Metadata)
|
||||||
.Include(s => s.Beatmaps).ThenInclude(s => s.Ruleset)
|
.Include(s => s.Beatmaps).ThenInclude(s => s.Ruleset)
|
||||||
|
168
osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs
Normal file
168
osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
// 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.Bindables;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Beatmaps.Drawables
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A pill that displays the star rating of a beatmap.
|
||||||
|
/// </summary>
|
||||||
|
public class StarRatingDisplay : CompositeDrawable, IHasCurrentValue<StarDifficulty>
|
||||||
|
{
|
||||||
|
private readonly bool animated;
|
||||||
|
private readonly Box background;
|
||||||
|
private readonly SpriteIcon starIcon;
|
||||||
|
private readonly OsuSpriteText starsText;
|
||||||
|
|
||||||
|
private readonly BindableWithCurrent<StarDifficulty> current = new BindableWithCurrent<StarDifficulty>();
|
||||||
|
|
||||||
|
public Bindable<StarDifficulty> Current
|
||||||
|
{
|
||||||
|
get => current.Current;
|
||||||
|
set => current.Current = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly Bindable<double> displayedStars = new BindableDouble();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The currently displayed stars of this display wrapped in a bindable.
|
||||||
|
/// This bindable gets transformed on change rather than instantaneous, if animation is enabled.
|
||||||
|
/// </summary>
|
||||||
|
public IBindable<double> DisplayedStars => displayedStars;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private OsuColour colours { get; set; }
|
||||||
|
|
||||||
|
[Resolved(canBeNull: true)]
|
||||||
|
private OverlayColourProvider colourProvider { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="StarRatingDisplay"/> using an already computed <see cref="StarDifficulty"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="starDifficulty">The already computed <see cref="StarDifficulty"/> to display.</param>
|
||||||
|
/// <param name="size">The size of the star rating display.</param>
|
||||||
|
/// <param name="animated">Whether the star rating display will perform transforms on change rather than updating instantaneously.</param>
|
||||||
|
public StarRatingDisplay(StarDifficulty starDifficulty, StarRatingDisplaySize size = StarRatingDisplaySize.Regular, bool animated = false)
|
||||||
|
{
|
||||||
|
this.animated = animated;
|
||||||
|
|
||||||
|
Current.Value = starDifficulty;
|
||||||
|
|
||||||
|
AutoSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
MarginPadding margin = default;
|
||||||
|
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case StarRatingDisplaySize.Small:
|
||||||
|
margin = new MarginPadding { Horizontal = 7f };
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StarRatingDisplaySize.Range:
|
||||||
|
margin = new MarginPadding { Horizontal = 8f };
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StarRatingDisplaySize.Regular:
|
||||||
|
margin = new MarginPadding { Horizontal = 8f, Vertical = 2f };
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
InternalChild = new CircularContainer
|
||||||
|
{
|
||||||
|
Masking = true,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
background = new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
new GridContainer
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Margin = margin,
|
||||||
|
ColumnDimensions = new[]
|
||||||
|
{
|
||||||
|
new Dimension(GridSizeMode.AutoSize),
|
||||||
|
new Dimension(GridSizeMode.Absolute, 3f),
|
||||||
|
new Dimension(GridSizeMode.AutoSize, minSize: 25f),
|
||||||
|
},
|
||||||
|
RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) },
|
||||||
|
Content = new[]
|
||||||
|
{
|
||||||
|
new[]
|
||||||
|
{
|
||||||
|
starIcon = new SpriteIcon
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Icon = FontAwesome.Solid.Star,
|
||||||
|
Size = new Vector2(8f),
|
||||||
|
},
|
||||||
|
Empty(),
|
||||||
|
starsText = new OsuSpriteText
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Margin = new MarginPadding { Bottom = 1.5f },
|
||||||
|
// todo: this should be size: 12f, but to match up with the design, it needs to be 14.4f
|
||||||
|
// see https://github.com/ppy/osu-framework/issues/3271.
|
||||||
|
Font = OsuFont.Torus.With(size: 14.4f, weight: FontWeight.Bold),
|
||||||
|
Shadow = false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
Current.BindValueChanged(c =>
|
||||||
|
{
|
||||||
|
if (animated)
|
||||||
|
this.TransformBindableTo(displayedStars, c.NewValue.Stars, 750, Easing.OutQuint);
|
||||||
|
else
|
||||||
|
displayedStars.Value = c.NewValue.Stars;
|
||||||
|
});
|
||||||
|
|
||||||
|
displayedStars.Value = Current.Value.Stars;
|
||||||
|
|
||||||
|
displayedStars.BindValueChanged(s =>
|
||||||
|
{
|
||||||
|
starsText.Text = s.NewValue.ToLocalisableString("0.00");
|
||||||
|
|
||||||
|
background.Colour = colours.ForStarDifficulty(s.NewValue);
|
||||||
|
|
||||||
|
starIcon.Colour = s.NewValue >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4Extensions.FromHex("303d47");
|
||||||
|
starsText.Colour = s.NewValue >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4.Black.Opacity(0.75f);
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum StarRatingDisplaySize
|
||||||
|
{
|
||||||
|
Small,
|
||||||
|
Range,
|
||||||
|
Regular,
|
||||||
|
}
|
||||||
|
}
|
@ -101,7 +101,7 @@ namespace osu.Game.Configuration
|
|||||||
SetDefault(OsuSetting.HitLighting, true);
|
SetDefault(OsuSetting.HitLighting, true);
|
||||||
|
|
||||||
SetDefault(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Always);
|
SetDefault(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Always);
|
||||||
SetDefault(OsuSetting.ShowDifficultyGraph, true);
|
SetDefault(OsuSetting.ShowProgressGraph, true);
|
||||||
SetDefault(OsuSetting.ShowHealthDisplayWhenCantFail, true);
|
SetDefault(OsuSetting.ShowHealthDisplayWhenCantFail, true);
|
||||||
SetDefault(OsuSetting.FadePlayfieldWhenHealthLow, true);
|
SetDefault(OsuSetting.FadePlayfieldWhenHealthLow, true);
|
||||||
SetDefault(OsuSetting.KeyOverlay, false);
|
SetDefault(OsuSetting.KeyOverlay, false);
|
||||||
@ -201,6 +201,8 @@ namespace osu.Game.Configuration
|
|||||||
public Func<GlobalAction, string> LookupKeyBindings { get; set; }
|
public Func<GlobalAction, string> LookupKeyBindings { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IMPORTANT: These are used in user configuration files.
|
||||||
|
// The naming of these keys should not be changed once they are deployed in a release, unless migration logic is also added.
|
||||||
public enum OsuSetting
|
public enum OsuSetting
|
||||||
{
|
{
|
||||||
Ruleset,
|
Ruleset,
|
||||||
@ -217,7 +219,7 @@ namespace osu.Game.Configuration
|
|||||||
AlwaysPlayFirstComboBreak,
|
AlwaysPlayFirstComboBreak,
|
||||||
FloatingComments,
|
FloatingComments,
|
||||||
HUDVisibilityMode,
|
HUDVisibilityMode,
|
||||||
ShowDifficultyGraph,
|
ShowProgressGraph,
|
||||||
ShowHealthDisplayWhenCantFail,
|
ShowHealthDisplayWhenCantFail,
|
||||||
FadePlayfieldWhenHealthLow,
|
FadePlayfieldWhenHealthLow,
|
||||||
MouseDisableButtons,
|
MouseDisableButtons,
|
||||||
|
@ -36,6 +36,11 @@ namespace osu.Game.Database
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IQueryable<T> ConsumableItems => AddIncludesForConsumption(ContextFactory.Get().Set<T>());
|
public IQueryable<T> ConsumableItems => AddIncludesForConsumption(ContextFactory.Get().Set<T>());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Access barebones items with no includes.
|
||||||
|
/// </summary>
|
||||||
|
public IQueryable<T> Items => ContextFactory.Get().Set<T>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add a <typeparamref name="T"/> to the database.
|
/// Add a <typeparamref name="T"/> to the database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -22,7 +22,8 @@ namespace osu.Game.Graphics.Containers
|
|||||||
where T : Drawable
|
where T : Drawable
|
||||||
{
|
{
|
||||||
public Bindable<T> SelectedSection { get; } = new Bindable<T>();
|
public Bindable<T> SelectedSection { get; } = new Bindable<T>();
|
||||||
private Drawable lastClickedSection;
|
|
||||||
|
private T lastClickedSection;
|
||||||
|
|
||||||
public Drawable ExpandableHeader
|
public Drawable ExpandableHeader
|
||||||
{
|
{
|
||||||
@ -144,10 +145,25 @@ namespace osu.Game.Graphics.Containers
|
|||||||
footerHeight = null;
|
footerHeight = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ScrollTo(Drawable section)
|
public void ScrollTo(Drawable target)
|
||||||
{
|
{
|
||||||
lastClickedSection = section;
|
lastKnownScroll = null;
|
||||||
scrollContainer.ScrollTo(scrollContainer.GetChildPosInContent(section) - scrollContainer.DisplayableContent * scroll_y_centre - (FixedHeader?.BoundingBox.Height ?? 0));
|
|
||||||
|
float fixedHeaderSize = FixedHeader?.BoundingBox.Height ?? 0;
|
||||||
|
|
||||||
|
// implementation similar to ScrollIntoView but a bit more nuanced.
|
||||||
|
float top = scrollContainer.GetChildPosInContent(target);
|
||||||
|
|
||||||
|
float bottomScrollExtent = scrollContainer.ScrollableExtent - fixedHeaderSize;
|
||||||
|
float scrollTarget = top - fixedHeaderSize - scrollContainer.DisplayableContent * scroll_y_centre;
|
||||||
|
|
||||||
|
if (scrollTarget > bottomScrollExtent)
|
||||||
|
scrollContainer.ScrollToEnd();
|
||||||
|
else
|
||||||
|
scrollContainer.ScrollTo(scrollTarget);
|
||||||
|
|
||||||
|
if (target is T section)
|
||||||
|
lastClickedSection = section;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ScrollToTop() => scrollContainer.ScrollTo(0);
|
public void ScrollToTop() => scrollContainer.ScrollTo(0);
|
||||||
@ -170,13 +186,22 @@ namespace osu.Game.Graphics.Containers
|
|||||||
|
|
||||||
if (source == InvalidationSource.Child && (invalidation & Invalidation.DrawSize) != 0)
|
if (source == InvalidationSource.Child && (invalidation & Invalidation.DrawSize) != 0)
|
||||||
{
|
{
|
||||||
lastKnownScroll = null;
|
InvalidateScrollPosition();
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void InvalidateScrollPosition()
|
||||||
|
{
|
||||||
|
Schedule(() =>
|
||||||
|
{
|
||||||
|
lastKnownScroll = null;
|
||||||
|
lastClickedSection = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
protected override void UpdateAfterChildren()
|
protected override void UpdateAfterChildren()
|
||||||
{
|
{
|
||||||
base.UpdateAfterChildren();
|
base.UpdateAfterChildren();
|
||||||
@ -224,15 +249,19 @@ namespace osu.Game.Graphics.Containers
|
|||||||
|
|
||||||
float scrollCentre = fixedHeaderSize + scrollContainer.DisplayableContent * scroll_y_centre + selectionLenienceAboveSection;
|
float scrollCentre = fixedHeaderSize + scrollContainer.DisplayableContent * scroll_y_centre + selectionLenienceAboveSection;
|
||||||
|
|
||||||
if (Precision.AlmostBigger(0, scrollContainer.Current))
|
var presentChildren = Children.Where(c => c.IsPresent);
|
||||||
SelectedSection.Value = lastClickedSection as T ?? Children.FirstOrDefault();
|
|
||||||
|
if (lastClickedSection != null)
|
||||||
|
SelectedSection.Value = lastClickedSection;
|
||||||
|
else if (Precision.AlmostBigger(0, scrollContainer.Current))
|
||||||
|
SelectedSection.Value = presentChildren.FirstOrDefault();
|
||||||
else if (Precision.AlmostBigger(scrollContainer.Current, scrollContainer.ScrollableExtent))
|
else if (Precision.AlmostBigger(scrollContainer.Current, scrollContainer.ScrollableExtent))
|
||||||
SelectedSection.Value = lastClickedSection as T ?? Children.LastOrDefault();
|
SelectedSection.Value = presentChildren.LastOrDefault();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SelectedSection.Value = Children
|
SelectedSection.Value = presentChildren
|
||||||
.TakeWhile(section => scrollContainer.GetChildPosInContent(section) - currentScroll - scrollCentre <= 0)
|
.TakeWhile(section => scrollContainer.GetChildPosInContent(section) - currentScroll - scrollCentre <= 0)
|
||||||
.LastOrDefault() ?? Children.FirstOrDefault();
|
.LastOrDefault() ?? presentChildren.FirstOrDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,12 @@ namespace osu.Game.Graphics.Containers
|
|||||||
base.OnUserScroll(value, animated, distanceDecay);
|
base.OnUserScroll(value, animated, distanceDecay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public new void ScrollIntoView(Drawable target, bool animated = true)
|
||||||
|
{
|
||||||
|
UserScrolling = false;
|
||||||
|
base.ScrollIntoView(target, animated);
|
||||||
|
}
|
||||||
|
|
||||||
public new void ScrollTo(float value, bool animated = true, double? distanceDecay = null)
|
public new void ScrollTo(float value, bool animated = true, double? distanceDecay = null)
|
||||||
{
|
{
|
||||||
UserScrolling = false;
|
UserScrolling = false;
|
||||||
|
@ -22,9 +22,14 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
public void TakeFocus()
|
public void TakeFocus()
|
||||||
{
|
{
|
||||||
if (allowImmediateFocus) GetContainingInputManager().ChangeFocus(this);
|
if (!allowImmediateFocus)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Scheduler.Add(() => GetContainingInputManager().ChangeFocus(this), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public new void KillFocus() => base.KillFocus();
|
||||||
|
|
||||||
public bool HoldFocus
|
public bool HoldFocus
|
||||||
{
|
{
|
||||||
get => allowImmediateFocus && focus;
|
get => allowImmediateFocus && focus;
|
||||||
|
@ -6,6 +6,7 @@ using osuTK;
|
|||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Effects;
|
using osu.Framework.Graphics.Effects;
|
||||||
@ -57,18 +58,13 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
EdgeEffect = new EdgeEffectParameters
|
EdgeEffect = new EdgeEffectParameters
|
||||||
{
|
{
|
||||||
Colour = GlowColour,
|
Colour = GlowColour.Opacity(0),
|
||||||
Type = EdgeEffectType.Glow,
|
Type = EdgeEffectType.Glow,
|
||||||
Radius = 10,
|
Radius = 10,
|
||||||
Roundness = 8,
|
Roundness = 8,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
FadeEdgeEffectTo(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool glowing;
|
private bool glowing;
|
||||||
|
|
||||||
public bool Glowing
|
public bool Glowing
|
||||||
@ -153,7 +149,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
glowColour = value;
|
glowColour = value;
|
||||||
|
|
||||||
var effect = EdgeEffect;
|
var effect = EdgeEffect;
|
||||||
effect.Colour = value;
|
effect.Colour = Glowing ? value : value.Opacity(0);
|
||||||
EdgeEffect = effect;
|
EdgeEffect = effect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
public Color4 BackgroundColour
|
public Color4 BackgroundColour
|
||||||
{
|
{
|
||||||
|
get => backgroundColour ?? Color4.White;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
backgroundColour = value;
|
backgroundColour = value;
|
||||||
|
@ -69,6 +69,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
BackgroundColour = Color4.Black.Opacity(0.5f);
|
BackgroundColour = Color4.Black.Opacity(0.5f);
|
||||||
|
|
||||||
MaskingContainer.CornerRadius = corner_radius;
|
MaskingContainer.CornerRadius = corner_radius;
|
||||||
|
Alpha = 0;
|
||||||
|
|
||||||
// todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring
|
// todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring
|
||||||
ItemsContainer.Padding = new MarginPadding(5);
|
ItemsContainer.Padding = new MarginPadding(5);
|
||||||
@ -94,9 +95,11 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
protected override void AnimateClose()
|
protected override void AnimateClose()
|
||||||
{
|
{
|
||||||
this.FadeOut(300, Easing.OutQuint);
|
|
||||||
if (wasOpened)
|
if (wasOpened)
|
||||||
|
{
|
||||||
|
this.FadeOut(300, Easing.OutQuint);
|
||||||
sampleClose?.Play();
|
sampleClose?.Play();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring
|
// todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring
|
||||||
|
@ -90,6 +90,7 @@ namespace osu.Game.Input.Bindings
|
|||||||
new KeyBinding(InputKey.Left, GlobalAction.SeekReplayBackward),
|
new KeyBinding(InputKey.Left, GlobalAction.SeekReplayBackward),
|
||||||
new KeyBinding(InputKey.Right, GlobalAction.SeekReplayForward),
|
new KeyBinding(InputKey.Right, GlobalAction.SeekReplayForward),
|
||||||
new KeyBinding(InputKey.Control, GlobalAction.HoldForHUD),
|
new KeyBinding(InputKey.Control, GlobalAction.HoldForHUD),
|
||||||
|
new KeyBinding(InputKey.Tab, GlobalAction.ToggleChatFocus),
|
||||||
};
|
};
|
||||||
|
|
||||||
public IEnumerable<KeyBinding> SongSelectKeyBindings => new[]
|
public IEnumerable<KeyBinding> SongSelectKeyBindings => new[]
|
||||||
@ -280,5 +281,8 @@ namespace osu.Game.Input.Bindings
|
|||||||
|
|
||||||
[Description("Seek replay backward")]
|
[Description("Seek replay backward")]
|
||||||
SeekReplayBackward,
|
SeekReplayBackward,
|
||||||
|
|
||||||
|
[Description("Toggle chat focus")]
|
||||||
|
ToggleChatFocus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ using osu.Framework.Configuration;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
namespace osu.Game.Input
|
namespace osu.Game.Input
|
||||||
{
|
{
|
||||||
@ -24,14 +25,14 @@ namespace osu.Game.Input
|
|||||||
private IBindable<bool> localUserPlaying;
|
private IBindable<bool> localUserPlaying;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGame game, FrameworkConfigManager frameworkConfigManager, OsuConfigManager osuConfigManager)
|
private void load(ILocalUserPlayInfo localUserInfo, FrameworkConfigManager frameworkConfigManager, OsuConfigManager osuConfigManager)
|
||||||
{
|
{
|
||||||
frameworkConfineMode = frameworkConfigManager.GetBindable<ConfineMouseMode>(FrameworkSetting.ConfineMouseMode);
|
frameworkConfineMode = frameworkConfigManager.GetBindable<ConfineMouseMode>(FrameworkSetting.ConfineMouseMode);
|
||||||
frameworkWindowMode = frameworkConfigManager.GetBindable<WindowMode>(FrameworkSetting.WindowMode);
|
frameworkWindowMode = frameworkConfigManager.GetBindable<WindowMode>(FrameworkSetting.WindowMode);
|
||||||
frameworkWindowMode.BindValueChanged(_ => updateConfineMode());
|
frameworkWindowMode.BindValueChanged(_ => updateConfineMode());
|
||||||
|
|
||||||
osuConfineMode = osuConfigManager.GetBindable<OsuConfineMouseMode>(OsuSetting.ConfineMouseMode);
|
osuConfineMode = osuConfigManager.GetBindable<OsuConfineMouseMode>(OsuSetting.ConfineMouseMode);
|
||||||
localUserPlaying = game.LocalUserPlaying.GetBoundCopy();
|
localUserPlaying = localUserInfo.IsPlaying.GetBoundCopy();
|
||||||
|
|
||||||
osuConfineMode.ValueChanged += _ => updateConfineMode();
|
osuConfineMode.ValueChanged += _ => updateConfineMode();
|
||||||
localUserPlaying.BindValueChanged(_ => updateConfineMode(), true);
|
localUserPlaying.BindValueChanged(_ => updateConfineMode(), true);
|
||||||
|
64
osu.Game/Localisation/AudioSettingsStrings.cs
Normal file
64
osu.Game/Localisation/AudioSettingsStrings.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// 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.Localisation;
|
||||||
|
|
||||||
|
namespace osu.Game.Localisation
|
||||||
|
{
|
||||||
|
public static class AudioSettingsStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.AudioSettings";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Audio"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AudioSectionHeader => new TranslatableString(getKey(@"audio_section_header"), @"Audio");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Devices"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AudioDevicesHeader => new TranslatableString(getKey(@"audio_devices_header"), @"Devices");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Volume"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString VolumeHeader => new TranslatableString(getKey(@"volume_header"), @"Volume");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Master"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString MasterVolume => new TranslatableString(getKey(@"master_volume"), @"Master");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Master (window inactive)"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString MasterVolumeInactive => new TranslatableString(getKey(@"master_volume_inactive"), @"Master (window inactive)");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Effect"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString EffectVolume => new TranslatableString(getKey(@"effect_volume"), @"Effect");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Music"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString MusicVolume => new TranslatableString(getKey(@"music_volume"), @"Music");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Offset Adjustment"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString OffsetHeader => new TranslatableString(getKey(@"offset_header"), @"Offset Adjustment");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Audio offset"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AudioOffset => new TranslatableString(getKey(@"audio_offset"), @"Audio offset");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Offset wizard"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString OffsetWizard => new TranslatableString(getKey(@"offset_wizard"), @"Offset wizard");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
@ -14,11 +14,21 @@ namespace osu.Game.Localisation
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString Cancel => new TranslatableString(getKey(@"cancel"), @"Cancel");
|
public static LocalisableString Cancel => new TranslatableString(getKey(@"cancel"), @"Cancel");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Clear"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString Clear => new TranslatableString(getKey(@"clear"), @"Clear");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Enabled"
|
/// "Enabled"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LocalisableString Enabled => new TranslatableString(getKey(@"enabled"), @"Enabled");
|
public static LocalisableString Enabled => new TranslatableString(getKey(@"enabled"), @"Enabled");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Default"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString Default => new TranslatableString(getKey(@"default"), @"Default");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// "Width"
|
/// "Width"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
49
osu.Game/Localisation/DebugSettingsStrings.cs
Normal file
49
osu.Game/Localisation/DebugSettingsStrings.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// 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.Localisation;
|
||||||
|
|
||||||
|
namespace osu.Game.Localisation
|
||||||
|
{
|
||||||
|
public static class DebugSettingsStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.DebugSettings";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Debug"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString DebugSectionHeader => new TranslatableString(getKey(@"debug_section_header"), @"Debug");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "General"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString GeneralHeader => new TranslatableString(getKey(@"general_header"), @"General");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Show log overlay"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShowLogOverlay => new TranslatableString(getKey(@"show_log_overlay"), @"Show log overlay");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Bypass front-to-back render pass"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString BypassFrontToBackPass => new TranslatableString(getKey(@"bypass_front_to_back_pass"), @"Bypass front-to-back render pass");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Import files"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ImportFiles => new TranslatableString(getKey(@"import_files"), @"Import files");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Memory"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString MemoryHeader => new TranslatableString(getKey(@"memory_header"), @"Memory");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Clear all caches"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ClearAllCaches => new TranslatableString(getKey(@"clear_all_caches"), @"Clear all caches");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
94
osu.Game/Localisation/GameplaySettingsStrings.cs
Normal file
94
osu.Game/Localisation/GameplaySettingsStrings.cs
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// 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.Localisation;
|
||||||
|
|
||||||
|
namespace osu.Game.Localisation
|
||||||
|
{
|
||||||
|
public static class GameplaySettingsStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.GameplaySettings";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Gameplay"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString GameplaySectionHeader => new TranslatableString(getKey(@"gameplay_section_header"), @"Gameplay");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "General"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString GeneralHeader => new TranslatableString(getKey(@"general_header"), @"General");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Background dim"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString BackgroundDim => new TranslatableString(getKey(@"dim"), @"Background dim");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Background blur"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString BackgroundBlur => new TranslatableString(getKey(@"blur"), @"Background blur");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Lighten playfield during breaks"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString LightenDuringBreaks => new TranslatableString(getKey(@"lighten_during_breaks"), @"Lighten playfield during breaks");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "HUD overlay visibility mode"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString HUDVisibilityMode => new TranslatableString(getKey(@"hud_visibility_mode"), @"HUD overlay visibility mode");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Show difficulty graph on progress bar"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShowDifficultyGraph => new TranslatableString(getKey(@"show_difficulty_graph"), @"Show difficulty graph on progress bar");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Show health display even when you can't fail"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShowHealthDisplayWhenCantFail => new TranslatableString(getKey(@"show_health_display_when_cant_fail"), @"Show health display even when you can't fail");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Fade playfield to red when health is low"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString FadePlayfieldWhenHealthLow => new TranslatableString(getKey(@"fade_playfield_when_health_low"), @"Fade playfield to red when health is low");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Always show key overlay"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AlwaysShowKeyOverlay => new TranslatableString(getKey(@"key_overlay"), @"Always show key overlay");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Positional hitsounds"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString PositionalHitsounds => new TranslatableString(getKey(@"positional_hitsounds"), @"Positional hitsounds");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Always play first combo break sound"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AlwaysPlayFirstComboBreak => new TranslatableString(getKey(@"always_play_first_combo_break"), @"Always play first combo break sound");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Score display mode"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ScoreDisplayMode => new TranslatableString(getKey(@"score_display_mode"), @"Score display mode");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Disable Windows key during gameplay"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString DisableWinKey => new TranslatableString(getKey(@"disable_win_key"), @"Disable Windows key during gameplay");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Mods"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ModsHeader => new TranslatableString(getKey(@"mods_header"), @"Mods");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Increase visibility of first object when visual impairment mods are enabled"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString IncreaseFirstObjectVisibility => new TranslatableString(getKey(@"increase_first_object_visibility"), @"Increase visibility of first object when visual impairment mods are enabled");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
59
osu.Game/Localisation/GeneralSettingsStrings.cs
Normal file
59
osu.Game/Localisation/GeneralSettingsStrings.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// 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.Localisation;
|
||||||
|
|
||||||
|
namespace osu.Game.Localisation
|
||||||
|
{
|
||||||
|
public static class GeneralSettingsStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.GeneralSettings";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "General"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString GeneralSectionHeader => new TranslatableString(getKey(@"general_section_header"), @"General");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Language"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString LanguageHeader => new TranslatableString(getKey(@"language_header"), @"Language");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Language"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString LanguageDropdown => new TranslatableString(getKey(@"language_dropdown"), @"Language");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Prefer metadata in original language"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString PreferOriginalMetadataLanguage => new TranslatableString(getKey(@"prefer_original"), @"Prefer metadata in original language");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Updates"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString UpdateHeader => new TranslatableString(getKey(@"update_header"), @"Updates");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Release stream"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ReleaseStream => new TranslatableString(getKey(@"release_stream"), @"Release stream");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Check for updates"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString CheckUpdate => new TranslatableString(getKey(@"check_update"), @"Check for updates");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Open osu! folder"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString OpenOsuFolder => new TranslatableString(getKey(@"open_osu_folder"), @"Open osu! folder");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Change folder location..."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ChangeFolderLocation => new TranslatableString(getKey(@"change_folder_location"), @"Change folder location...");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
119
osu.Game/Localisation/GraphicsSettingsStrings.cs
Normal file
119
osu.Game/Localisation/GraphicsSettingsStrings.cs
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// 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.Localisation;
|
||||||
|
|
||||||
|
namespace osu.Game.Localisation
|
||||||
|
{
|
||||||
|
public static class GraphicsSettingsStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.GraphicsSettings";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Graphics"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString GraphicsSectionHeader => new TranslatableString(getKey(@"graphics_section_header"), @"Graphics");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Renderer"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString RendererHeader => new TranslatableString(getKey(@"renderer_header"), @"Renderer");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Frame limiter"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString FrameLimiter => new TranslatableString(getKey(@"frame_limiter"), @"Frame limiter");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Threading mode"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ThreadingMode => new TranslatableString(getKey(@"threading_mode"), @"Threading mode");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Show FPS"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShowFPS => new TranslatableString(getKey(@"show_fps"), @"Show FPS");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Using unlimited frame limiter can lead to stutters, bad performance and overheating. It will not improve perceived latency. "2x refresh rate" is recommended."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString UnlimitedFramesNote => new TranslatableString(getKey(@"unlimited_frames_note"), @"Using unlimited frame limiter can lead to stutters, bad performance and overheating. It will not improve perceived latency. ""2x refresh rate"" is recommended.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Layout"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString LayoutHeader => new TranslatableString(getKey(@"layout_header"), @"Layout");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Screen mode"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ScreenMode => new TranslatableString(getKey(@"screen_mode"), @"Screen mode");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Resolution"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString Resolution => new TranslatableString(getKey(@"resolution"), @"Resolution");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "UI scaling"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString UIScaling => new TranslatableString(getKey(@"ui_scaling"), @"UI scaling");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Screen scaling"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ScreenScaling => new TranslatableString(getKey(@"screen_scaling"), @"Screen scaling");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Horizontal position"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString HorizontalPosition => new TranslatableString(getKey(@"horizontal_position"), @"Horizontal position");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Vertical position"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString VerticalPosition => new TranslatableString(getKey(@"vertical_position"), @"Vertical position");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Horizontal scale"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString HorizontalScale => new TranslatableString(getKey(@"horizontal_scale"), @"Horizontal scale");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Vertical scale"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString VerticalScale => new TranslatableString(getKey(@"vertical_scale"), @"Vertical scale");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Running without fullscreen mode will increase your input latency!"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString NotFullscreenNote => new TranslatableString(getKey(@"not_fullscreen_note"), @"Running without fullscreen mode will increase your input latency!");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Detail Settings"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString DetailSettingsHeader => new TranslatableString(getKey(@"detail_settings_header"), @"Detail Settings");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Storyboard / video"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString StoryboardVideo => new TranslatableString(getKey(@"storyboard_video"), @"Storyboard / video");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Hit lighting"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString HitLighting => new TranslatableString(getKey(@"hit_lighting"), @"Hit lighting");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Screenshot format"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ScreenshotFormat => new TranslatableString(getKey(@"screenshot_format"), @"Screenshot format");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Show menu cursor in screenshots"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShowCursorInScreenshots => new TranslatableString(getKey(@"show_cursor_in_screenshots"), @"Show menu cursor in screenshots");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
59
osu.Game/Localisation/InputSettingsStrings.cs
Normal file
59
osu.Game/Localisation/InputSettingsStrings.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// 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.Localisation;
|
||||||
|
|
||||||
|
namespace osu.Game.Localisation
|
||||||
|
{
|
||||||
|
public static class InputSettingsStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.InputSettings";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Input"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString InputSectionHeader => new TranslatableString(getKey(@"input_section_header"), @"Input");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Global"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString GlobalKeyBindingHeader => new TranslatableString(getKey(@"global_key_binding_header"), @"Global");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Song Select"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString SongSelectSection => new TranslatableString(getKey(@"song_select_section"), @"Song Select");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "In Game"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString InGameSection => new TranslatableString(getKey(@"in_game_section"), @"In Game");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Audio"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AudioSection => new TranslatableString(getKey(@"audio_section"), @"Audio");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Editor"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString EditorSection => new TranslatableString(getKey(@"editor_section"), @"Editor");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Reset all bindings in section"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ResetSectionButton => new TranslatableString(getKey(@"reset_section_button"), @"Reset all bindings in section");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "key configuration"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString KeyBindingPanelHeader => new TranslatableString(getKey(@"key_binding_panel_header"), @"key configuration");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Customise your keys!"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString KeyBindingPanelDescription => new TranslatableString(getKey(@"key_binding_panel_description"), @"Customise your keys!");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
74
osu.Game/Localisation/MaintenanceSettingsStrings.cs
Normal file
74
osu.Game/Localisation/MaintenanceSettingsStrings.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 osu.Framework.Localisation;
|
||||||
|
|
||||||
|
namespace osu.Game.Localisation
|
||||||
|
{
|
||||||
|
public static class MaintenanceSettingsStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.MaintenanceSettings";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Maintenance"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString MaintenanceSectionHeader => new TranslatableString(getKey(@"maintenance_section_header"), @"Maintenance");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Select directory"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString SelectDirectory => new TranslatableString(getKey(@"select_directory"), @"Select directory");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Import beatmaps from stable"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ImportBeatmapsFromStable => new TranslatableString(getKey(@"import_beatmaps_from_stable"), @"Import beatmaps from stable");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Delete ALL beatmaps"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString DeleteAllBeatmaps => new TranslatableString(getKey(@"delete_all_beatmaps"), @"Delete ALL beatmaps");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Import scores from stable"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ImportScoresFromStable => new TranslatableString(getKey(@"import_scores_from_stable"), @"Import scores from stable");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Delete ALL scores"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString DeleteAllScores => new TranslatableString(getKey(@"delete_all_scores"), @"Delete ALL scores");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Import skins from stable"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ImportSkinsFromStable => new TranslatableString(getKey(@"import_skins_from_stable"), @"Import skins from stable");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Delete ALL skins"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString DeleteAllSkins => new TranslatableString(getKey(@"delete_all_skins"), @"Delete ALL skins");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Import collections from stable"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ImportCollectionsFromStable => new TranslatableString(getKey(@"import_collections_from_stable"), @"Import collections from stable");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Delete ALL collections"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString DeleteAllCollections => new TranslatableString(getKey(@"delete_all_collections"), @"Delete ALL collections");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Restore all hidden difficulties"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString RestoreAllHiddenDifficulties => new TranslatableString(getKey(@"restore_all_hidden_difficulties"), @"Restore all hidden difficulties");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Restore all recently deleted beatmaps"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString RestoreAllRecentlyDeletedBeatmaps => new TranslatableString(getKey(@"restore_all_recently_deleted_beatmaps"), @"Restore all recently deleted beatmaps");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
69
osu.Game/Localisation/OnlineSettingsStrings.cs
Normal file
69
osu.Game/Localisation/OnlineSettingsStrings.cs
Normal 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.Localisation;
|
||||||
|
|
||||||
|
namespace osu.Game.Localisation
|
||||||
|
{
|
||||||
|
public static class OnlineSettingsStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.OnlineSettings";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Online"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString OnlineSectionHeader => new TranslatableString(getKey(@"online_section_header"), @"Online");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Alerts and Privacy"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AlertsAndPrivacyHeader => new TranslatableString(getKey(@"alerts_and_privacy_header"), @"Alerts and Privacy");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Show a notification when someone mentions your name"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString NotifyOnMentioned => new TranslatableString(getKey(@"notify_on_mentioned"), @"Show a notification when someone mentions your name");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Show a notification when you receive a private message"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString NotifyOnPrivateMessage => new TranslatableString(getKey(@"notify_on_private_message"), @"Show a notification when you receive a private message");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Integrations"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString IntegrationsHeader => new TranslatableString(getKey(@"integrations_header"), @"Integrations");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Discord Rich Presence"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString DiscordRichPresence => new TranslatableString(getKey(@"discord_rich_presence"), @"Discord Rich Presence");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Web"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString WebHeader => new TranslatableString(getKey(@"web_header"), @"Web");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Warn about opening external links"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ExternalLinkWarning => new TranslatableString(getKey(@"external_link_warning"), @"Warn about opening external links");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Prefer downloads without video"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString PreferNoVideo => new TranslatableString(getKey(@"prefer_no_video"), @"Prefer downloads without video");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Automatically download beatmaps when spectating"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AutomaticallyDownloadWhenSpectating => new TranslatableString(getKey(@"automatically_download_when_spectating"), @"Automatically download beatmaps when spectating");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Show explicit content in search results"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShowExplicitContent => new TranslatableString(getKey(@"show_explicit_content"), @"Show explicit content in search results");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
54
osu.Game/Localisation/SkinSettingsStrings.cs
Normal file
54
osu.Game/Localisation/SkinSettingsStrings.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 osu.Framework.Localisation;
|
||||||
|
|
||||||
|
namespace osu.Game.Localisation
|
||||||
|
{
|
||||||
|
public static class SkinSettingsStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.SkinSettings";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Skin"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString SkinSectionHeader => new TranslatableString(getKey(@"skin_section_header"), @"Skin");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Skin layout editor"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString SkinLayoutEditor => new TranslatableString(getKey(@"skin_layout_editor"), @"Skin layout editor");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Gameplay cursor size"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString GameplayCursorSize => new TranslatableString(getKey(@"gameplay_cursor_size"), @"Gameplay cursor size");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Adjust gameplay cursor size based on current beatmap"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString AutoCursorSize => new TranslatableString(getKey(@"auto_cursor_size"), @"Adjust gameplay cursor size based on current beatmap");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Beatmap skins"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString BeatmapSkins => new TranslatableString(getKey(@"beatmap_skins"), @"Beatmap skins");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Beatmap colours"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString BeatmapColours => new TranslatableString(getKey(@"beatmap_colours"), @"Beatmap colours");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Beatmap hitsounds"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString BeatmapHitsounds => new TranslatableString(getKey(@"beatmap_hitsounds"), @"Beatmap hitsounds");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Export selected skin"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ExportSkinButton => new TranslatableString(getKey(@"export_skin_button"), @"Export selected skin");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
114
osu.Game/Localisation/UserInterfaceStrings.cs
Normal file
114
osu.Game/Localisation/UserInterfaceStrings.cs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
// 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.Localisation;
|
||||||
|
|
||||||
|
namespace osu.Game.Localisation
|
||||||
|
{
|
||||||
|
public static class UserInterfaceStrings
|
||||||
|
{
|
||||||
|
private const string prefix = @"osu.Game.Resources.Localisation.UserInterface";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "User Interface"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString UserInterfaceSectionHeader => new TranslatableString(getKey(@"user_interface_section_header"), @"User Interface");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "General"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString GeneralHeader => new TranslatableString(getKey(@"general_header"), @"General");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Rotate cursor when dragging"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString CursorRotation => new TranslatableString(getKey(@"cursor_rotation"), @"Rotate cursor when dragging");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Menu cursor size"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString MenuCursorSize => new TranslatableString(getKey(@"menu_cursor_size"), @"Menu cursor size");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Parallax"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString Parallax => new TranslatableString(getKey(@"parallax"), @"Parallax");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Hold-to-confirm activation time"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString HoldToConfirmActivationTime => new TranslatableString(getKey(@"hold_to_confirm_activation_time"), @"Hold-to-confirm activation time");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Main Menu"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString MainMenuHeader => new TranslatableString(getKey(@"main_menu_header"), @"Main Menu");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Interface voices"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString InterfaceVoices => new TranslatableString(getKey(@"interface_voices"), @"Interface voices");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "osu! music theme"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString OsuMusicTheme => new TranslatableString(getKey(@"osu_music_theme"), @"osu! music theme");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Intro sequence"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString IntroSequence => new TranslatableString(getKey(@"intro_sequence"), @"Intro sequence");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Background source"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString BackgroundSource => new TranslatableString(getKey(@"background_source"), @"Background source");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Seasonal backgrounds"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString SeasonalBackgrounds => new TranslatableString(getKey(@"seasonal_backgrounds"), @"Seasonal backgrounds");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Changes to this setting will only apply with an active osu!supporter tag."
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString NotSupporterNote => new TranslatableString(getKey(@"not_supporter_note"), @"Changes to this setting will only apply with an active osu!supporter tag.");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Song Select"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString SongSelectHeader => new TranslatableString(getKey(@"song_select_header"), @"Song Select");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Right mouse drag to absolute scroll"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString RightMouseScroll => new TranslatableString(getKey(@"right_mouse_scroll"), @"Right mouse drag to absolute scroll");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Show converted beatmaps"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString ShowConvertedBeatmaps => new TranslatableString(getKey(@"show_converted_beatmaps"), @"Show converted beatmaps");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Display beatmaps from"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString StarsMinimum => new TranslatableString(getKey(@"stars_minimum"), @"Display beatmaps from");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "up to"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString StarsMaximum => new TranslatableString(getKey(@"stars_maximum"), @"up to");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "Random selection algorithm"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString RandomSelectionAlgorithm => new TranslatableString(getKey(@"random_selection_algorithm"), @"Random selection algorithm");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// "no limit"
|
||||||
|
/// </summary>
|
||||||
|
public static LocalisableString NoLimit => new TranslatableString(getKey(@"no_limit"), @"no limit");
|
||||||
|
|
||||||
|
private static string getKey(string key) => $"{prefix}:{key}";
|
||||||
|
}
|
||||||
|
}
|
@ -305,9 +305,11 @@ namespace osu.Game.Online.API
|
|||||||
{
|
{
|
||||||
req.Perform(this);
|
req.Perform(this);
|
||||||
|
|
||||||
|
if (req.CompletionState != APIRequestCompletionState.Completed)
|
||||||
|
return false;
|
||||||
|
|
||||||
// we could still be in initialisation, at which point we don't want to say we're Online yet.
|
// we could still be in initialisation, at which point we don't want to say we're Online yet.
|
||||||
if (IsLoggedIn) state.Value = APIState.Online;
|
if (IsLoggedIn) state.Value = APIState.Online;
|
||||||
|
|
||||||
failureCount = 0;
|
failureCount = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -381,7 +383,7 @@ namespace osu.Game.Online.API
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsLoggedIn => localUser.Value.Id > 1;
|
public bool IsLoggedIn => localUser.Value.Id > 1; // TODO: should this also be true if attempting to connect?
|
||||||
|
|
||||||
public void Queue(APIRequest request)
|
public void Queue(APIRequest request)
|
||||||
{
|
{
|
||||||
|
@ -84,7 +84,7 @@ namespace osu.Game.Online.API
|
|||||||
/// The state of this request, from an outside perspective.
|
/// The state of this request, from an outside perspective.
|
||||||
/// This is used to ensure correct notification events are fired.
|
/// This is used to ensure correct notification events are fired.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private APIRequestCompletionState completionState;
|
public APIRequestCompletionState CompletionState { get; private set; }
|
||||||
|
|
||||||
public void Perform(IAPIProvider api)
|
public void Perform(IAPIProvider api)
|
||||||
{
|
{
|
||||||
@ -127,10 +127,10 @@ namespace osu.Game.Online.API
|
|||||||
{
|
{
|
||||||
lock (completionStateLock)
|
lock (completionStateLock)
|
||||||
{
|
{
|
||||||
if (completionState != APIRequestCompletionState.Waiting)
|
if (CompletionState != APIRequestCompletionState.Waiting)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
completionState = APIRequestCompletionState.Completed;
|
CompletionState = APIRequestCompletionState.Completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (API == null)
|
if (API == null)
|
||||||
@ -143,10 +143,10 @@ namespace osu.Game.Online.API
|
|||||||
{
|
{
|
||||||
lock (completionStateLock)
|
lock (completionStateLock)
|
||||||
{
|
{
|
||||||
if (completionState != APIRequestCompletionState.Waiting)
|
if (CompletionState != APIRequestCompletionState.Waiting)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
completionState = APIRequestCompletionState.Failed;
|
CompletionState = APIRequestCompletionState.Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (API == null)
|
if (API == null)
|
||||||
@ -161,7 +161,7 @@ namespace osu.Game.Online.API
|
|||||||
{
|
{
|
||||||
lock (completionStateLock)
|
lock (completionStateLock)
|
||||||
{
|
{
|
||||||
if (completionState != APIRequestCompletionState.Waiting)
|
if (CompletionState != APIRequestCompletionState.Waiting)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WebRequest?.Abort();
|
WebRequest?.Abort();
|
||||||
@ -200,7 +200,7 @@ namespace osu.Game.Online.API
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
lock (completionStateLock)
|
lock (completionStateLock)
|
||||||
return completionState == APIRequestCompletionState.Failed;
|
return CompletionState == APIRequestCompletionState.Failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,8 @@ namespace osu.Game.Online.Chat
|
|||||||
RegexOptions.IgnoreCase);
|
RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
// 00:00:000 (1,2,3) - test
|
// 00:00:000 (1,2,3) - test
|
||||||
private static readonly Regex time_regex = new Regex(@"\d\d:\d\d:\d\d\d? [^-]*");
|
// regex from https://github.com/ppy/osu-web/blob/651a9bac2b60d031edd7e33b8073a469bf11edaa/resources/assets/coffee/_classes/beatmap-discussion-helper.coffee#L10
|
||||||
|
private static readonly Regex time_regex = new Regex(@"\b(((\d{2,}):([0-5]\d)[:.](\d{3}))(\s\((?:\d+[,|])*\d+\))?)");
|
||||||
|
|
||||||
// #osu
|
// #osu
|
||||||
private static readonly Regex channel_regex = new Regex(@"(#[a-zA-Z]+[a-zA-Z0-9]+)");
|
private static readonly Regex channel_regex = new Regex(@"(#[a-zA-Z]+[a-zA-Z0-9]+)");
|
||||||
|
@ -8,6 +8,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays.Chat;
|
using osu.Game.Overlays.Chat;
|
||||||
@ -22,7 +23,7 @@ namespace osu.Game.Online.Chat
|
|||||||
{
|
{
|
||||||
public readonly Bindable<Channel> Channel = new Bindable<Channel>();
|
public readonly Bindable<Channel> Channel = new Bindable<Channel>();
|
||||||
|
|
||||||
private readonly FocusedTextBox textbox;
|
protected readonly ChatTextBox Textbox;
|
||||||
|
|
||||||
protected ChannelManager ChannelManager;
|
protected ChannelManager ChannelManager;
|
||||||
|
|
||||||
@ -30,6 +31,8 @@ namespace osu.Game.Online.Chat
|
|||||||
|
|
||||||
private readonly bool postingTextbox;
|
private readonly bool postingTextbox;
|
||||||
|
|
||||||
|
protected readonly Box Background;
|
||||||
|
|
||||||
private const float textbox_height = 30;
|
private const float textbox_height = 30;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -44,7 +47,7 @@ namespace osu.Game.Online.Chat
|
|||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
new Box
|
Background = new Box
|
||||||
{
|
{
|
||||||
Colour = Color4.Black,
|
Colour = Color4.Black,
|
||||||
Alpha = 0.8f,
|
Alpha = 0.8f,
|
||||||
@ -54,7 +57,7 @@ namespace osu.Game.Online.Chat
|
|||||||
|
|
||||||
if (postingTextbox)
|
if (postingTextbox)
|
||||||
{
|
{
|
||||||
AddInternal(textbox = new FocusedTextBox
|
AddInternal(Textbox = new ChatTextBox
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Height = textbox_height,
|
Height = textbox_height,
|
||||||
@ -65,7 +68,7 @@ namespace osu.Game.Online.Chat
|
|||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
});
|
});
|
||||||
|
|
||||||
textbox.OnCommit += postMessage;
|
Textbox.OnCommit += postMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
Channel.BindValueChanged(channelChanged);
|
Channel.BindValueChanged(channelChanged);
|
||||||
@ -82,7 +85,7 @@ namespace osu.Game.Online.Chat
|
|||||||
|
|
||||||
private void postMessage(TextBox sender, bool newtext)
|
private void postMessage(TextBox sender, bool newtext)
|
||||||
{
|
{
|
||||||
var text = textbox.Text.Trim();
|
var text = Textbox.Text.Trim();
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(text))
|
if (string.IsNullOrWhiteSpace(text))
|
||||||
return;
|
return;
|
||||||
@ -92,7 +95,7 @@ namespace osu.Game.Online.Chat
|
|||||||
else
|
else
|
||||||
ChannelManager?.PostMessage(text, target: Channel.Value);
|
ChannelManager?.PostMessage(text, target: Channel.Value);
|
||||||
|
|
||||||
textbox.Text = string.Empty;
|
Textbox.Text = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual ChatLine CreateMessage(Message message) => new StandAloneMessage(message);
|
protected virtual ChatLine CreateMessage(Message message) => new StandAloneMessage(message);
|
||||||
@ -110,6 +113,25 @@ namespace osu.Game.Online.Chat
|
|||||||
AddInternal(drawableChannel);
|
AddInternal(drawableChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ChatTextBox : FocusedTextBox
|
||||||
|
{
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
BackgroundUnfocused = new Color4(10, 10, 10, 10);
|
||||||
|
BackgroundFocused = new Color4(10, 10, 10, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFocusLost(FocusLostEvent e)
|
||||||
|
{
|
||||||
|
base.OnFocusLost(e);
|
||||||
|
FocusLost?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Action FocusLost;
|
||||||
|
}
|
||||||
|
|
||||||
public class StandAloneDrawableChannel : DrawableChannel
|
public class StandAloneDrawableChannel : DrawableChannel
|
||||||
{
|
{
|
||||||
public Func<Message, ChatLine> CreateChatLineAction;
|
public Func<Message, ChatLine> CreateChatLineAction;
|
||||||
|
@ -148,7 +148,12 @@ namespace osu.Game.Online
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (RuntimeInfo.SupportsJIT && preferMessagePack)
|
if (RuntimeInfo.SupportsJIT && preferMessagePack)
|
||||||
builder.AddMessagePackProtocol();
|
{
|
||||||
|
builder.AddMessagePackProtocol(options =>
|
||||||
|
{
|
||||||
|
options.SerializerOptions = SignalRUnionWorkaroundResolver.OPTIONS;
|
||||||
|
});
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// eventually we will precompile resolvers for messagepack, but this isn't working currently
|
// eventually we will precompile resolvers for messagepack, but this isn't working currently
|
||||||
|
@ -15,9 +15,9 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
[MessagePackObject]
|
[MessagePackObject]
|
||||||
[Union(0, typeof(TeamVersusRoomState))]
|
[Union(0, typeof(TeamVersusRoomState))] // IMPORTANT: Add rules to SignalRUnionWorkaroundResolver for new derived types.
|
||||||
// TODO: this will need to be abstract or interface when/if we get messagepack working. for now it isn't as it breaks json serialisation.
|
// TODO: abstract breaks json serialisation. attention will be required for iOS support (unless we get messagepack AOT working instead).
|
||||||
public class MatchRoomState
|
public abstract class MatchRoomState
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using MessagePack;
|
using MessagePack;
|
||||||
|
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
|
||||||
|
|
||||||
namespace osu.Game.Online.Multiplayer
|
namespace osu.Game.Online.Multiplayer
|
||||||
{
|
{
|
||||||
@ -11,6 +12,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
[MessagePackObject]
|
[MessagePackObject]
|
||||||
|
[Union(0, typeof(ChangeTeamRequest))] // IMPORTANT: Add rules to SignalRUnionWorkaroundResolver for new derived types.
|
||||||
public abstract class MatchUserRequest
|
public abstract class MatchUserRequest
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,9 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
[MessagePackObject]
|
[MessagePackObject]
|
||||||
[Union(0, typeof(TeamVersusUserState))]
|
[Union(0, typeof(TeamVersusUserState))] // IMPORTANT: Add rules to SignalRUnionWorkaroundResolver for new derived types.
|
||||||
// TODO: this will need to be abstract or interface when/if we get messagepack working. for now it isn't as it breaks json serialisation.
|
// TODO: abstract breaks json serialisation. attention will be required for iOS support (unless we get messagepack AOT working instead).
|
||||||
public class MatchUserState
|
public abstract class MatchUserState
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
{
|
{
|
||||||
// Importantly, we are intentionally not using MessagePack here to correctly support derived class serialization.
|
// Importantly, we are intentionally not using MessagePack here to correctly support derived class serialization.
|
||||||
// More information on the limitations / reasoning can be found in osu-server-spectator's initialisation code.
|
// More information on the limitations / reasoning can be found in osu-server-spectator's initialisation code.
|
||||||
connector = api.GetHubConnector(nameof(OnlineMultiplayerClient), endpoint, false);
|
connector = api.GetHubConnector(nameof(OnlineMultiplayerClient), endpoint);
|
||||||
|
|
||||||
if (connector != null)
|
if (connector != null)
|
||||||
{
|
{
|
||||||
|
@ -47,39 +47,13 @@ namespace osu.Game.Online
|
|||||||
pollIfNecessary();
|
pollIfNecessary();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool pollIfNecessary()
|
/// <summary>
|
||||||
|
/// Immediately performs a <see cref="Poll"/>.
|
||||||
|
/// </summary>
|
||||||
|
public void PollImmediately()
|
||||||
{
|
{
|
||||||
// we must be loaded so we have access to clock.
|
lastTimePolled = Time.Current - TimeBetweenPolls.Value;
|
||||||
if (!IsLoaded) return false;
|
|
||||||
|
|
||||||
// there's already a poll process running.
|
|
||||||
if (pollingActive) return false;
|
|
||||||
|
|
||||||
// don't try polling if the time between polls hasn't been set.
|
|
||||||
if (TimeBetweenPolls.Value == 0) return false;
|
|
||||||
|
|
||||||
if (!lastTimePolled.HasValue)
|
|
||||||
{
|
|
||||||
doPoll();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Time.Current - lastTimePolled.Value > TimeBetweenPolls.Value)
|
|
||||||
{
|
|
||||||
doPoll();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not enough time has passed since the last poll. we do want to schedule a poll to happen, though.
|
|
||||||
scheduleNextPoll();
|
scheduleNextPoll();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doPoll()
|
|
||||||
{
|
|
||||||
scheduledPoll = null;
|
|
||||||
pollingActive = true;
|
|
||||||
Poll().ContinueWith(_ => pollComplete());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -90,13 +64,11 @@ namespace osu.Game.Online
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private void doPoll()
|
||||||
/// Immediately performs a <see cref="Poll"/>.
|
|
||||||
/// </summary>
|
|
||||||
public void PollImmediately()
|
|
||||||
{
|
{
|
||||||
lastTimePolled = Time.Current - TimeBetweenPolls.Value;
|
scheduledPoll = null;
|
||||||
scheduleNextPoll();
|
pollingActive = true;
|
||||||
|
Poll().ContinueWith(_ => pollComplete());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -111,6 +83,33 @@ namespace osu.Game.Online
|
|||||||
pollIfNecessary();
|
pollIfNecessary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void pollIfNecessary()
|
||||||
|
{
|
||||||
|
// we must be loaded so we have access to clock.
|
||||||
|
if (!IsLoaded) return;
|
||||||
|
|
||||||
|
// there's already a poll process running.
|
||||||
|
if (pollingActive) return;
|
||||||
|
|
||||||
|
// don't try polling if the time between polls hasn't been set.
|
||||||
|
if (TimeBetweenPolls.Value == 0) return;
|
||||||
|
|
||||||
|
if (!lastTimePolled.HasValue)
|
||||||
|
{
|
||||||
|
doPoll();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Time.Current - lastTimePolled.Value > TimeBetweenPolls.Value)
|
||||||
|
{
|
||||||
|
doPoll();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not enough time has passed since the last poll. we do want to schedule a poll to happen, though.
|
||||||
|
scheduleNextPoll();
|
||||||
|
}
|
||||||
|
|
||||||
private void scheduleNextPoll()
|
private void scheduleNextPoll()
|
||||||
{
|
{
|
||||||
scheduledPoll?.Cancel();
|
scheduledPoll?.Cancel();
|
||||||
|
@ -134,7 +134,7 @@ namespace osu.Game.Online.Rooms
|
|||||||
/// The position of this <see cref="Room"/> in the list. This is not read from or written to the API.
|
/// The position of this <see cref="Room"/> in the list. This is not read from or written to the API.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public readonly Bindable<int> Position = new Bindable<int>(-1);
|
public readonly Bindable<long> Position = new Bindable<long>(-1); // Todo: This does not need to exist.
|
||||||
|
|
||||||
public Room()
|
public Room()
|
||||||
{
|
{
|
||||||
|
@ -8,6 +8,5 @@ namespace osu.Game.Online.Rooms
|
|||||||
// used for osu-web deserialization so names shouldn't be changed.
|
// used for osu-web deserialization so names shouldn't be changed.
|
||||||
Normal,
|
Normal,
|
||||||
Spotlight,
|
Spotlight,
|
||||||
Realtime,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
61
osu.Game/Online/SignalRUnionWorkaroundResolver.cs
Normal file
61
osu.Game/Online/SignalRUnionWorkaroundResolver.cs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// 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 MessagePack;
|
||||||
|
using MessagePack.Formatters;
|
||||||
|
using MessagePack.Resolvers;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
|
using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus;
|
||||||
|
|
||||||
|
namespace osu.Game.Online
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Handles SignalR being unable to comprehend [Union] types correctly by redirecting to a known base (union) type.
|
||||||
|
/// See https://github.com/dotnet/aspnetcore/issues/7298.
|
||||||
|
/// </summary>
|
||||||
|
public class SignalRUnionWorkaroundResolver : IFormatterResolver
|
||||||
|
{
|
||||||
|
public static readonly MessagePackSerializerOptions OPTIONS =
|
||||||
|
MessagePackSerializerOptions.Standard.WithResolver(new SignalRUnionWorkaroundResolver());
|
||||||
|
|
||||||
|
private static readonly Dictionary<Type, IMessagePackFormatter> formatter_map = new Dictionary<Type, IMessagePackFormatter>
|
||||||
|
{
|
||||||
|
{ typeof(TeamVersusUserState), new TypeRedirectingFormatter<TeamVersusUserState, MatchUserState>() },
|
||||||
|
{ typeof(TeamVersusRoomState), new TypeRedirectingFormatter<TeamVersusRoomState, MatchRoomState>() },
|
||||||
|
{ typeof(ChangeTeamRequest), new TypeRedirectingFormatter<ChangeTeamRequest, MatchUserRequest>() },
|
||||||
|
|
||||||
|
// These should not be required. The fallback should work. But something is weird with the way caching is done.
|
||||||
|
// For future adventurers, I would not advise looking into this further. It's likely not worth the effort.
|
||||||
|
{ typeof(MatchUserState), new TypeRedirectingFormatter<MatchUserState, MatchUserState>() },
|
||||||
|
{ typeof(MatchRoomState), new TypeRedirectingFormatter<MatchRoomState, MatchRoomState>() },
|
||||||
|
{ typeof(MatchUserRequest), new TypeRedirectingFormatter<MatchUserRequest, MatchUserRequest>() },
|
||||||
|
{ typeof(MatchServerEvent), new TypeRedirectingFormatter<MatchServerEvent, MatchServerEvent>() },
|
||||||
|
};
|
||||||
|
|
||||||
|
public IMessagePackFormatter<T> GetFormatter<T>()
|
||||||
|
{
|
||||||
|
if (formatter_map.TryGetValue(typeof(T), out var formatter))
|
||||||
|
return (IMessagePackFormatter<T>)formatter;
|
||||||
|
|
||||||
|
return StandardResolver.Instance.GetFormatter<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TypeRedirectingFormatter<TActual, TBase> : IMessagePackFormatter<TActual>
|
||||||
|
{
|
||||||
|
private readonly IMessagePackFormatter<TBase> baseFormatter;
|
||||||
|
|
||||||
|
public TypeRedirectingFormatter()
|
||||||
|
{
|
||||||
|
baseFormatter = StandardResolver.Instance.GetFormatter<TBase>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Serialize(ref MessagePackWriter writer, TActual value, MessagePackSerializerOptions options) =>
|
||||||
|
baseFormatter.Serialize(ref writer, (TBase)(object)value, StandardResolver.Options);
|
||||||
|
|
||||||
|
public TActual Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) =>
|
||||||
|
(TActual)(object)baseFormatter.Deserialize(ref reader, StandardResolver.Options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -62,7 +62,7 @@ namespace osu.Game
|
|||||||
/// The full osu! experience. Builds on top of <see cref="OsuGameBase"/> to add menus and binding logic
|
/// The full osu! experience. Builds on top of <see cref="OsuGameBase"/> to add menus and binding logic
|
||||||
/// for initial components that are generally retrieved via DI.
|
/// for initial components that are generally retrieved via DI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class OsuGame : OsuGameBase, IKeyBindingHandler<GlobalAction>
|
public class OsuGame : OsuGameBase, IKeyBindingHandler<GlobalAction>, ILocalUserPlayInfo
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The amount of global offset to apply when a left/right anchored overlay is displayed (ie. settings or notifications).
|
/// The amount of global offset to apply when a left/right anchored overlay is displayed (ie. settings or notifications).
|
||||||
@ -1018,10 +1018,13 @@ namespace osu.Game
|
|||||||
|
|
||||||
var horizontalOffset = 0f;
|
var horizontalOffset = 0f;
|
||||||
|
|
||||||
|
// Content.ToLocalSpace() is used instead of this.ToLocalSpace() to correctly calculate the offset with scaling modes active.
|
||||||
|
// Content is a child of a scaling container with ScalingMode.Everything set, while the game itself is never scaled.
|
||||||
|
// this avoids a visible jump in the positioning of the screen offset container.
|
||||||
if (Settings.IsLoaded && Settings.IsPresent)
|
if (Settings.IsLoaded && Settings.IsPresent)
|
||||||
horizontalOffset += ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X * SIDE_OVERLAY_OFFSET_RATIO;
|
horizontalOffset += Content.ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X * SIDE_OVERLAY_OFFSET_RATIO;
|
||||||
if (Notifications.IsLoaded && Notifications.IsPresent)
|
if (Notifications.IsLoaded && Notifications.IsPresent)
|
||||||
horizontalOffset += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SIDE_OVERLAY_OFFSET_RATIO;
|
horizontalOffset += (Content.ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - Content.DrawWidth) * SIDE_OVERLAY_OFFSET_RATIO;
|
||||||
|
|
||||||
ScreenOffsetContainer.X = horizontalOffset;
|
ScreenOffsetContainer.X = horizontalOffset;
|
||||||
|
|
||||||
@ -1085,5 +1088,7 @@ namespace osu.Game
|
|||||||
if (newScreen == null)
|
if (newScreen == null)
|
||||||
Exit();
|
Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IBindable<bool> ILocalUserPlayInfo.IsPlaying => LocalUserPlaying;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,19 +139,24 @@ namespace osu.Game.Overlays.BeatmapListing.Panels
|
|||||||
|
|
||||||
LoadComponentAsync(Preview = previewTrackManager.Get(beatmapSet), preview =>
|
LoadComponentAsync(Preview = previewTrackManager.Get(beatmapSet), preview =>
|
||||||
{
|
{
|
||||||
// beatmapset may have changed.
|
// Make sure that we schedule to after the next audio frame to fix crashes in single-threaded execution.
|
||||||
if (Preview != preview)
|
// See: https://github.com/ppy/osu-framework/issues/4692
|
||||||
return;
|
Schedule(() =>
|
||||||
|
{
|
||||||
|
// beatmapset may have changed.
|
||||||
|
if (Preview != preview)
|
||||||
|
return;
|
||||||
|
|
||||||
AddInternal(preview);
|
AddInternal(preview);
|
||||||
loading = false;
|
loading = false;
|
||||||
// make sure that the update of value of Playing (and the ensuing value change callbacks)
|
// make sure that the update of value of Playing (and the ensuing value change callbacks)
|
||||||
// are marshaled back to the update thread.
|
// are marshaled back to the update thread.
|
||||||
preview.Stopped += () => Schedule(() => playing.Value = false);
|
preview.Stopped += () => Schedule(() => playing.Value = false);
|
||||||
|
|
||||||
// user may have changed their mind.
|
// user may have changed their mind.
|
||||||
if (playing.Value)
|
if (playing.Value)
|
||||||
attemptStart();
|
attemptStart();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -24,6 +24,7 @@ namespace osu.Game.Overlays.Changelog
|
|||||||
public class ChangelogSupporterPromo : CompositeDrawable
|
public class ChangelogSupporterPromo : CompositeDrawable
|
||||||
{
|
{
|
||||||
private const float image_container_width = 164;
|
private const float image_container_width = 164;
|
||||||
|
private const float heart_size = 75;
|
||||||
|
|
||||||
private readonly FillFlowContainer textContainer;
|
private readonly FillFlowContainer textContainer;
|
||||||
private readonly Container imageContainer;
|
private readonly Container imageContainer;
|
||||||
@ -134,18 +135,30 @@ namespace osu.Game.Overlays.Changelog
|
|||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
|
Margin = new MarginPadding { Bottom = 28 },
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
FillMode = FillMode.Fill,
|
FillMode = FillMode.Fill,
|
||||||
Texture = textures.Get(@"Online/supporter-pippi"),
|
Texture = textures.Get(@"Online/supporter-pippi"),
|
||||||
},
|
},
|
||||||
new Sprite
|
new Container
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
Width = 75,
|
Size = new Vector2(heart_size),
|
||||||
Height = 75,
|
|
||||||
Margin = new MarginPadding { Top = 70 },
|
Margin = new MarginPadding { Top = 70 },
|
||||||
Texture = textures.Get(@"Online/supporter-heart"),
|
Masking = true,
|
||||||
|
EdgeEffect = new EdgeEffectParameters
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Shadow,
|
||||||
|
Colour = colour.Pink,
|
||||||
|
Radius = 10,
|
||||||
|
Roundness = heart_size / 2,
|
||||||
|
},
|
||||||
|
Child = new Sprite
|
||||||
|
{
|
||||||
|
Size = new Vector2(heart_size),
|
||||||
|
Texture = textures.Get(@"Online/supporter-heart"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -110,15 +110,15 @@ namespace osu.Game.Overlays.Chat
|
|||||||
EdgeEffect = new EdgeEffectParameters
|
EdgeEffect = new EdgeEffectParameters
|
||||||
{
|
{
|
||||||
Roundness = 1,
|
Roundness = 1,
|
||||||
Offset = new Vector2(0, 3),
|
Radius = 1,
|
||||||
Radius = 3,
|
|
||||||
Colour = Color4.Black.Opacity(0.3f),
|
Colour = Color4.Black.Opacity(0.3f),
|
||||||
|
Offset = new Vector2(0, 1),
|
||||||
Type = EdgeEffectType.Shadow,
|
Type = EdgeEffectType.Shadow,
|
||||||
},
|
},
|
||||||
Child = new Container
|
Child = new Container
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Y = 3,
|
Y = 0,
|
||||||
Masking = true,
|
Masking = true,
|
||||||
CornerRadius = 4,
|
CornerRadius = 4,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
|
@ -6,6 +6,7 @@ using osu.Framework.Bindables;
|
|||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Colour;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Framework.Graphics.Effects;
|
using osu.Framework.Graphics.Effects;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
@ -38,12 +39,12 @@ namespace osu.Game.Overlays
|
|||||||
current.ValueChanged += _ => UpdateState();
|
current.ValueChanged += _ => UpdateState();
|
||||||
current.DefaultChanged += _ => UpdateState();
|
current.DefaultChanged += _ => UpdateState();
|
||||||
current.DisabledChanged += _ => UpdateState();
|
current.DisabledChanged += _ => UpdateState();
|
||||||
UpdateState();
|
|
||||||
|
if (IsLoaded)
|
||||||
|
UpdateState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color4 buttonColour;
|
|
||||||
|
|
||||||
private bool hovering;
|
private bool hovering;
|
||||||
|
|
||||||
public RestoreDefaultValueButton()
|
public RestoreDefaultValueButton()
|
||||||
@ -58,12 +59,11 @@ namespace osu.Game.Overlays
|
|||||||
private void load(OsuColour colour)
|
private void load(OsuColour colour)
|
||||||
{
|
{
|
||||||
BackgroundColour = colour.Yellow;
|
BackgroundColour = colour.Yellow;
|
||||||
buttonColour = colour.Yellow;
|
|
||||||
Content.Width = 0.33f;
|
Content.Width = 0.33f;
|
||||||
Content.CornerRadius = 3;
|
Content.CornerRadius = 3;
|
||||||
Content.EdgeEffect = new EdgeEffectParameters
|
Content.EdgeEffect = new EdgeEffectParameters
|
||||||
{
|
{
|
||||||
Colour = buttonColour.Opacity(0.1f),
|
Colour = BackgroundColour.Opacity(0.1f),
|
||||||
Type = EdgeEffectType.Glow,
|
Type = EdgeEffectType.Glow,
|
||||||
Radius = 2,
|
Radius = 2,
|
||||||
};
|
};
|
||||||
@ -81,7 +81,10 @@ namespace osu.Game.Overlays
|
|||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
UpdateState();
|
|
||||||
|
// avoid unnecessary transforms on first display.
|
||||||
|
Alpha = currentAlpha;
|
||||||
|
Background.Colour = currentColour;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalisableString TooltipText => "revert to default";
|
public LocalisableString TooltipText => "revert to default";
|
||||||
@ -101,14 +104,16 @@ namespace osu.Game.Overlays
|
|||||||
|
|
||||||
public void UpdateState() => Scheduler.AddOnce(updateState);
|
public void UpdateState() => Scheduler.AddOnce(updateState);
|
||||||
|
|
||||||
|
private float currentAlpha => current.IsDefault ? 0f : hovering && !current.Disabled ? 1f : 0.65f;
|
||||||
|
private ColourInfo currentColour => current.Disabled ? Color4.Gray : BackgroundColour;
|
||||||
|
|
||||||
private void updateState()
|
private void updateState()
|
||||||
{
|
{
|
||||||
if (current == null)
|
if (current == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.FadeTo(current.IsDefault ? 0f :
|
this.FadeTo(currentAlpha, 200, Easing.OutQuint);
|
||||||
hovering && !current.Disabled ? 1f : 0.65f, 200, Easing.OutQuint);
|
Background.FadeColour(currentColour, 200, Easing.OutQuint);
|
||||||
this.FadeColour(current.Disabled ? Color4.Gray : buttonColour, 200, Easing.OutQuint);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,29 +8,39 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.Audio
|
namespace osu.Game.Overlays.Settings.Sections.Audio
|
||||||
{
|
{
|
||||||
public class AudioDevicesSettings : SettingsSubsection
|
public class AudioDevicesSettings : SettingsSubsection
|
||||||
{
|
{
|
||||||
protected override LocalisableString Header => "Devices";
|
protected override LocalisableString Header => AudioSettingsStrings.AudioDevicesHeader;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private AudioManager audio { get; set; }
|
private AudioManager audio { get; set; }
|
||||||
|
|
||||||
private SettingsDropdown<string> dropdown;
|
private SettingsDropdown<string> dropdown;
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
Children = new Drawable[]
|
||||||
|
|
||||||
if (audio != null)
|
|
||||||
{
|
{
|
||||||
audio.OnNewDevice -= onDeviceChanged;
|
dropdown = new AudioDeviceSettingsDropdown
|
||||||
audio.OnLostDevice -= onDeviceChanged;
|
{
|
||||||
}
|
Keywords = new[] { "speaker", "headphone", "output" }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
updateItems();
|
||||||
|
|
||||||
|
audio.OnNewDevice += onDeviceChanged;
|
||||||
|
audio.OnLostDevice += onDeviceChanged;
|
||||||
|
dropdown.Current = audio.AudioDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onDeviceChanged(string name) => updateItems();
|
||||||
|
|
||||||
private void updateItems()
|
private void updateItems()
|
||||||
{
|
{
|
||||||
var deviceItems = new List<string> { string.Empty };
|
var deviceItems = new List<string> { string.Empty };
|
||||||
@ -49,26 +59,15 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
|
|||||||
dropdown.Items = deviceItems.Distinct().ToList();
|
dropdown.Items = deviceItems.Distinct().ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onDeviceChanged(string name) => updateItems();
|
protected override void Dispose(bool isDisposing)
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
Children = new Drawable[]
|
if (audio != null)
|
||||||
{
|
{
|
||||||
dropdown = new AudioDeviceSettingsDropdown
|
audio.OnNewDevice -= onDeviceChanged;
|
||||||
{
|
audio.OnLostDevice -= onDeviceChanged;
|
||||||
Keywords = new[] { "speaker", "headphone", "output" }
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
updateItems();
|
|
||||||
|
|
||||||
dropdown.Current = audio.AudioDevice;
|
|
||||||
|
|
||||||
audio.OnNewDevice += onDeviceChanged;
|
|
||||||
audio.OnLostDevice += onDeviceChanged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AudioDeviceSettingsDropdown : SettingsDropdown<string>
|
private class AudioDeviceSettingsDropdown : SettingsDropdown<string>
|
||||||
@ -78,7 +77,7 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
|
|||||||
private class AudioDeviceDropdownControl : DropdownControl
|
private class AudioDeviceDropdownControl : DropdownControl
|
||||||
{
|
{
|
||||||
protected override LocalisableString GenerateItemText(string item)
|
protected override LocalisableString GenerateItemText(string item)
|
||||||
=> string.IsNullOrEmpty(item) ? "Default" : base.GenerateItemText(item);
|
=> string.IsNullOrEmpty(item) ? CommonStrings.Default : base.GenerateItemText(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,22 @@
|
|||||||
// 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 osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.Audio
|
namespace osu.Game.Overlays.Settings.Sections.Audio
|
||||||
{
|
{
|
||||||
public class OffsetSettings : SettingsSubsection
|
public class OffsetSettings : SettingsSubsection
|
||||||
{
|
{
|
||||||
protected override LocalisableString Header => "Offset Adjustment";
|
protected override LocalisableString Header => AudioSettingsStrings.OffsetHeader;
|
||||||
|
|
||||||
|
public override IEnumerable<string> FilterTerms => base.FilterTerms.Concat(new[] { "universal", "uo", "timing" });
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config)
|
private void load(OsuConfigManager config)
|
||||||
@ -20,13 +25,13 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
|
|||||||
{
|
{
|
||||||
new SettingsSlider<double, OffsetSlider>
|
new SettingsSlider<double, OffsetSlider>
|
||||||
{
|
{
|
||||||
LabelText = "Audio offset",
|
LabelText = AudioSettingsStrings.AudioOffset,
|
||||||
Current = config.GetBindable<double>(OsuSetting.AudioOffset),
|
Current = config.GetBindable<double>(OsuSetting.AudioOffset),
|
||||||
KeyboardStep = 1f
|
KeyboardStep = 1f
|
||||||
},
|
},
|
||||||
new SettingsButton
|
new SettingsButton
|
||||||
{
|
{
|
||||||
Text = "Offset wizard"
|
Text = AudioSettingsStrings.OffsetWizard
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,13 @@ using osu.Framework.Audio;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.Audio
|
namespace osu.Game.Overlays.Settings.Sections.Audio
|
||||||
{
|
{
|
||||||
public class VolumeSettings : SettingsSubsection
|
public class VolumeSettings : SettingsSubsection
|
||||||
{
|
{
|
||||||
protected override LocalisableString Header => "Volume";
|
protected override LocalisableString Header => AudioSettingsStrings.VolumeHeader;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audio, OsuConfigManager config)
|
private void load(AudioManager audio, OsuConfigManager config)
|
||||||
@ -20,28 +21,28 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
|
|||||||
{
|
{
|
||||||
new SettingsSlider<double>
|
new SettingsSlider<double>
|
||||||
{
|
{
|
||||||
LabelText = "Master",
|
LabelText = AudioSettingsStrings.MasterVolume,
|
||||||
Current = audio.Volume,
|
Current = audio.Volume,
|
||||||
KeyboardStep = 0.01f,
|
KeyboardStep = 0.01f,
|
||||||
DisplayAsPercentage = true
|
DisplayAsPercentage = true
|
||||||
},
|
},
|
||||||
new SettingsSlider<double>
|
new SettingsSlider<double>
|
||||||
{
|
{
|
||||||
LabelText = "Master (window inactive)",
|
LabelText = AudioSettingsStrings.MasterVolumeInactive,
|
||||||
Current = config.GetBindable<double>(OsuSetting.VolumeInactive),
|
Current = config.GetBindable<double>(OsuSetting.VolumeInactive),
|
||||||
KeyboardStep = 0.01f,
|
KeyboardStep = 0.01f,
|
||||||
DisplayAsPercentage = true
|
DisplayAsPercentage = true
|
||||||
},
|
},
|
||||||
new SettingsSlider<double>
|
new SettingsSlider<double>
|
||||||
{
|
{
|
||||||
LabelText = "Effect",
|
LabelText = AudioSettingsStrings.EffectVolume,
|
||||||
Current = audio.VolumeSample,
|
Current = audio.VolumeSample,
|
||||||
KeyboardStep = 0.01f,
|
KeyboardStep = 0.01f,
|
||||||
DisplayAsPercentage = true
|
DisplayAsPercentage = true
|
||||||
},
|
},
|
||||||
new SettingsSlider<double>
|
new SettingsSlider<double>
|
||||||
{
|
{
|
||||||
LabelText = "Music",
|
LabelText = AudioSettingsStrings.MusicVolume,
|
||||||
Current = audio.VolumeTrack,
|
Current = audio.VolumeTrack,
|
||||||
KeyboardStep = 0.01f,
|
KeyboardStep = 0.01f,
|
||||||
DisplayAsPercentage = true
|
DisplayAsPercentage = true
|
||||||
|
@ -3,15 +3,17 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Overlays.Settings.Sections.Audio;
|
using osu.Game.Overlays.Settings.Sections.Audio;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections
|
namespace osu.Game.Overlays.Settings.Sections
|
||||||
{
|
{
|
||||||
public class AudioSection : SettingsSection
|
public class AudioSection : SettingsSection
|
||||||
{
|
{
|
||||||
public override string Header => "Audio";
|
public override LocalisableString Header => AudioSettingsStrings.AudioSectionHeader;
|
||||||
|
|
||||||
public override Drawable CreateIcon() => new SpriteIcon
|
public override Drawable CreateIcon() => new SpriteIcon
|
||||||
{
|
{
|
||||||
|
@ -6,13 +6,14 @@ using osu.Framework.Configuration;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Screens.Import;
|
using osu.Game.Screens.Import;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.Debug
|
namespace osu.Game.Overlays.Settings.Sections.Debug
|
||||||
{
|
{
|
||||||
public class GeneralSettings : SettingsSubsection
|
public class GeneralSettings : SettingsSubsection
|
||||||
{
|
{
|
||||||
protected override LocalisableString Header => "General";
|
protected override LocalisableString Header => DebugSettingsStrings.GeneralHeader;
|
||||||
|
|
||||||
[BackgroundDependencyLoader(true)]
|
[BackgroundDependencyLoader(true)]
|
||||||
private void load(FrameworkDebugConfigManager config, FrameworkConfigManager frameworkConfig, OsuGame game)
|
private void load(FrameworkDebugConfigManager config, FrameworkConfigManager frameworkConfig, OsuGame game)
|
||||||
@ -21,18 +22,18 @@ namespace osu.Game.Overlays.Settings.Sections.Debug
|
|||||||
{
|
{
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Show log overlay",
|
LabelText = DebugSettingsStrings.ShowLogOverlay,
|
||||||
Current = frameworkConfig.GetBindable<bool>(FrameworkSetting.ShowLogOverlay)
|
Current = frameworkConfig.GetBindable<bool>(FrameworkSetting.ShowLogOverlay)
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Bypass front-to-back render pass",
|
LabelText = DebugSettingsStrings.BypassFrontToBackPass,
|
||||||
Current = config.GetBindable<bool>(DebugSetting.BypassFrontToBackPass)
|
Current = config.GetBindable<bool>(DebugSetting.BypassFrontToBackPass)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Add(new SettingsButton
|
Add(new SettingsButton
|
||||||
{
|
{
|
||||||
Text = "Import files",
|
Text = DebugSettingsStrings.ImportFiles,
|
||||||
Action = () => game?.PerformFromScreen(menu => menu.Push(new FileImportScreen()))
|
Action = () => game?.PerformFromScreen(menu => menu.Push(new FileImportScreen()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,13 @@ using osu.Framework.Configuration;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.Debug
|
namespace osu.Game.Overlays.Settings.Sections.Debug
|
||||||
{
|
{
|
||||||
public class MemorySettings : SettingsSubsection
|
public class MemorySettings : SettingsSubsection
|
||||||
{
|
{
|
||||||
protected override LocalisableString Header => "Memory";
|
protected override LocalisableString Header => DebugSettingsStrings.MemoryHeader;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(FrameworkDebugConfigManager config, GameHost host)
|
private void load(FrameworkDebugConfigManager config, GameHost host)
|
||||||
@ -20,7 +21,7 @@ namespace osu.Game.Overlays.Settings.Sections.Debug
|
|||||||
{
|
{
|
||||||
new SettingsButton
|
new SettingsButton
|
||||||
{
|
{
|
||||||
Text = "Clear all caches",
|
Text = DebugSettingsStrings.ClearAllCaches,
|
||||||
Action = host.Collect
|
Action = host.Collect
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -3,13 +3,15 @@
|
|||||||
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Overlays.Settings.Sections.Debug;
|
using osu.Game.Overlays.Settings.Sections.Debug;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections
|
namespace osu.Game.Overlays.Settings.Sections
|
||||||
{
|
{
|
||||||
public class DebugSection : SettingsSection
|
public class DebugSection : SettingsSection
|
||||||
{
|
{
|
||||||
public override string Header => "Debug";
|
public override LocalisableString Header => DebugSettingsStrings.DebugSectionHeader;
|
||||||
|
|
||||||
public override Drawable CreateIcon() => new SpriteIcon
|
public override Drawable CreateIcon() => new SpriteIcon
|
||||||
{
|
{
|
||||||
|
@ -6,13 +6,14 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
||||||
{
|
{
|
||||||
public class GeneralSettings : SettingsSubsection
|
public class GeneralSettings : SettingsSubsection
|
||||||
{
|
{
|
||||||
protected override LocalisableString Header => "General";
|
protected override LocalisableString Header => GameplaySettingsStrings.GeneralHeader;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config)
|
private void load(OsuConfigManager config)
|
||||||
@ -21,62 +22,62 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
|||||||
{
|
{
|
||||||
new SettingsSlider<double>
|
new SettingsSlider<double>
|
||||||
{
|
{
|
||||||
LabelText = "Background dim",
|
LabelText = GameplaySettingsStrings.BackgroundDim,
|
||||||
Current = config.GetBindable<double>(OsuSetting.DimLevel),
|
Current = config.GetBindable<double>(OsuSetting.DimLevel),
|
||||||
KeyboardStep = 0.01f,
|
KeyboardStep = 0.01f,
|
||||||
DisplayAsPercentage = true
|
DisplayAsPercentage = true
|
||||||
},
|
},
|
||||||
new SettingsSlider<double>
|
new SettingsSlider<double>
|
||||||
{
|
{
|
||||||
LabelText = "Background blur",
|
LabelText = GameplaySettingsStrings.BackgroundBlur,
|
||||||
Current = config.GetBindable<double>(OsuSetting.BlurLevel),
|
Current = config.GetBindable<double>(OsuSetting.BlurLevel),
|
||||||
KeyboardStep = 0.01f,
|
KeyboardStep = 0.01f,
|
||||||
DisplayAsPercentage = true
|
DisplayAsPercentage = true
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Lighten playfield during breaks",
|
LabelText = GameplaySettingsStrings.LightenDuringBreaks,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.LightenDuringBreaks)
|
Current = config.GetBindable<bool>(OsuSetting.LightenDuringBreaks)
|
||||||
},
|
},
|
||||||
new SettingsEnumDropdown<HUDVisibilityMode>
|
new SettingsEnumDropdown<HUDVisibilityMode>
|
||||||
{
|
{
|
||||||
LabelText = "HUD overlay visibility mode",
|
LabelText = GameplaySettingsStrings.HUDVisibilityMode,
|
||||||
Current = config.GetBindable<HUDVisibilityMode>(OsuSetting.HUDVisibilityMode)
|
Current = config.GetBindable<HUDVisibilityMode>(OsuSetting.HUDVisibilityMode)
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Show difficulty graph on progress bar",
|
LabelText = GameplaySettingsStrings.ShowDifficultyGraph,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.ShowDifficultyGraph)
|
Current = config.GetBindable<bool>(OsuSetting.ShowProgressGraph)
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Show health display even when you can't fail",
|
LabelText = GameplaySettingsStrings.ShowHealthDisplayWhenCantFail,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.ShowHealthDisplayWhenCantFail),
|
Current = config.GetBindable<bool>(OsuSetting.ShowHealthDisplayWhenCantFail),
|
||||||
Keywords = new[] { "hp", "bar" }
|
Keywords = new[] { "hp", "bar" }
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Fade playfield to red when health is low",
|
LabelText = GameplaySettingsStrings.FadePlayfieldWhenHealthLow,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.FadePlayfieldWhenHealthLow),
|
Current = config.GetBindable<bool>(OsuSetting.FadePlayfieldWhenHealthLow),
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Always show key overlay",
|
LabelText = GameplaySettingsStrings.AlwaysShowKeyOverlay,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.KeyOverlay)
|
Current = config.GetBindable<bool>(OsuSetting.KeyOverlay)
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Positional hitsounds",
|
LabelText = GameplaySettingsStrings.PositionalHitsounds,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.PositionalHitSounds)
|
Current = config.GetBindable<bool>(OsuSetting.PositionalHitSounds)
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Always play first combo break sound",
|
LabelText = GameplaySettingsStrings.AlwaysPlayFirstComboBreak,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.AlwaysPlayFirstComboBreak)
|
Current = config.GetBindable<bool>(OsuSetting.AlwaysPlayFirstComboBreak)
|
||||||
},
|
},
|
||||||
new SettingsEnumDropdown<ScoringMode>
|
new SettingsEnumDropdown<ScoringMode>
|
||||||
{
|
{
|
||||||
LabelText = "Score display mode",
|
LabelText = GameplaySettingsStrings.ScoreDisplayMode,
|
||||||
Current = config.GetBindable<ScoringMode>(OsuSetting.ScoreDisplayMode),
|
Current = config.GetBindable<ScoringMode>(OsuSetting.ScoreDisplayMode),
|
||||||
Keywords = new[] { "scoring" }
|
Keywords = new[] { "scoring" }
|
||||||
},
|
},
|
||||||
@ -86,7 +87,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
|||||||
{
|
{
|
||||||
Add(new SettingsCheckbox
|
Add(new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Disable Windows key during gameplay",
|
LabelText = GameplaySettingsStrings.DisableWinKey,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.GameplayDisableWinKey)
|
Current = config.GetBindable<bool>(OsuSetting.GameplayDisableWinKey)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,13 @@ using System.Linq;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
||||||
{
|
{
|
||||||
public class ModsSettings : SettingsSubsection
|
public class ModsSettings : SettingsSubsection
|
||||||
{
|
{
|
||||||
protected override LocalisableString Header => "Mods";
|
protected override LocalisableString Header => GameplaySettingsStrings.ModsHeader;
|
||||||
|
|
||||||
public override IEnumerable<string> FilterTerms => base.FilterTerms.Concat(new[] { "mod" });
|
public override IEnumerable<string> FilterTerms => base.FilterTerms.Concat(new[] { "mod" });
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
|
|||||||
{
|
{
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
LabelText = "Increase visibility of first object when visual impairment mods are enabled",
|
LabelText = GameplaySettingsStrings.IncreaseFirstObjectVisibility,
|
||||||
Current = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility),
|
Current = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user