diff --git a/osu.Android.props b/osu.Android.props
index 6ff9416e47..0b41d5cda4 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -53,7 +53,7 @@
-
+
diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
index 386bcbb724..ee2cec1bbd 100644
--- a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
+++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
@@ -22,26 +22,15 @@ namespace osu.Game.Rulesets.Mania.UI.Components
private readonly IBindable direction = new Bindable();
- private readonly Container hitTargetLine;
- private readonly Drawable hitTargetBar;
+ private readonly Drawable hitTarget;
public ColumnHitObjectArea(HitObjectContainer hitObjectContainer)
{
InternalChildren = new[]
{
- hitTargetBar = new Box
+ hitTarget = new DefaultHitTarget
{
RelativeSizeAxes = Axes.X,
- Height = NotePiece.NOTE_HEIGHT,
- Alpha = 0.6f,
- Colour = Color4.Black
- },
- hitTargetLine = new Container
- {
- RelativeSizeAxes = Axes.X,
- Height = hit_target_bar_height,
- Masking = true,
- Child = new Box { RelativeSizeAxes = Axes.Both }
},
hitObjectContainer
};
@@ -55,17 +44,10 @@ namespace osu.Game.Rulesets.Mania.UI.Components
{
Anchor anchor = dir.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
- hitTargetBar.Anchor = hitTargetBar.Origin = anchor;
- hitTargetLine.Anchor = hitTargetLine.Origin = anchor;
+ hitTarget.Anchor = hitTarget.Origin = anchor;
}, true);
}
- protected override void LoadComplete()
- {
- base.LoadComplete();
- updateColours();
- }
-
private Color4 accentColour;
public Color4 AccentColour
@@ -78,21 +60,86 @@ namespace osu.Game.Rulesets.Mania.UI.Components
accentColour = value;
- updateColours();
+ if (hitTarget is IHasAccentColour colouredHitTarget)
+ colouredHitTarget.AccentColour = accentColour;
}
}
- private void updateColours()
+ private class DefaultHitTarget : CompositeDrawable, IHasAccentColour
{
- if (!IsLoaded)
- return;
+ private readonly IBindable direction = new Bindable();
- hitTargetLine.EdgeEffect = new EdgeEffectParameters
+ private readonly Container hitTargetLine;
+ private readonly Drawable hitTargetBar;
+
+ public DefaultHitTarget()
{
- Type = EdgeEffectType.Glow,
- Radius = 5,
- Colour = accentColour.Opacity(0.5f),
- };
+ InternalChildren = new[]
+ {
+ hitTargetBar = new Box
+ {
+ RelativeSizeAxes = Axes.X,
+ Height = NotePiece.NOTE_HEIGHT,
+ Alpha = 0.6f,
+ Colour = Color4.Black
+ },
+ hitTargetLine = new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ Height = hit_target_bar_height,
+ Masking = true,
+ Child = new Box { RelativeSizeAxes = Axes.Both }
+ },
+ };
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(IScrollingInfo scrollingInfo)
+ {
+ direction.BindTo(scrollingInfo.Direction);
+ direction.BindValueChanged(dir =>
+ {
+ Anchor anchor = dir.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
+
+ hitTargetBar.Anchor = hitTargetBar.Origin = anchor;
+ hitTargetLine.Anchor = hitTargetLine.Origin = anchor;
+ }, true);
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+ updateColours();
+ }
+
+ private Color4 accentColour;
+
+ public Color4 AccentColour
+ {
+ get => accentColour;
+ set
+ {
+ if (accentColour == value)
+ return;
+
+ accentColour = value;
+
+ updateColours();
+ }
+ }
+
+ private void updateColours()
+ {
+ if (!IsLoaded)
+ return;
+
+ hitTargetLine.EdgeEffect = new EdgeEffectParameters
+ {
+ Type = EdgeEffectType.Glow,
+ Radius = 5,
+ Colour = accentColour.Opacity(0.5f),
+ };
+ }
}
}
}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuDistanceSnapGrid.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuDistanceSnapGrid.cs
index eff4d919b0..c9b3d08a22 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuDistanceSnapGrid.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuDistanceSnapGrid.cs
@@ -33,8 +33,8 @@ namespace osu.Game.Rulesets.Osu.Tests
typeof(CircularDistanceSnapGrid)
};
- [Cached(typeof(IEditorBeatmap))]
- private readonly EditorBeatmap editorBeatmap;
+ [Cached(typeof(EditorBeatmap))]
+ private readonly EditorBeatmap editorBeatmap;
[Cached]
private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor();
@@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.Tests
public TestSceneOsuDistanceSnapGrid()
{
- editorBeatmap = new EditorBeatmap(new OsuBeatmap());
+ editorBeatmap = new EditorBeatmap(new OsuBeatmap());
}
[SetUp]
diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
index a2c1a5f5f4..49624ea733 100644
--- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
+++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs
@@ -91,10 +91,10 @@ namespace osu.Game.Rulesets.Osu.Edit
if (sourceIndex == -1)
return null;
- OsuHitObject sourceObject = EditorBeatmap.HitObjects[sourceIndex];
+ HitObject sourceObject = EditorBeatmap.HitObjects[sourceIndex];
int targetIndex = sourceIndex + targetOffset;
- OsuHitObject targetObject = null;
+ HitObject targetObject = null;
// Keep advancing the target object while its start time falls before the end time of the source object
while (true)
@@ -111,7 +111,7 @@ namespace osu.Game.Rulesets.Osu.Edit
targetIndex++;
}
- return new OsuDistanceSnapGrid(sourceObject, targetObject);
+ return new OsuDistanceSnapGrid((OsuHitObject)sourceObject, (OsuHitObject)targetObject);
}
}
}
diff --git a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs
index aaf113f216..c31b07344d 100644
--- a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs
+++ b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs
@@ -26,10 +26,6 @@ namespace osu.Game.Rulesets.Taiko.Audio
var centre = s.GetSampleInfo();
var rim = s.GetSampleInfo(HitSampleInfo.HIT_CLAP);
- // todo: this is ugly
- centre.Namespace = "taiko";
- rim.Namespace = "taiko";
-
mappings[s.Time] = new DrumSample
{
Centre = addSound(centre),
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
index 2da5a9c403..b9d31ff906 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
@@ -166,8 +166,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
// Normal and clap samples are handled by the drum
protected override IEnumerable GetSamples() => HitObject.Samples.Where(s => s.Name != HitSampleInfo.HIT_NORMAL && s.Name != HitSampleInfo.HIT_CLAP);
- protected override string SampleNamespace => "taiko";
-
protected virtual TaikoPiece CreateMainPiece() => new CirclePiece();
///
diff --git a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs
index 4b234b56d4..48eb33976e 100644
--- a/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs
+++ b/osu.Game.Rulesets.Taiko/Replays/TaikoAutoGenerator.cs
@@ -121,41 +121,13 @@ namespace osu.Game.Rulesets.Taiko.Replays
var nextHitObject = GetNextObject(i); // Get the next object that requires pressing the same button
bool canDelayKeyUp = nextHitObject == null || nextHitObject.StartTime > endTime + KEY_UP_DELAY;
-
double calculatedDelay = canDelayKeyUp ? KEY_UP_DELAY : (nextHitObject.StartTime - endTime) * 0.9;
-
Frames.Add(new TaikoReplayFrame(endTime + calculatedDelay));
- if (i < Beatmap.HitObjects.Count - 1)
- {
- double waitTime = Beatmap.HitObjects[i + 1].StartTime - 1000;
- if (waitTime > endTime)
- Frames.Add(new TaikoReplayFrame(waitTime));
- }
-
hitButton = !hitButton;
}
return Replay;
}
-
- protected override HitObject GetNextObject(int currentIndex)
- {
- Type desiredType = Beatmap.HitObjects[currentIndex].GetType();
-
- for (int i = currentIndex + 1; i < Beatmap.HitObjects.Count; i++)
- {
- var currentObj = Beatmap.HitObjects[i];
-
- if (currentObj.GetType() == desiredType ||
- // Un-press all keys before a DrumRoll or Swell
- currentObj is DrumRoll || currentObj is Swell)
- {
- return Beatmap.HitObjects[i];
- }
- }
-
- return null;
- }
}
}
diff --git a/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/normal-hitclap.wav b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/normal-hitclap.wav
new file mode 100755
index 0000000000..9ea2be5855
Binary files /dev/null and b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/normal-hitclap.wav differ
diff --git a/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/normal-hitfinish.wav b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/normal-hitfinish.wav
new file mode 100755
index 0000000000..af270ae12a
Binary files /dev/null and b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/normal-hitfinish.wav differ
diff --git a/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/normal-hitnormal.wav b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/normal-hitnormal.wav
new file mode 100755
index 0000000000..3d8024c6ae
Binary files /dev/null and b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/normal-hitnormal.wav differ
diff --git a/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/normal-hitwhistle.wav b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/normal-hitwhistle.wav
new file mode 100755
index 0000000000..16d254cc87
Binary files /dev/null and b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/normal-hitwhistle.wav differ
diff --git a/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/soft-hitclap.wav b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/soft-hitclap.wav
new file mode 100755
index 0000000000..b4cfa26265
Binary files /dev/null and b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/soft-hitclap.wav differ
diff --git a/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/soft-hitfinish.wav b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/soft-hitfinish.wav
new file mode 100755
index 0000000000..97804a5a61
Binary files /dev/null and b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/soft-hitfinish.wav differ
diff --git a/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/soft-hitnormal.wav b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/soft-hitnormal.wav
new file mode 100755
index 0000000000..67f02877a8
Binary files /dev/null and b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/soft-hitnormal.wav differ
diff --git a/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/soft-hitwhistle.wav b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/soft-hitwhistle.wav
new file mode 100755
index 0000000000..10206cd228
Binary files /dev/null and b/osu.Game.Rulesets.Taiko/Resources/Samples/Gameplay/soft-hitwhistle.wav differ
diff --git a/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs
new file mode 100644
index 0000000000..381cd14cd4
--- /dev/null
+++ b/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs
@@ -0,0 +1,55 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Collections.Generic;
+using osu.Framework.Audio.Sample;
+using osu.Framework.Bindables;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Textures;
+using osu.Game.Audio;
+using osu.Game.Skinning;
+
+namespace osu.Game.Rulesets.Taiko.Skinning
+{
+ public class TaikoLegacySkinTransformer : ISkin
+ {
+ private readonly ISkinSource source;
+
+ public TaikoLegacySkinTransformer(ISkinSource source)
+ {
+ this.source = source;
+ }
+
+ public Drawable GetDrawableComponent(ISkinComponent component) => source.GetDrawableComponent(component);
+
+ public Texture GetTexture(string componentName) => source.GetTexture(componentName);
+
+ public SampleChannel GetSample(ISampleInfo sampleInfo) => source.GetSample(new LegacyTaikoSampleInfo(sampleInfo));
+
+ public IBindable GetConfig(TLookup lookup) => source.GetConfig(lookup);
+
+ private class LegacyTaikoSampleInfo : ISampleInfo
+ {
+ private readonly ISampleInfo source;
+
+ public LegacyTaikoSampleInfo(ISampleInfo source)
+ {
+ this.source = source;
+ }
+
+ public IEnumerable LookupNames
+ {
+ get
+ {
+ foreach (var name in source.LookupNames)
+ yield return $"taiko-{name}";
+
+ foreach (var name in source.LookupNames)
+ yield return name;
+ }
+ }
+
+ public int Volume => source.Volume;
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs
index 777b68a993..536cbdc562 100644
--- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs
+++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs
@@ -21,6 +21,8 @@ using osu.Game.Rulesets.Taiko.Difficulty;
using osu.Game.Rulesets.Taiko.Scoring;
using osu.Game.Scoring;
using System;
+using osu.Game.Rulesets.Taiko.Skinning;
+using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko
{
@@ -34,6 +36,8 @@ namespace osu.Game.Rulesets.Taiko
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap, this);
+ public override ISkin CreateLegacySkinProvider(ISkinSource source) => new TaikoLegacySkinTransformer(source);
+
public const string SHORT_NAME = "taiko";
public override IEnumerable GetDefaultKeyBindings(int variant = 0) => new[]
diff --git a/osu.Game.Tests/Beatmaps/EditorBeatmapTest.cs b/osu.Game.Tests/Beatmaps/EditorBeatmapTest.cs
index 98e630abd2..12d729d09f 100644
--- a/osu.Game.Tests/Beatmaps/EditorBeatmapTest.cs
+++ b/osu.Game.Tests/Beatmaps/EditorBeatmapTest.cs
@@ -20,7 +20,7 @@ namespace osu.Game.Tests.Beatmaps
[Test]
public void TestHitObjectAddEvent()
{
- var editorBeatmap = new EditorBeatmap(new OsuBeatmap());
+ var editorBeatmap = new EditorBeatmap(new OsuBeatmap());
HitObject addedObject = null;
editorBeatmap.HitObjectAdded += h => addedObject = h;
@@ -38,7 +38,7 @@ namespace osu.Game.Tests.Beatmaps
public void HitObjectRemoveEvent()
{
var hitCircle = new HitCircle();
- var editorBeatmap = new EditorBeatmap(new OsuBeatmap { HitObjects = { hitCircle } });
+ var editorBeatmap = new EditorBeatmap(new OsuBeatmap { HitObjects = { hitCircle } });
HitObject removedObject = null;
editorBeatmap.HitObjectRemoved += h => removedObject = h;
@@ -55,7 +55,7 @@ namespace osu.Game.Tests.Beatmaps
public void TestInitialHitObjectStartTimeChangeEvent()
{
var hitCircle = new HitCircle();
- var editorBeatmap = new EditorBeatmap(new OsuBeatmap { HitObjects = { hitCircle } });
+ var editorBeatmap = new EditorBeatmap(new OsuBeatmap { HitObjects = { hitCircle } });
HitObject changedObject = null;
editorBeatmap.StartTimeChanged += h => changedObject = h;
@@ -71,7 +71,7 @@ namespace osu.Game.Tests.Beatmaps
[Test]
public void TestAddedHitObjectStartTimeChangeEvent()
{
- var editorBeatmap = new EditorBeatmap(new OsuBeatmap());
+ var editorBeatmap = new EditorBeatmap(new OsuBeatmap());
HitObject changedObject = null;
editorBeatmap.StartTimeChanged += h => changedObject = h;
@@ -92,7 +92,7 @@ namespace osu.Game.Tests.Beatmaps
public void TestRemovedHitObjectStartTimeChangeEvent()
{
var hitCircle = new HitCircle();
- var editorBeatmap = new EditorBeatmap(new OsuBeatmap { HitObjects = { hitCircle } });
+ var editorBeatmap = new EditorBeatmap(new OsuBeatmap { HitObjects = { hitCircle } });
HitObject changedObject = null;
editorBeatmap.StartTimeChanged += h => changedObject = h;
@@ -110,7 +110,7 @@ namespace osu.Game.Tests.Beatmaps
[Test]
public void TestAddHitObjectInMiddle()
{
- var editorBeatmap = new EditorBeatmap(new OsuBeatmap
+ var editorBeatmap = new EditorBeatmap(new OsuBeatmap
{
HitObjects =
{
@@ -134,7 +134,7 @@ namespace osu.Game.Tests.Beatmaps
public void TestResortWhenStartTimeChanged()
{
var hitCircle = new HitCircle { StartTime = 1000 };
- var editorBeatmap = new EditorBeatmap(new OsuBeatmap
+ var editorBeatmap = new EditorBeatmap(new OsuBeatmap
{
HitObjects =
{
diff --git a/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs
index fe3cc375ea..2d336bd19c 100644
--- a/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs
+++ b/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs
@@ -2,11 +2,12 @@
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
+using osu.Framework.Allocation;
using osu.Framework.Testing;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Osu;
+using osu.Game.Rulesets.Osu.Beatmaps;
using osu.Game.Rulesets.Osu.Edit;
-using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Edit;
using osu.Game.Tests.Visual;
@@ -17,6 +18,9 @@ namespace osu.Game.Tests.Editor
{
private TestHitObjectComposer composer;
+ [Cached(typeof(EditorBeatmap))]
+ private readonly EditorBeatmap editorBeatmap = new EditorBeatmap(new OsuBeatmap());
+
[SetUp]
public void Setup() => Schedule(() =>
{
@@ -183,7 +187,7 @@ namespace osu.Game.Tests.Editor
private class TestHitObjectComposer : OsuHitObjectComposer
{
- public new EditorBeatmap EditorBeatmap => base.EditorBeatmap;
+ public new EditorBeatmap EditorBeatmap => base.EditorBeatmap;
public TestHitObjectComposer()
: base(new OsuRuleset())
diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs
new file mode 100644
index 0000000000..5deb136c85
--- /dev/null
+++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs
@@ -0,0 +1,74 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
+using NUnit.Framework;
+using osu.Framework.Audio;
+using osu.Framework.Audio.Sample;
+using osu.Framework.IO.Stores;
+using osu.Game.Audio;
+using osu.Game.Skinning;
+using osu.Game.Tests.Resources;
+using osu.Game.Tests.Visual;
+
+namespace osu.Game.Tests.Gameplay
+{
+ public class TestSceneStoryboardSamples : OsuTestScene
+ {
+ [Test]
+ public void TestRetrieveTopLevelSample()
+ {
+ ISkin skin = null;
+ SampleChannel channel = null;
+
+ AddStep("create skin", () => skin = new TestSkin("test-sample", Audio));
+ AddStep("retrieve sample", () => channel = skin.GetSample(new SampleInfo("test-sample")));
+
+ AddAssert("sample is non-null", () => channel != null);
+ }
+
+ [Test]
+ public void TestRetrieveSampleInSubFolder()
+ {
+ ISkin skin = null;
+ SampleChannel channel = null;
+
+ AddStep("create skin", () => skin = new TestSkin("folder/test-sample", Audio));
+ AddStep("retrieve sample", () => channel = skin.GetSample(new SampleInfo("folder/test-sample")));
+
+ AddAssert("sample is non-null", () => channel != null);
+ }
+
+ private class TestSkin : LegacySkin
+ {
+ public TestSkin(string resourceName, AudioManager audioManager)
+ : base(DefaultLegacySkin.Info, new TestResourceStore(resourceName), audioManager, "skin.ini")
+ {
+ }
+ }
+
+ private class TestResourceStore : IResourceStore
+ {
+ private readonly string resourceName;
+
+ public TestResourceStore(string resourceName)
+ {
+ this.resourceName = resourceName;
+ }
+
+ public byte[] Get(string name) => name == resourceName ? TestResources.GetStore().Get("Resources/test-sample.mp3") : null;
+
+ public Task GetAsync(string name) => name == resourceName ? TestResources.GetStore().GetAsync("Resources/test-sample.mp3") : null;
+
+ public Stream GetStream(string name) => name == resourceName ? TestResources.GetStore().GetStream("Resources/test-sample.mp3") : null;
+
+ public IEnumerable GetAvailableResources() => new[] { resourceName };
+
+ public void Dispose()
+ {
+ }
+ }
+ }
+}
diff --git a/osu.Game.Tests/Resources/Archives/241526 Soleily - Renatus.osz b/osu.Game.Tests/Resources/Archives/241526 Soleily - Renatus.osz
new file mode 100644
index 0000000000..987dbea6db
Binary files /dev/null and b/osu.Game.Tests/Resources/Archives/241526 Soleily - Renatus.osz differ
diff --git a/osu.Game.Tests/Resources/Archives/241526 Soleily - Renatus_virtual.osz b/osu.Game.Tests/Resources/Archives/241526 Soleily - Renatus_virtual.osz
new file mode 100644
index 0000000000..8a92423d35
Binary files /dev/null and b/osu.Game.Tests/Resources/Archives/241526 Soleily - Renatus_virtual.osz differ
diff --git a/osu.Game.Tests/Resources/TestResources.cs b/osu.Game.Tests/Resources/TestResources.cs
index be9f1dd9b0..7588e27b3e 100644
--- a/osu.Game.Tests/Resources/TestResources.cs
+++ b/osu.Game.Tests/Resources/TestResources.cs
@@ -14,7 +14,7 @@ namespace osu.Game.Tests.Resources
public static Stream OpenResource(string name) => GetStore().GetStream($"Resources/{name}");
- public static Stream GetTestBeatmapStream(bool virtualTrack = false) => new DllResourceStore(OsuResources.ResourceAssembly).GetStream($"Beatmaps/241526 Soleily - Renatus{(virtualTrack ? "_virtual" : "")}.osz");
+ public static Stream GetTestBeatmapStream(bool virtualTrack = false) => OpenResource($"Archives/241526 Soleily - Renatus{(virtualTrack ? "_virtual" : "")}.osz");
public static string GetTestBeatmapForImport(bool virtualTrack = false)
{
diff --git a/osu.Game.Tests/Resources/test-sample.mp3 b/osu.Game.Tests/Resources/test-sample.mp3
new file mode 100644
index 0000000000..f7c344f39a
Binary files /dev/null and b/osu.Game.Tests/Resources/test-sample.mp3 differ
diff --git a/osu.Game.Tests/Visual/Editor/TestSceneComposeScreen.cs b/osu.Game.Tests/Visual/Editor/TestSceneComposeScreen.cs
index 9f16e1d781..3562689482 100644
--- a/osu.Game.Tests/Visual/Editor/TestSceneComposeScreen.cs
+++ b/osu.Game.Tests/Visual/Editor/TestSceneComposeScreen.cs
@@ -4,6 +4,8 @@
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Game.Rulesets.Osu;
+using osu.Game.Rulesets.Osu.Beatmaps;
+using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Compose;
namespace osu.Game.Tests.Visual.Editor
@@ -11,10 +13,21 @@ namespace osu.Game.Tests.Visual.Editor
[TestFixture]
public class TestSceneComposeScreen : EditorClockTestScene
{
+ [Cached(typeof(EditorBeatmap))]
+ private readonly EditorBeatmap editorBeatmap =
+ new EditorBeatmap(new OsuBeatmap
+ {
+ BeatmapInfo =
+ {
+ Ruleset = new OsuRuleset().RulesetInfo
+ }
+ });
+
[BackgroundDependencyLoader]
private void load()
{
- Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
+ Beatmap.Value = CreateWorkingBeatmap(editorBeatmap.PlayableBeatmap);
+
Child = new ComposeScreen();
}
}
diff --git a/osu.Game.Tests/Visual/Editor/TestSceneDistanceSnapGrid.cs b/osu.Game.Tests/Visual/Editor/TestSceneDistanceSnapGrid.cs
index 39b4bf7218..847d168e51 100644
--- a/osu.Game.Tests/Visual/Editor/TestSceneDistanceSnapGrid.cs
+++ b/osu.Game.Tests/Visual/Editor/TestSceneDistanceSnapGrid.cs
@@ -8,7 +8,6 @@ using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Osu.Beatmaps;
-using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Compose.Components;
using osuTK;
@@ -21,15 +20,15 @@ namespace osu.Game.Tests.Visual.Editor
private const double beat_length = 100;
private static readonly Vector2 grid_position = new Vector2(512, 384);
- [Cached(typeof(IEditorBeatmap))]
- private readonly EditorBeatmap editorBeatmap;
+ [Cached(typeof(EditorBeatmap))]
+ private readonly EditorBeatmap editorBeatmap;
[Cached(typeof(IDistanceSnapProvider))]
private readonly SnapProvider snapProvider = new SnapProvider();
public TestSceneDistanceSnapGrid()
{
- editorBeatmap = new EditorBeatmap(new OsuBeatmap());
+ editorBeatmap = new EditorBeatmap(new OsuBeatmap());
editorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = beat_length });
}
diff --git a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs b/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs
index ed6bc5fe0c..29575cb42e 100644
--- a/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs
+++ b/osu.Game.Tests/Visual/Editor/TestSceneEditorComposeTimeline.cs
@@ -38,7 +38,7 @@ namespace osu.Game.Tests.Visual.Editor
{
Beatmap.Value = new WaveformTestBeatmap(audio);
- var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap);
+ var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap);
Children = new Drawable[]
{
diff --git a/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs b/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs
index b7c7028b52..c001c83877 100644
--- a/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs
+++ b/osu.Game.Tests/Visual/Editor/TestSceneHitObjectComposer.cs
@@ -16,6 +16,7 @@ using osu.Game.Rulesets.Osu.Edit;
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles;
using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components;
using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Compose.Components;
using osuTK;
@@ -59,9 +60,12 @@ namespace osu.Game.Tests.Visual.Editor
},
});
+ var editorBeatmap = new EditorBeatmap(Beatmap.Value.GetPlayableBeatmap(new OsuRuleset().RulesetInfo));
+
var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
Dependencies.CacheAs(clock);
Dependencies.CacheAs(clock);
+ Dependencies.CacheAs(editorBeatmap);
Child = new OsuHitObjectComposer(new OsuRuleset());
}
diff --git a/osu.Game.Tests/Visual/Editor/TestSceneTimingScreen.cs b/osu.Game.Tests/Visual/Editor/TestSceneTimingScreen.cs
index 121853d8d0..adfed9a299 100644
--- a/osu.Game.Tests/Visual/Editor/TestSceneTimingScreen.cs
+++ b/osu.Game.Tests/Visual/Editor/TestSceneTimingScreen.cs
@@ -5,7 +5,8 @@ using System;
using System.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Allocation;
-using osu.Game.Rulesets.Osu;
+using osu.Game.Rulesets.Osu.Beatmaps;
+using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Timing;
namespace osu.Game.Tests.Visual.Editor
@@ -25,10 +26,13 @@ namespace osu.Game.Tests.Visual.Editor
typeof(RowAttribute)
};
+ [Cached(typeof(EditorBeatmap))]
+ private readonly EditorBeatmap editorBeatmap = new EditorBeatmap(new OsuBeatmap());
+
[BackgroundDependencyLoader]
private void load()
{
- Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
+ Beatmap.Value = CreateWorkingBeatmap(editorBeatmap.PlayableBeatmap);
Child = new TimingScreen();
}
}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs
index 63b8acb234..63b46c991f 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs
@@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual.Online
typeof(ProfileHeader),
typeof(RankGraph),
typeof(LineGraph),
- typeof(OverlayHeaderTabControl),
+ typeof(TabControlOverlayHeader.OverlayHeaderTabControl),
typeof(CentreHeaderContainer),
typeof(BottomHeaderContainer),
typeof(DetailHeaderContainer),
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbs.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs
similarity index 92%
rename from osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbs.cs
rename to osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs
index 554696765e..19eebc89b6 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbs.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs
@@ -10,11 +10,11 @@ using osu.Game.Graphics.UserInterface;
namespace osu.Game.Tests.Visual.UserInterface
{
[TestFixture]
- public class TestSceneBreadcrumbs : OsuTestScene
+ public class TestSceneBreadcrumbControl : OsuTestScene
{
private readonly BreadcrumbControl breadcrumbs;
- public TestSceneBreadcrumbs()
+ public TestSceneBreadcrumbControl()
{
Add(breadcrumbs = new BreadcrumbControl
{
diff --git a/osu.Game/Audio/HitSampleInfo.cs b/osu.Game/Audio/HitSampleInfo.cs
index 23a74d3fa6..f6b0107bd2 100644
--- a/osu.Game/Audio/HitSampleInfo.cs
+++ b/osu.Game/Audio/HitSampleInfo.cs
@@ -17,11 +17,6 @@ namespace osu.Game.Audio
public const string HIT_NORMAL = @"hitnormal";
public const string HIT_CLAP = @"hitclap";
- ///
- /// An optional ruleset namespace.
- ///
- public string Namespace;
-
///
/// The bank to load the sample from.
///
@@ -49,15 +44,6 @@ namespace osu.Game.Audio
{
get
{
- if (!string.IsNullOrEmpty(Namespace))
- {
- if (!string.IsNullOrEmpty(Suffix))
- yield return $"{Namespace}/{Bank}-{Name}{Suffix}";
-
- yield return $"{Namespace}/{Bank}-{Name}";
- }
-
- // check non-namespace as a fallback even when we have a namespace
if (!string.IsNullOrEmpty(Suffix))
yield return $"{Bank}-{Name}{Suffix}";
diff --git a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs
index 93ea6bbbe6..e2438cc4cd 100644
--- a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs
+++ b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs
@@ -15,14 +15,13 @@ namespace osu.Game.Graphics.UserInterface
public class BreadcrumbControl : OsuTabControl
{
private const float padding = 10;
- private const float item_chevron_size = 10;
protected override TabItem CreateTabItem(T value) => new BreadcrumbTabItem(value)
{
AccentColour = AccentColour,
};
- protected override float StripWidth() => base.StripWidth() - (padding + item_chevron_size);
+ protected override float StripWidth => base.StripWidth - TabContainer.FirstOrDefault()?.Padding.Right ?? 0;
public BreadcrumbControl()
{
@@ -41,8 +40,10 @@ namespace osu.Game.Graphics.UserInterface
};
}
- private class BreadcrumbTabItem : OsuTabItem, IStateful
+ protected class BreadcrumbTabItem : OsuTabItem, IStateful
{
+ protected virtual float ChevronSize => 10;
+
public event Action StateChanged;
public readonly SpriteIcon Chevron;
@@ -90,12 +91,12 @@ namespace osu.Game.Graphics.UserInterface
{
Text.Font = Text.Font.With(size: 18);
Text.Margin = new MarginPadding { Vertical = 8 };
- Padding = new MarginPadding { Right = padding + item_chevron_size };
+ Padding = new MarginPadding { Right = padding + ChevronSize };
Add(Chevron = new SpriteIcon
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreLeft,
- Size = new Vector2(item_chevron_size),
+ Size = new Vector2(ChevronSize),
Icon = FontAwesome.Solid.ChevronRight,
Margin = new MarginPadding { Left = padding },
Alpha = 0f,
diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs
index 064cba6adf..ed8904db7e 100644
--- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs
+++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs
@@ -28,8 +28,7 @@ namespace osu.Game.Graphics.UserInterface
protected override TabItem CreateTabItem(T value) => new OsuTabItem(value);
- protected virtual float StripWidth() => TabContainer.Children.Sum(c => c.IsPresent ? c.DrawWidth + TabContainer.Spacing.X : 0) - TabContainer.Spacing.X;
- protected virtual float StripHeight() => 1;
+ protected virtual float StripWidth => TabContainer.Children.Sum(c => c.IsPresent ? c.DrawWidth + TabContainer.Spacing.X : 0) - TabContainer.Spacing.X;
///
/// Whether entries should be automatically populated if is an type.
@@ -46,7 +45,7 @@ namespace osu.Game.Graphics.UserInterface
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
- Height = StripHeight(),
+ Height = 1,
Colour = Color4.White.Opacity(0),
});
@@ -99,7 +98,7 @@ namespace osu.Game.Graphics.UserInterface
// dont bother calculating if the strip is invisible
if (strip.Colour.MaxAlpha > 0)
- strip.Width = Interpolation.ValueAt(Math.Clamp(Clock.ElapsedFrameTime, 0, 1000), strip.Width, StripWidth(), 0, 500, Easing.OutQuint);
+ strip.Width = Interpolation.ValueAt(Math.Clamp(Clock.ElapsedFrameTime, 0, 1000), strip.Width, StripWidth, 0, 500, Easing.OutQuint);
}
public class OsuTabItem : TabItem, IHasAccentColour
diff --git a/osu.Game/Graphics/UserInterface/SearchTextBox.cs b/osu.Game/Graphics/UserInterface/SearchTextBox.cs
index ff3618b263..fe8756a4d2 100644
--- a/osu.Game/Graphics/UserInterface/SearchTextBox.cs
+++ b/osu.Game/Graphics/UserInterface/SearchTextBox.cs
@@ -34,11 +34,21 @@ namespace osu.Game.Graphics.UserInterface
public override bool OnPressed(PlatformAction action)
{
- // Shift+delete is handled via PlatformAction on macOS. this is not so useful in the context of a SearchTextBox
- // as we do not allow arrow key navigation in the first place (ie. the caret should always be at the end of text)
- // Avoid handling it here to allow other components to potentially consume the shortcut.
- if (action.ActionType == PlatformActionType.CharNext && action.ActionMethod == PlatformActionMethod.Delete)
- return false;
+ switch (action.ActionType)
+ {
+ case PlatformActionType.LineEnd:
+ case PlatformActionType.LineStart:
+ return false;
+
+ // Shift+delete is handled via PlatformAction on macOS. this is not so useful in the context of a SearchTextBox
+ // as we do not allow arrow key navigation in the first place (ie. the caret should always be at the end of text)
+ // Avoid handling it here to allow other components to potentially consume the shortcut.
+ case PlatformActionType.CharNext:
+ if (action.ActionMethod == PlatformActionMethod.Delete)
+ return false;
+
+ break;
+ }
return base.OnPressed(action);
}
diff --git a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs
new file mode 100644
index 0000000000..8a82b1f0c0
--- /dev/null
+++ b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs
@@ -0,0 +1,39 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.UserInterface;
+using osu.Game.Graphics.UserInterface;
+
+namespace osu.Game.Overlays
+{
+ public abstract class BreadcrumbControlOverlayHeader : OverlayHeader
+ {
+ protected OverlayHeaderBreadcrumbControl BreadcrumbControl;
+
+ protected override TabControl CreateTabControl() => BreadcrumbControl = new OverlayHeaderBreadcrumbControl();
+
+ public class OverlayHeaderBreadcrumbControl : BreadcrumbControl
+ {
+ public OverlayHeaderBreadcrumbControl()
+ {
+ RelativeSizeAxes = Axes.X;
+ }
+
+ protected override TabItem CreateTabItem(string value) => new ControlTabItem(value);
+
+ private class ControlTabItem : BreadcrumbTabItem
+ {
+ protected override float ChevronSize => 8;
+
+ public ControlTabItem(string value)
+ : base(value)
+ {
+ Text.Font = Text.Font.With(size: 14);
+ Chevron.Y = 3;
+ Bar.Height = 0;
+ }
+ }
+ }
+ }
+}
diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs
index 3b6f0d778d..7e47a3e29f 100644
--- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs
+++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs
@@ -15,7 +15,7 @@ using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Overlays.Changelog
{
- public class ChangelogHeader : OverlayHeader
+ public class ChangelogHeader : BreadcrumbControlOverlayHeader
{
public readonly Bindable Current = new Bindable();
@@ -23,12 +23,12 @@ namespace osu.Game.Overlays.Changelog
public UpdateStreamBadgeArea Streams;
- private const string listing_string = "Listing";
+ private const string listing_string = "listing";
public ChangelogHeader()
{
- TabControl.AddItem(listing_string);
- TabControl.Current.ValueChanged += e =>
+ BreadcrumbControl.AddItem(listing_string);
+ BreadcrumbControl.Current.ValueChanged += e =>
{
if (e.NewValue == listing_string)
ListingSelected?.Invoke();
@@ -46,7 +46,7 @@ namespace osu.Game.Overlays.Changelog
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
- TabControl.AccentColour = colours.Violet;
+ BreadcrumbControl.AccentColour = colours.Violet;
TitleBackgroundColour = colours.GreyVioletDarker;
ControlBackgroundColour = colours.GreyVioletDark;
}
@@ -56,12 +56,12 @@ namespace osu.Game.Overlays.Changelog
private void showBuild(ValueChangedEvent e)
{
if (e.OldValue != null)
- TabControl.RemoveItem(e.OldValue.ToString());
+ BreadcrumbControl.RemoveItem(e.OldValue.ToString());
if (e.NewValue != null)
{
- TabControl.AddItem(e.NewValue.ToString());
- TabControl.Current.Value = e.NewValue.ToString();
+ BreadcrumbControl.AddItem(e.NewValue.ToString());
+ BreadcrumbControl.Current.Value = e.NewValue.ToString();
Streams.Current.Value = Streams.Items.FirstOrDefault(s => s.Name == e.NewValue.UpdateStream.Name);
@@ -69,7 +69,7 @@ namespace osu.Game.Overlays.Changelog
}
else
{
- TabControl.Current.Value = listing_string;
+ BreadcrumbControl.Current.Value = listing_string;
Streams.Current.Value = null;
title.Version = null;
}
diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs
index fbc9dfcbd9..15b0079277 100644
--- a/osu.Game/Overlays/ChangelogOverlay.cs
+++ b/osu.Game/Overlays/ChangelogOverlay.cs
@@ -158,7 +158,8 @@ namespace osu.Game.Overlays
private Task initialFetchTask;
- private void performAfterFetch(Action action) => fetchListing()?.ContinueWith(_ => Schedule(action));
+ private void performAfterFetch(Action action) => fetchListing()?.ContinueWith(_ =>
+ Schedule(action), TaskContinuationOptions.OnlyOnRanToCompletion);
private Task fetchListing()
{
@@ -185,10 +186,10 @@ namespace osu.Game.Overlays
tcs.SetResult(true);
});
- req.Failure += _ =>
+ req.Failure += e =>
{
initialFetchTask = null;
- tcs.SetResult(false);
+ tcs.SetException(e);
};
await API.PerformAsync(req);
diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs
index c1c5113c5e..4ad8e95512 100644
--- a/osu.Game/Overlays/Direct/DirectPanel.cs
+++ b/osu.Game/Overlays/Direct/DirectPanel.cs
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
@@ -9,21 +10,25 @@ using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
+using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics;
+using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
+using osu.Game.Graphics.UserInterface;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Overlays.Direct
{
- public abstract class DirectPanel : Container
+ public abstract class DirectPanel : OsuClickableContainer, IHasContextMenu
{
public readonly BeatmapSetInfo SetInfo;
@@ -32,8 +37,6 @@ namespace osu.Game.Overlays.Direct
private Container content;
- private BeatmapSetOverlay beatmapSetOverlay;
-
public PreviewTrack Preview => PlayButton.Preview;
public Bindable PreviewPlaying => PlayButton?.Playing;
@@ -44,6 +47,8 @@ namespace osu.Game.Overlays.Direct
protected override Container Content => content;
+ protected Action ViewBeatmap;
+
protected DirectPanel(BeatmapSetInfo setInfo)
{
Debug.Assert(setInfo.OnlineBeatmapSetID != null);
@@ -70,8 +75,6 @@ namespace osu.Game.Overlays.Direct
[BackgroundDependencyLoader(permitNulls: true)]
private void load(BeatmapManager beatmaps, OsuColour colours, BeatmapSetOverlay beatmapSetOverlay)
{
- this.beatmapSetOverlay = beatmapSetOverlay;
-
AddInternal(content = new Container
{
RelativeSizeAxes = Axes.Both,
@@ -88,6 +91,12 @@ namespace osu.Game.Overlays.Direct
},
}
});
+
+ Action = ViewBeatmap = () =>
+ {
+ Debug.Assert(SetInfo.OnlineBeatmapSetID != null);
+ beatmapSetOverlay?.FetchAndShowBeatmapSet(SetInfo.OnlineBeatmapSetID.Value);
+ };
}
protected override void Update()
@@ -120,13 +129,6 @@ namespace osu.Game.Overlays.Direct
base.OnHoverLost(e);
}
- protected override bool OnClick(ClickEvent e)
- {
- Debug.Assert(SetInfo.OnlineBeatmapSetID != null);
- beatmapSetOverlay?.FetchAndShowBeatmapSet(SetInfo.OnlineBeatmapSetID.Value);
- return true;
- }
-
protected override void LoadComplete()
{
base.LoadComplete();
@@ -203,5 +205,10 @@ namespace osu.Game.Overlays.Direct
Value = value;
}
}
+
+ public MenuItem[] ContextMenuItems => new MenuItem[]
+ {
+ new OsuMenuItem("View Beatmap", MenuItemType.Highlighted, ViewBeatmap),
+ };
}
}
diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs
index e3cf58ed0a..fc88c86df2 100644
--- a/osu.Game/Overlays/News/NewsHeader.cs
+++ b/osu.Game/Overlays/News/NewsHeader.cs
@@ -12,7 +12,7 @@ using System;
namespace osu.Game.Overlays.News
{
- public class NewsHeader : OverlayHeader
+ public class NewsHeader : BreadcrumbControlOverlayHeader
{
private const string front_page_string = "frontpage";
@@ -24,9 +24,9 @@ namespace osu.Game.Overlays.News
public NewsHeader()
{
- TabControl.AddItem(front_page_string);
+ BreadcrumbControl.AddItem(front_page_string);
- TabControl.Current.ValueChanged += e =>
+ BreadcrumbControl.Current.ValueChanged += e =>
{
if (e.NewValue == front_page_string)
ShowFrontPage?.Invoke();
@@ -38,7 +38,7 @@ namespace osu.Game.Overlays.News
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
- TabControl.AccentColour = colours.Violet;
+ BreadcrumbControl.AccentColour = colours.Violet;
TitleBackgroundColour = colours.GreyVioletDarker;
ControlBackgroundColour = colours.GreyVioletDark;
}
@@ -46,18 +46,18 @@ namespace osu.Game.Overlays.News
private void showPost(ValueChangedEvent e)
{
if (e.OldValue != null)
- TabControl.RemoveItem(e.OldValue);
+ BreadcrumbControl.RemoveItem(e.OldValue);
if (e.NewValue != null)
{
- TabControl.AddItem(e.NewValue);
- TabControl.Current.Value = e.NewValue;
+ BreadcrumbControl.AddItem(e.NewValue);
+ BreadcrumbControl.Current.Value = e.NewValue;
title.IsReadingPost = true;
}
else
{
- TabControl.Current.Value = front_page_string;
+ BreadcrumbControl.Current.Value = front_page_string;
title.IsReadingPost = false;
}
}
diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs
index 7a397d10c6..53da2da634 100644
--- a/osu.Game/Overlays/OverlayHeader.cs
+++ b/osu.Game/Overlays/OverlayHeader.cs
@@ -5,6 +5,7 @@ using JetBrains.Annotations;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
+using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.UserInterface;
using osuTK.Graphics;
@@ -12,8 +13,6 @@ namespace osu.Game.Overlays
{
public abstract class OverlayHeader : Container
{
- protected readonly OverlayHeaderTabControl TabControl;
-
private readonly Box titleBackground;
private readonly Box controlBackground;
private readonly Container background;
@@ -85,14 +84,7 @@ namespace osu.Game.Overlays
RelativeSizeAxes = Axes.Both,
Colour = Color4.Gray,
},
- TabControl = new OverlayHeaderTabControl
- {
- Anchor = Anchor.BottomLeft,
- Origin = Anchor.BottomLeft,
- RelativeSizeAxes = Axes.X,
- Height = 30,
- Padding = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN },
- }
+ CreateTabControl().With(control => control.Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN })
}
},
CreateContent()
@@ -106,5 +98,7 @@ namespace osu.Game.Overlays
protected virtual Drawable CreateContent() => new Container();
protected abstract ScreenTitle CreateTitle();
+
+ protected abstract TabControl CreateTabControl();
}
}
diff --git a/osu.Game/Overlays/OverlayHeaderTabControl.cs b/osu.Game/Overlays/OverlayHeaderTabControl.cs
deleted file mode 100644
index 7d0cdad6d8..0000000000
--- a/osu.Game/Overlays/OverlayHeaderTabControl.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
-// See the LICENCE file in the repository root for full licence text.
-
-using osu.Framework.Graphics.UserInterface;
-
-namespace osu.Game.Overlays
-{
- public class OverlayHeaderTabControl : OverlayTabControl
- {
- protected override TabItem CreateTabItem(string value) => new OverlayHeaderTabItem(value)
- {
- AccentColour = AccentColour,
- };
-
- private class OverlayHeaderTabItem : OverlayTabItem
- {
- public OverlayHeaderTabItem(string value)
- : base(value)
- {
- Text.Text = value;
- }
- }
- }
-}
diff --git a/osu.Game/Overlays/OverlayTabControl.cs b/osu.Game/Overlays/OverlayTabControl.cs
index 4c396eabc1..812f8963c9 100644
--- a/osu.Game/Overlays/OverlayTabControl.cs
+++ b/osu.Game/Overlays/OverlayTabControl.cs
@@ -43,6 +43,11 @@ namespace osu.Game.Overlays
set => TabContainer.Padding = value;
}
+ protected float BarHeight
+ {
+ set => bar.Height = value;
+ }
+
protected OverlayTabControl()
{
TabContainer.Masking = false;
@@ -63,8 +68,7 @@ namespace osu.Game.Overlays
protected class OverlayTabItem : TabItem
{
- private readonly ExpandingBar bar;
-
+ protected readonly ExpandingBar Bar;
protected readonly OsuSpriteText Text;
private Color4 accentColour;
@@ -78,7 +82,7 @@ namespace osu.Game.Overlays
return;
accentColour = value;
- bar.Colour = value;
+ Bar.Colour = value;
updateState();
}
@@ -99,7 +103,7 @@ namespace osu.Game.Overlays
Anchor = Anchor.BottomLeft,
Font = OsuFont.GetFont(),
},
- bar = new ExpandingBar
+ Bar = new ExpandingBar
{
Anchor = Anchor.BottomCentre,
ExpandedSize = 7.5f,
@@ -149,13 +153,13 @@ namespace osu.Game.Overlays
protected virtual void HoverAction()
{
- bar.Expand();
+ Bar.Expand();
Text.FadeColour(Color4.White, 120, Easing.InQuad);
}
protected virtual void UnhoverAction()
{
- bar.Collapse();
+ Bar.Collapse();
Text.FadeColour(AccentColour, 120, Easing.InQuad);
}
}
diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs
index 4a792f7375..59e64dfc26 100644
--- a/osu.Game/Overlays/Profile/ProfileHeader.cs
+++ b/osu.Game/Overlays/Profile/ProfileHeader.cs
@@ -15,7 +15,7 @@ using osu.Game.Users;
namespace osu.Game.Overlays.Profile
{
- public class ProfileHeader : OverlayHeader
+ public class ProfileHeader : TabControlOverlayHeader
{
private UserCoverBackground coverContainer;
@@ -30,8 +30,8 @@ namespace osu.Game.Overlays.Profile
User.ValueChanged += e => updateDisplay(e.NewValue);
- TabControl.AddItem("Info");
- TabControl.AddItem("Modding");
+ TabControl.AddItem("info");
+ TabControl.AddItem("modding");
centreHeaderContainer.DetailsVisible.BindValueChanged(visible => detailHeaderContainer.Expanded = visible.NewValue, true);
}
diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs
index 37478d902b..5975e94ffc 100644
--- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs
+++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs
@@ -9,6 +9,7 @@ using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Containers;
+using osu.Game.Graphics.Cursor;
namespace osu.Game.Overlays.SearchableList
{
@@ -61,21 +62,20 @@ namespace osu.Game.Overlays.SearchableList
scrollContainer = new Container
{
RelativeSizeAxes = Axes.Both,
- Children = new[]
+ Child = new OsuContextMenuContainer
{
- new OsuScrollContainer
+ RelativeSizeAxes = Axes.Both,
+ Masking = true,
+ Child = new OsuScrollContainer
{
RelativeSizeAxes = Axes.Both,
ScrollbarVisible = false,
- Children = new[]
+ Child = ScrollFlow = new FillFlowContainer
{
- ScrollFlow = new FillFlowContainer
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Padding = new MarginPadding { Horizontal = WIDTH_PADDING, Bottom = 50 },
- Direction = FillDirection.Vertical,
- },
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Padding = new MarginPadding { Horizontal = WIDTH_PADDING, Bottom = 50 },
+ Direction = FillDirection.Vertical,
},
},
},
diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs
new file mode 100644
index 0000000000..f3521b66c8
--- /dev/null
+++ b/osu.Game/Overlays/TabControlOverlayHeader.cs
@@ -0,0 +1,55 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.UserInterface;
+using osu.Game.Graphics;
+using osuTK;
+
+namespace osu.Game.Overlays
+{
+ public abstract class TabControlOverlayHeader : OverlayHeader
+ {
+ protected OverlayHeaderTabControl TabControl;
+
+ protected override TabControl CreateTabControl() => TabControl = new OverlayHeaderTabControl();
+
+ public class OverlayHeaderTabControl : OverlayTabControl
+ {
+ public OverlayHeaderTabControl()
+ {
+ BarHeight = 1;
+ RelativeSizeAxes = Axes.None;
+ AutoSizeAxes = Axes.X;
+ Anchor = Anchor.BottomLeft;
+ Origin = Anchor.BottomLeft;
+ Height = 35;
+ }
+
+ protected override TabItem CreateTabItem(string value) => new OverlayHeaderTabItem(value)
+ {
+ AccentColour = AccentColour,
+ };
+
+ protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer
+ {
+ RelativeSizeAxes = Axes.Y,
+ AutoSizeAxes = Axes.X,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(5, 0),
+ };
+
+ private class OverlayHeaderTabItem : OverlayTabItem
+ {
+ public OverlayHeaderTabItem(string value)
+ : base(value)
+ {
+ Text.Text = value;
+ Text.Font = OsuFont.GetFont(size: 14);
+ Bar.ExpandedSize = 5;
+ }
+ }
+ }
+ }
+}
diff --git a/osu.Game/Rulesets/Edit/DrawableEditRulesetWrapper.cs b/osu.Game/Rulesets/Edit/DrawableEditRulesetWrapper.cs
index 4710465536..89e7866707 100644
--- a/osu.Game/Rulesets/Edit/DrawableEditRulesetWrapper.cs
+++ b/osu.Game/Rulesets/Edit/DrawableEditRulesetWrapper.cs
@@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Edit
private readonly DrawableRuleset drawableRuleset;
[Resolved]
- private IEditorBeatmap beatmap { get; set; }
+ private EditorBeatmap beatmap { get; set; }
public DrawableEditRulesetWrapper(DrawableRuleset drawableRuleset)
{
diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs
index 22d94abcb9..bfaa7e8872 100644
--- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs
+++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs
@@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Allocation;
-using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
@@ -35,20 +34,20 @@ namespace osu.Game.Rulesets.Edit
{
protected IRulesetConfigManager Config { get; private set; }
- protected new EditorBeatmap EditorBeatmap { get; private set; }
-
protected readonly Ruleset Ruleset;
[Resolved]
protected IFrameBasedClock EditorClock { get; private set; }
+ [Resolved]
+ protected EditorBeatmap EditorBeatmap { get; private set; }
+
[Resolved]
private IAdjustableClock adjustableClock { get; set; }
[Resolved]
private BindableBeatDivisor beatDivisor { get; set; }
- private Beatmap playableBeatmap;
private IBeatmapProcessor beatmapProcessor;
private DrawableEditRulesetWrapper drawableRulesetWrapper;
@@ -68,9 +67,17 @@ namespace osu.Game.Rulesets.Edit
[BackgroundDependencyLoader]
private void load(IFrameBasedClock framedClock)
{
+ beatmapProcessor = Ruleset.CreateBeatmapProcessor(EditorBeatmap.PlayableBeatmap);
+
+ EditorBeatmap.HitObjectAdded += addHitObject;
+ EditorBeatmap.HitObjectRemoved += removeHitObject;
+ EditorBeatmap.StartTimeChanged += UpdateHitObject;
+
+ Config = Dependencies.Get().GetConfigFor(Ruleset);
+
try
{
- drawableRulesetWrapper = new DrawableEditRulesetWrapper(CreateDrawableRuleset(Ruleset, playableBeatmap))
+ drawableRulesetWrapper = new DrawableEditRulesetWrapper(CreateDrawableRuleset(Ruleset, EditorBeatmap.PlayableBeatmap))
{
Clock = framedClock,
ProcessCustomClock = false
@@ -140,28 +147,6 @@ namespace osu.Game.Rulesets.Edit
blueprintContainer.SelectionChanged += selectionChanged;
}
- protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
- {
- var parentWorkingBeatmap = parent.Get>().Value;
-
- playableBeatmap = (Beatmap)parentWorkingBeatmap.GetPlayableBeatmap(Ruleset.RulesetInfo);
-
- beatmapProcessor = Ruleset.CreateBeatmapProcessor(playableBeatmap);
-
- base.EditorBeatmap = EditorBeatmap = new EditorBeatmap(playableBeatmap);
- EditorBeatmap.HitObjectAdded += addHitObject;
- EditorBeatmap.HitObjectRemoved += removeHitObject;
- EditorBeatmap.StartTimeChanged += UpdateHitObject;
-
- var dependencies = new DependencyContainer(parent);
- dependencies.CacheAs(EditorBeatmap);
- dependencies.CacheAs>(EditorBeatmap);
-
- Config = dependencies.Get().GetConfigFor(Ruleset);
-
- return base.CreateChildDependencies(dependencies);
- }
-
protected override void LoadComplete()
{
base.LoadComplete();
@@ -234,7 +219,7 @@ namespace osu.Game.Rulesets.Edit
scheduledUpdate = Schedule(() =>
{
beatmapProcessor?.PreProcess();
- hitObject?.ApplyDefaults(playableBeatmap.ControlPointInfo, playableBeatmap.BeatmapInfo.BaseDifficulty);
+ hitObject?.ApplyDefaults(EditorBeatmap.ControlPointInfo, EditorBeatmap.BeatmapInfo.BaseDifficulty);
beatmapProcessor?.PostProcess();
});
}
@@ -333,11 +318,6 @@ namespace osu.Game.Rulesets.Edit
///
public abstract IEnumerable HitObjects { get; }
- ///
- /// An editor-specific beatmap, exposing mutation events.
- ///
- public IEditorBeatmap EditorBeatmap { get; protected set; }
-
///
/// Whether the user's cursor is currently in an area of the that is valid for placement.
///
diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
index a959fee9be..4ac30fe7fb 100644
--- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
+++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
@@ -31,9 +31,6 @@ namespace osu.Game.Rulesets.Objects.Drawables
///
public readonly Bindable AccentColour = new Bindable(Color4.Gray);
- // Todo: Rulesets should be overriding the resources instead, but we need to figure out where/when to apply overrides first
- protected virtual string SampleNamespace => null;
-
protected SkinnableSound Samples { get; private set; }
protected virtual IEnumerable GetSamples() => HitObject.Samples;
@@ -154,11 +151,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
+ $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}.");
}
- samples = samples.Select(s => HitObject.SampleControlPoint.ApplyTo(s)).ToArray();
- foreach (var s in samples)
- s.Namespace = SampleNamespace;
-
- AddInternal(Samples = new SkinnableSound(samples));
+ AddInternal(Samples = new SkinnableSound(samples.Select(s => HitObject.SampleControlPoint.ApplyTo(s))));
}
private void onDefaultsApplied() => apply(HitObject);
diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
index 195bc663f1..cafaddc39e 100644
--- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
@@ -40,7 +40,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
private HitObjectComposer composer { get; set; }
[Resolved]
- private IEditorBeatmap beatmap { get; set; }
+ private EditorBeatmap beatmap { get; set; }
public BlueprintContainer()
{
diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs
index 00326d04f7..53c5cf97fa 100644
--- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs
@@ -45,7 +45,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
protected IDistanceSnapProvider SnapProvider { get; private set; }
[Resolved]
- private IEditorBeatmap beatmap { get; set; }
+ private EditorBeatmap beatmap { get; set; }
[Resolved]
private BindableBeatDivisor beatDivisor { get; set; }
diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs
index db4aca75e5..b20f2fa11d 100644
--- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectDisplay.cs
@@ -16,9 +16,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
internal class TimelineHitObjectDisplay : TimelinePart
{
- private IEditorBeatmap beatmap { get; }
+ private EditorBeatmap beatmap { get; }
- public TimelineHitObjectDisplay(IEditorBeatmap beatmap)
+ public TimelineHitObjectDisplay(EditorBeatmap beatmap)
{
RelativeSizeAxes = Axes.Both;
diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs
index 5d9757778d..1a6aae294a 100644
--- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs
+++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs
@@ -32,6 +32,6 @@ namespace osu.Game.Screens.Edit.Compose
return beatmapSkinProvider.WithChild(rulesetSkinProvider.WithChild(composer));
}
- protected override Drawable CreateTimelineContent() => composer == null ? base.CreateTimelineContent() : new TimelineHitObjectDisplay(composer.EditorBeatmap);
+ protected override Drawable CreateTimelineContent() => composer == null ? base.CreateTimelineContent() : new TimelineHitObjectDisplay(EditorBeatmap);
}
}
diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs
index 1b4964c068..14d69cddd1 100644
--- a/osu.Game/Screens/Edit/Editor.cs
+++ b/osu.Game/Screens/Edit/Editor.cs
@@ -23,6 +23,7 @@ using osuTK.Input;
using System.Collections.Generic;
using osu.Framework;
using osu.Framework.Input.Bindings;
+using osu.Game.Beatmaps;
using osu.Game.Graphics.Cursor;
using osu.Game.Input.Bindings;
using osu.Game.Screens.Edit.Compose;
@@ -49,9 +50,11 @@ namespace osu.Game.Screens.Edit
private EditorScreen currentScreen;
private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor();
-
private EditorClock clock;
+ private IBeatmap playableBeatmap;
+ private EditorBeatmap editorBeatmap;
+
private DependencyContainer dependencies;
private GameHost host;
@@ -73,9 +76,13 @@ namespace osu.Game.Screens.Edit
clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false };
clock.ChangeSource(sourceClock);
+ playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset);
+ editorBeatmap = new EditorBeatmap(playableBeatmap);
+
dependencies.CacheAs(clock);
dependencies.CacheAs(clock);
dependencies.Cache(beatDivisor);
+ dependencies.CacheAs(editorBeatmap);
EditorMenuBar menuBar;
diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs
index c3a322ea36..6ed74dfdb0 100644
--- a/osu.Game/Screens/Edit/EditorBeatmap.cs
+++ b/osu.Game/Screens/Edit/EditorBeatmap.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
+using System.Collections;
using System.Collections.Generic;
using osu.Framework.Bindables;
using osu.Game.Beatmaps;
@@ -11,30 +12,30 @@ using osu.Game.Rulesets.Objects;
namespace osu.Game.Screens.Edit
{
- public class EditorBeatmap : IEditorBeatmap
- where T : HitObject
+ public class EditorBeatmap : IBeatmap
{
///
- /// Invoked when a is added to this .
+ /// Invoked when a is added to this .
///
public event Action HitObjectAdded;
///
- /// Invoked when a is removed from this .
+ /// Invoked when a is removed from this .
///
public event Action HitObjectRemoved;
///
- /// Invoked when the start time of a in this was changed.
+ /// Invoked when the start time of a in this was changed.
///
public event Action StartTimeChanged;
- private readonly Dictionary> startTimeBindables = new Dictionary>();
- private readonly Beatmap beatmap;
+ public readonly IBeatmap PlayableBeatmap;
- public EditorBeatmap(Beatmap beatmap)
+ private readonly Dictionary> startTimeBindables = new Dictionary>();
+
+ public EditorBeatmap(IBeatmap playableBeatmap)
{
- this.beatmap = beatmap;
+ PlayableBeatmap = playableBeatmap;
foreach (var obj in HitObjects)
trackStartTime(obj);
@@ -42,82 +43,83 @@ namespace osu.Game.Screens.Edit
public BeatmapInfo BeatmapInfo
{
- get => beatmap.BeatmapInfo;
- set => beatmap.BeatmapInfo = value;
+ get => PlayableBeatmap.BeatmapInfo;
+ set => PlayableBeatmap.BeatmapInfo = value;
}
- public BeatmapMetadata Metadata => beatmap.Metadata;
+ public BeatmapMetadata Metadata => PlayableBeatmap.Metadata;
- public ControlPointInfo ControlPointInfo => beatmap.ControlPointInfo;
+ public ControlPointInfo ControlPointInfo => PlayableBeatmap.ControlPointInfo;
- public List Breaks => beatmap.Breaks;
+ public List Breaks => PlayableBeatmap.Breaks;
- public double TotalBreakTime => beatmap.TotalBreakTime;
+ public double TotalBreakTime => PlayableBeatmap.TotalBreakTime;
- public IReadOnlyList HitObjects => beatmap.HitObjects;
+ public IReadOnlyList HitObjects => PlayableBeatmap.HitObjects;
- IReadOnlyList IBeatmap.HitObjects => beatmap.HitObjects;
+ public IEnumerable GetStatistics() => PlayableBeatmap.GetStatistics();
- public IEnumerable GetStatistics() => beatmap.GetStatistics();
+ public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone();
- public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone();
+ private IList mutableHitObjects => (IList)PlayableBeatmap.HitObjects;
///
- /// Adds a to this .
+ /// Adds a to this .
///
/// The to add.
- public void Add(T hitObject)
+ public void Add(HitObject hitObject)
{
trackStartTime(hitObject);
// Preserve existing sorting order in the beatmap
- var insertionIndex = beatmap.HitObjects.FindLastIndex(h => h.StartTime <= hitObject.StartTime);
- beatmap.HitObjects.Insert(insertionIndex + 1, hitObject);
+ var insertionIndex = findInsertionIndex(PlayableBeatmap.HitObjects, hitObject.StartTime);
+ mutableHitObjects.Insert(insertionIndex + 1, hitObject);
HitObjectAdded?.Invoke(hitObject);
}
///
- /// Removes a from this .
+ /// Removes a from this .
///
/// The to add.
- public void Remove(T hitObject)
+ public void Remove(HitObject hitObject)
{
- if (beatmap.HitObjects.Remove(hitObject))
- {
- var bindable = startTimeBindables[hitObject];
- bindable.UnbindAll();
+ if (!mutableHitObjects.Contains(hitObject))
+ return;
- startTimeBindables.Remove(hitObject);
- HitObjectRemoved?.Invoke(hitObject);
- }
+ mutableHitObjects.Remove(hitObject);
+
+ var bindable = startTimeBindables[hitObject];
+ bindable.UnbindAll();
+
+ startTimeBindables.Remove(hitObject);
+ HitObjectRemoved?.Invoke(hitObject);
}
- private void trackStartTime(T hitObject)
+ private void trackStartTime(HitObject hitObject)
{
startTimeBindables[hitObject] = hitObject.StartTimeBindable.GetBoundCopy();
startTimeBindables[hitObject].ValueChanged += _ =>
{
// For now we'll remove and re-add the hitobject. This is not optimal and can be improved if required.
- beatmap.HitObjects.Remove(hitObject);
+ mutableHitObjects.Remove(hitObject);
- var insertionIndex = beatmap.HitObjects.FindLastIndex(h => h.StartTime <= hitObject.StartTime);
- beatmap.HitObjects.Insert(insertionIndex + 1, hitObject);
+ var insertionIndex = findInsertionIndex(PlayableBeatmap.HitObjects, hitObject.StartTime);
+ mutableHitObjects.Insert(insertionIndex + 1, hitObject);
StartTimeChanged?.Invoke(hitObject);
};
}
- ///
- /// Adds a to this .
- ///
- /// The to add.
- public void Add(HitObject hitObject) => Add((T)hitObject);
+ private int findInsertionIndex(IReadOnlyList list, double startTime)
+ {
+ for (int i = 0; i < list.Count; i++)
+ {
+ if (list[i].StartTime > startTime)
+ return i - 1;
+ }
- ///
- /// Removes a from this .
- ///
- /// The to add.
- public void Remove(HitObject hitObject) => Remove((T)hitObject);
+ return list.Count - 1;
+ }
}
}
diff --git a/osu.Game/Screens/Edit/EditorScreen.cs b/osu.Game/Screens/Edit/EditorScreen.cs
index 1b57c703ae..d42447ac4b 100644
--- a/osu.Game/Screens/Edit/EditorScreen.cs
+++ b/osu.Game/Screens/Edit/EditorScreen.cs
@@ -17,6 +17,9 @@ namespace osu.Game.Screens.Edit
[Resolved]
protected IBindable Beatmap { get; private set; }
+ [Resolved]
+ protected EditorBeatmap EditorBeatmap { get; private set; }
+
protected override Container Content => content;
private readonly Container content;
diff --git a/osu.Game/Screens/Edit/IEditorBeatmap.cs b/osu.Game/Screens/Edit/IEditorBeatmap.cs
deleted file mode 100644
index 3e3418ef79..0000000000
--- a/osu.Game/Screens/Edit/IEditorBeatmap.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
-// See the LICENCE file in the repository root for full licence text.
-
-using System;
-using osu.Game.Beatmaps;
-using osu.Game.Rulesets.Edit;
-using osu.Game.Rulesets.Objects;
-
-namespace osu.Game.Screens.Edit
-{
- ///
- /// Interface for the contained by the see .
- /// Children of may resolve the beatmap via or .
- ///
- public interface IEditorBeatmap : IBeatmap
- {
- ///
- /// Invoked when a is added to this .
- ///
- event Action HitObjectAdded;
-
- ///
- /// Invoked when a is removed from this .
- ///
- event Action HitObjectRemoved;
-
- ///
- /// Invoked when the start time of a in this was changed.
- ///
- event Action StartTimeChanged;
- }
-
- ///
- /// Interface for the contained by the see .
- /// Children of may resolve the beatmap via or .
- ///
- public interface IEditorBeatmap : IEditorBeatmap, IBeatmap
- where T : HitObject
- {
- }
-}
diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs
index 48c520986a..671d37fda4 100644
--- a/osu.Game/Skinning/LegacySkin.cs
+++ b/osu.Game/Skinning/LegacySkin.cs
@@ -175,7 +175,7 @@ namespace osu.Game.Skinning
{
foreach (var lookup in sampleInfo.LookupNames)
{
- var sample = Samples?.Get(getFallbackName(lookup));
+ var sample = Samples?.Get(lookup);
if (sample != null)
return sample;
diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs
index 18dbd212cc..8926c76018 100644
--- a/osu.Game/Tests/Visual/OsuTestScene.cs
+++ b/osu.Game/Tests/Visual/OsuTestScene.cs
@@ -105,7 +105,7 @@ namespace osu.Game.Tests.Visual
}
[Resolved]
- private AudioManager audio { get; set; }
+ protected AudioManager Audio { get; private set; }
protected virtual IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(ruleset);
@@ -113,7 +113,7 @@ namespace osu.Game.Tests.Visual
CreateWorkingBeatmap(CreateBeatmap(ruleset), null);
protected virtual WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) =>
- new ClockBackedTestWorkingBeatmap(beatmap, storyboard, Clock, audio);
+ new ClockBackedTestWorkingBeatmap(beatmap, storyboard, Clock, Audio);
[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 806aadde84..565608b40f 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -22,7 +22,7 @@
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 230ff01cce..60355b8592 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -73,7 +73,7 @@
-
+
diff --git a/osu.iOS/Info.plist b/osu.iOS/Info.plist
index 5ceccdf99f..249474b1d7 100644
--- a/osu.iOS/Info.plist
+++ b/osu.iOS/Info.plist
@@ -14,8 +14,6 @@
0.1.0
LSRequiresIPhoneOS
- LSSupportsOpeningDocumentsInPlace
-
MinimumOSVersion
10.0
UIDeviceFamily
@@ -23,6 +21,8 @@
1
2
+ UIFileSharingEnabled
+
UILaunchStoryboardName
LaunchScreen
UIRequiredDeviceCapabilities
@@ -51,7 +51,7 @@
UTTypeConformsTo
-
+ public.data
UTTypeIdentifier
sh.ppy.osu.items
@@ -105,6 +105,8 @@
Owner
CFBundleTypeName
Supported osu! files
+ CFBundleTypeRole
+ Viewer
LSItemContentTypes
sh.ppy.osu.items