diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1d5c565d60..320197b88e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -78,15 +78,6 @@ jobs:
with:
dotnet-version: "6.0.x"
- # FIXME: libavformat is not included in Ubuntu. Let's fix that.
- # https://github.com/ppy/osu-framework/issues/4349
- # Remove this once https://github.com/actions/virtual-environments/issues/3306 has been resolved.
- - name: Install libavformat-dev
- if: ${{matrix.os.fullname == 'ubuntu-latest'}}
- run: |
- sudo apt-get update && \
- sudo apt-get -y install libavformat-dev
-
- name: Compile
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf
diff --git a/osu.Android.props b/osu.Android.props
index aaea784852..d5a77c6349 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -52,7 +52,7 @@
-
+
diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaComposeScreen.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaComposeScreen.cs
index 5dd7c23ab6..746bdae02e 100644
--- a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaComposeScreen.cs
+++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaComposeScreen.cs
@@ -9,6 +9,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Database;
+using osu.Game.Overlays;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Screens.Edit;
@@ -45,6 +46,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor
{
(typeof(EditorBeatmap), editorBeatmap),
(typeof(IBeatSnapProvider), editorBeatmap),
+ (typeof(OverlayColourProvider), new OverlayColourProvider(OverlayColourScheme.Green)),
},
Child = new ComposeScreen { State = { Value = Visibility.Visible } },
};
diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
index 89baaf228d..e2d9910b82 100644
--- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
+++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
@@ -898,5 +898,24 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.That(controlPoints[3].Type, Is.Null);
}
}
+
+ [Test]
+ public void TestLegacyDuplicateInitialCatmullPointIsMerged()
+ {
+ var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
+
+ using (var resStream = TestResources.OpenResource("catmull-duplicate-initial-controlpoint.osu"))
+ using (var stream = new LineBufferedReader(resStream))
+ {
+ var decoded = decoder.Decode(stream);
+ var controlPoints = ((IHasPath)decoded.HitObjects[0]).Path.ControlPoints;
+
+ Assert.That(controlPoints.Count, Is.EqualTo(4));
+ Assert.That(controlPoints[0].Type, Is.EqualTo(PathType.Catmull));
+ Assert.That(controlPoints[0].Position, Is.EqualTo(Vector2.Zero));
+ Assert.That(controlPoints[1].Type, Is.Null);
+ Assert.That(controlPoints[1].Position, Is.Not.EqualTo(Vector2.Zero));
+ }
+ }
}
}
diff --git a/osu.Game.Tests/Resources/catmull-duplicate-initial-controlpoint.osu b/osu.Game.Tests/Resources/catmull-duplicate-initial-controlpoint.osu
new file mode 100644
index 0000000000..7062229eed
--- /dev/null
+++ b/osu.Game.Tests/Resources/catmull-duplicate-initial-controlpoint.osu
@@ -0,0 +1,2 @@
+[HitObjects]
+200,304,23875,6,0,C|200:304|288:304|288:208|352:208,1,260,8|0
\ No newline at end of file
diff --git a/osu.Game.Tests/Visual/Editing/TestSceneBeatDivisorControl.cs b/osu.Game.Tests/Visual/Editing/TestSceneBeatDivisorControl.cs
index 6a0950c6dd..073a228224 100644
--- a/osu.Game.Tests/Visual/Editing/TestSceneBeatDivisorControl.cs
+++ b/osu.Game.Tests/Visual/Editing/TestSceneBeatDivisorControl.cs
@@ -5,11 +5,13 @@ using System;
using System.Diagnostics;
using System.Linq;
using NUnit.Framework;
+using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Testing;
+using osu.Game.Overlays;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Compose.Components;
using osuTK;
@@ -23,7 +25,10 @@ namespace osu.Game.Tests.Visual.Editing
private BindableBeatDivisor bindableBeatDivisor;
private SliderBar tickSliderBar => beatDivisorControl.ChildrenOfType>().Single();
- private EquilateralTriangle tickMarkerHead => tickSliderBar.ChildrenOfType().Single();
+ private Triangle tickMarkerHead => tickSliderBar.ChildrenOfType().Single();
+
+ [Cached]
+ private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Aquamarine);
[SetUp]
public void SetUp() => Schedule(() =>
diff --git a/osu.Game.Tests/Visual/Editing/TestSceneComposeScreen.cs b/osu.Game.Tests/Visual/Editing/TestSceneComposeScreen.cs
index 30c8539d85..fa15c00cd4 100644
--- a/osu.Game.Tests/Visual/Editing/TestSceneComposeScreen.cs
+++ b/osu.Game.Tests/Visual/Editing/TestSceneComposeScreen.cs
@@ -9,6 +9,7 @@ using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
+using osu.Game.Overlays;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Beatmaps;
@@ -47,6 +48,7 @@ namespace osu.Game.Tests.Visual.Editing
{
(typeof(EditorBeatmap), editorBeatmap),
(typeof(IBeatSnapProvider), editorBeatmap),
+ (typeof(OverlayColourProvider), new OverlayColourProvider(OverlayColourScheme.Green)),
},
Child = new ComposeScreen { State = { Value = Visibility.Visible } },
};
diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorMenuBar.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorMenuBar.cs
index 3cb44d9ae8..ad6fc55a32 100644
--- a/osu.Game.Tests/Visual/Editing/TestSceneEditorMenuBar.cs
+++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorMenuBar.cs
@@ -2,10 +2,12 @@
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
+using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Overlays;
using osu.Game.Screens.Edit.Components.Menus;
namespace osu.Game.Tests.Visual.Editing
@@ -13,6 +15,9 @@ namespace osu.Game.Tests.Visual.Editing
[TestFixture]
public class TestSceneEditorMenuBar : OsuTestScene
{
+ [Cached]
+ private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Aquamarine);
+
public TestSceneEditorMenuBar()
{
Add(new Container
diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs b/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs
index de441995b5..46b45979ea 100644
--- a/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs
+++ b/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs
@@ -4,15 +4,15 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
+using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Beatmaps.ControlPoints;
+using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Overlays;
-using osu.Game.Rulesets.Edit;
-using osu.Game.Rulesets.Osu;
using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Timing;
using osuTK;
@@ -22,9 +22,9 @@ namespace osu.Game.Tests.Visual.Editing
[TestFixture]
public class TestSceneTapTimingControl : EditorClockTestScene
{
- [Cached(typeof(EditorBeatmap))]
- [Cached(typeof(IBeatSnapProvider))]
- private readonly EditorBeatmap editorBeatmap;
+ private EditorBeatmap editorBeatmap => editorBeatmapContainer?.EditorBeatmap;
+
+ private TestSceneHitObjectComposer.EditorBeatmapContainer editorBeatmapContainer;
[Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
@@ -33,38 +33,48 @@ namespace osu.Game.Tests.Visual.Editing
private Bindable selectedGroup = new Bindable();
private TapTimingControl control;
+ private OsuSpriteText timingInfo;
- public TestSceneTapTimingControl()
+ [Resolved]
+ private AudioManager audio { get; set; }
+
+ [SetUpSteps]
+ public void SetUpSteps()
{
- var playableBeatmap = CreateBeatmap(new OsuRuleset().RulesetInfo);
+ AddStep("create beatmap", () =>
+ {
+ Beatmap.Value = new WaveformTestBeatmap(audio);
+ });
- // Ensure time doesn't end while testing
- playableBeatmap.BeatmapInfo.Length = 1200000;
+ AddStep("Create component", () =>
+ {
+ Child = editorBeatmapContainer = new TestSceneHitObjectComposer.EditorBeatmapContainer(Beatmap.Value)
+ {
+ Children = new Drawable[]
+ {
+ new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ AutoSizeAxes = Axes.Y,
+ Width = 400,
+ Scale = new Vector2(1.5f),
+ Child = control = new TapTimingControl(),
+ },
+ timingInfo = new OsuSpriteText(),
+ }
+ };
- editorBeatmap = new EditorBeatmap(playableBeatmap);
-
- selectedGroup.Value = editorBeatmap.ControlPointInfo.Groups.First();
+ selectedGroup.Value = editorBeatmap.ControlPointInfo.Groups.First();
+ });
}
- protected override void LoadComplete()
+ protected override void Update()
{
- base.LoadComplete();
+ base.Update();
- Beatmap.Value = CreateWorkingBeatmap(editorBeatmap.PlayableBeatmap);
- Beatmap.Disabled = true;
-
- Children = new Drawable[]
- {
- new Container
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- AutoSizeAxes = Axes.Y,
- Width = 400,
- Scale = new Vector2(1.5f),
- Child = control = new TapTimingControl(),
- }
- };
+ if (selectedGroup.Value != null)
+ timingInfo.Text = $"offset: {selectedGroup.Value.Time:N2} bpm: {selectedGroup.Value.ControlPoints.OfType().First().BPM:N2}";
}
[Test]
@@ -104,7 +114,13 @@ namespace osu.Game.Tests.Visual.Editing
.TriggerClick();
});
- AddSliderStep("BPM", 30, 400, 60, bpm => editorBeatmap.ControlPointInfo.TimingPoints.First().BeatLength = 60000f / bpm);
+ AddSliderStep("BPM", 30, 400, 128, bpm =>
+ {
+ if (editorBeatmap == null)
+ return;
+
+ editorBeatmap.ControlPointInfo.TimingPoints.First().BeatLength = 60000f / bpm;
+ });
}
protected override void Dispose(bool isDisposing)
diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTimelineTickDisplay.cs b/osu.Game.Tests/Visual/Editing/TestSceneTimelineTickDisplay.cs
index 20e58c3d2a..b78512e469 100644
--- a/osu.Game.Tests/Visual/Editing/TestSceneTimelineTickDisplay.cs
+++ b/osu.Game.Tests/Visual/Editing/TestSceneTimelineTickDisplay.cs
@@ -4,6 +4,7 @@
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
+using osu.Game.Overlays;
using osu.Game.Screens.Edit.Compose.Components;
using osuTK;
@@ -14,6 +15,9 @@ namespace osu.Game.Tests.Visual.Editing
{
public override Drawable CreateTestComponent() => Empty(); // tick display is implicitly inside the timeline.
+ [Cached]
+ private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Green);
+
[BackgroundDependencyLoader]
private void load()
{
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneFreeModSelectOverlay.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneFreeModSelectOverlay.cs
index c37bff2066..a8471edbf8 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneFreeModSelectOverlay.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneFreeModSelectOverlay.cs
@@ -9,7 +9,6 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using osu.Framework.Testing;
-using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Mods;
@@ -73,19 +72,23 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
createFreeModSelect();
+ AddAssert("select all button enabled", () => this.ChildrenOfType().Single().Enabled.Value);
+
AddStep("click select all button", () =>
{
- InputManager.MoveMouseTo(this.ChildrenOfType().ElementAt(1));
+ InputManager.MoveMouseTo(this.ChildrenOfType().Single());
InputManager.Click(MouseButton.Left);
});
AddUntilStep("all mods selected", assertAllAvailableModsSelected);
+ AddAssert("select all button disabled", () => !this.ChildrenOfType().Single().Enabled.Value);
AddStep("click deselect all button", () =>
{
- InputManager.MoveMouseTo(this.ChildrenOfType().Last());
+ InputManager.MoveMouseTo(this.ChildrenOfType().Single());
InputManager.Click(MouseButton.Left);
});
AddUntilStep("all mods deselected", () => !freeModSelectOverlay.SelectedMods.Value.Any());
+ AddAssert("select all button enabled", () => this.ChildrenOfType().Single().Enabled.Value);
}
private void createFreeModSelect()
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
index a3e0caedb9..c1f5f110d1 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
@@ -8,9 +8,11 @@ using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.UserInterface;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
+using osu.Game.Collections;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.Leaderboards;
@@ -54,6 +56,39 @@ namespace osu.Game.Tests.Visual.Navigation
exitViaEscapeAndConfirm();
}
+ [Test]
+ public void TestSongSelectBackActionHandling()
+ {
+ TestPlaySongSelect songSelect = null;
+
+ PushAndConfirm(() => songSelect = new TestPlaySongSelect());
+
+ AddStep("set filter", () => songSelect.ChildrenOfType().Single().Current.Value = "test");
+ AddStep("press back", () => InputManager.Click(MouseButton.Button1));
+
+ AddAssert("still at song select", () => Game.ScreenStack.CurrentScreen == songSelect);
+ AddAssert("filter cleared", () => string.IsNullOrEmpty(songSelect.ChildrenOfType().Single().Current.Value));
+
+ AddStep("set filter again", () => songSelect.ChildrenOfType().Single().Current.Value = "test");
+ AddStep("open collections dropdown", () =>
+ {
+ InputManager.MoveMouseTo(songSelect.ChildrenOfType().Single());
+ InputManager.Click(MouseButton.Left);
+ });
+
+ AddStep("press back once", () => InputManager.Click(MouseButton.Button1));
+ AddAssert("still at song select", () => Game.ScreenStack.CurrentScreen == songSelect);
+ AddAssert("collections dropdown closed", () => songSelect
+ .ChildrenOfType().Single()
+ .ChildrenOfType.DropdownMenu>().Single().State == MenuState.Closed);
+
+ AddStep("press back a second time", () => InputManager.Click(MouseButton.Button1));
+ AddAssert("filter cleared", () => string.IsNullOrEmpty(songSelect.ChildrenOfType().Single().Current.Value));
+
+ AddStep("press back a third time", () => InputManager.Click(MouseButton.Button1));
+ ConfirmAtMainMenu();
+ }
+
///
/// This tests that the F1 key will open the mod select overlay, and not be handled / blocked by the music controller (which has the same default binding
/// but should be handled *after* song select).
@@ -487,6 +522,9 @@ namespace osu.Game.Tests.Visual.Navigation
AddStep("move cursor to background", () => InputManager.MoveMouseTo(Game.ScreenSpaceDrawQuad.BottomRight));
AddStep("click left mouse button", () => InputManager.Click(MouseButton.Left));
AddAssert("now playing is hidden", () => nowPlayingOverlay.State.Value == Visibility.Hidden);
+
+ // move the mouse firmly inside game bounds to avoid interfering with other tests.
+ AddStep("center cursor", () => InputManager.MoveMouseTo(Game.ScreenSpaceDrawQuad.Centre));
}
[Test]
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunSetupOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunSetupOverlay.cs
index 48b5690243..d09efdc925 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunSetupOverlay.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunSetupOverlay.cs
@@ -185,7 +185,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
AddStep("step to next", () => overlay.NextButton.TriggerClick());
- AddAssert("is at known screen", () => overlay.CurrentScreen is ScreenBeatmaps);
+ AddAssert("is at known screen", () => overlay.CurrentScreen is ScreenUIScale);
AddStep("hide", () => overlay.Hide());
AddAssert("overlay hidden", () => overlay.State.Value == Visibility.Hidden);
@@ -195,7 +195,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("run notification action", () => lastNotification.Activated());
AddAssert("overlay shown", () => overlay.State.Value == Visibility.Visible);
- AddAssert("is resumed", () => overlay.CurrentScreen is ScreenBeatmaps);
+ AddAssert("is resumed", () => overlay.CurrentScreen is ScreenUIScale);
}
// interface mocks break hot reload, mocking this stub implementation instead works around it.
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs
index 75e30f76c3..9bb02c3e75 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs
@@ -435,15 +435,19 @@ namespace osu.Game.Tests.Visual.UserInterface
createScreen();
changeRuleset(0);
+ AddAssert("deselect all button disabled", () => !this.ChildrenOfType().Single().Enabled.Value);
+
AddStep("select DT + HD", () => SelectedMods.Value = new Mod[] { new OsuModDoubleTime(), new OsuModHidden() });
AddAssert("DT + HD selected", () => modSelectOverlay.ChildrenOfType().Count(panel => panel.Active.Value) == 2);
+ AddAssert("deselect all button enabled", () => this.ChildrenOfType().Single().Enabled.Value);
AddStep("click deselect all button", () =>
{
- InputManager.MoveMouseTo(this.ChildrenOfType().Last());
+ InputManager.MoveMouseTo(this.ChildrenOfType().Single());
InputManager.Click(MouseButton.Left);
});
AddUntilStep("all mods deselected", () => !SelectedMods.Value.Any());
+ AddAssert("deselect all button disabled", () => !this.ChildrenOfType().Single().Enabled.Value);
}
[Test]
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs
index f45c55d912..454a71e6d2 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs
@@ -5,9 +5,12 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
+using osu.Game.Graphics;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Overlays;
+using osu.Game.Overlays.Settings;
namespace osu.Game.Tests.Visual.UserInterface
{
@@ -15,14 +18,31 @@ namespace osu.Game.Tests.Visual.UserInterface
{
private readonly BindableBool enabled = new BindableBool(true);
- protected override Drawable CreateContent() => new RoundedButton
+ protected override Drawable CreateContent()
{
- Width = 400,
- Text = "Test button",
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Enabled = { BindTarget = enabled },
- };
+ return new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
+ {
+ new RoundedButton
+ {
+ Width = 400,
+ Text = "Test button",
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Enabled = { BindTarget = enabled },
+ },
+ new SettingsButton
+ {
+ Text = "Test button",
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Enabled = { BindTarget = enabled },
+ },
+ }
+ };
+ }
[Test]
public void TestDisabled()
@@ -34,7 +54,8 @@ namespace osu.Game.Tests.Visual.UserInterface
public void TestBackgroundColour()
{
AddStep("set red scheme", () => CreateThemedContent(OverlayColourScheme.Red));
- AddAssert("first button has correct colour", () => Cell(0, 1).ChildrenOfType().First().BackgroundColour == new OverlayColourProvider(OverlayColourScheme.Red).Highlight1);
+ AddAssert("rounded button has correct colour", () => Cell(0, 1).ChildrenOfType().First().BackgroundColour == new OsuColour().Blue3);
+ AddAssert("settings button has correct colour", () => Cell(0, 1).ChildrenOfType().First().BackgroundColour == new OverlayColourProvider(OverlayColourScheme.Red).Highlight1);
}
}
}
diff --git a/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs
index 922439fcb8..3a7c8b2ec0 100644
--- a/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs
+++ b/osu.Game/Beatmaps/ControlPoints/TimingControlPoint.cs
@@ -1,6 +1,8 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+#nullable enable
+
using osu.Framework.Bindables;
using osu.Game.Beatmaps.Timing;
using osu.Game.Graphics;
diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs
index 4e391c8221..23e05c7ccc 100644
--- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs
+++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs
@@ -12,9 +12,12 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.UserInterface;
+using osu.Framework.Input.Bindings;
+using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
+using osu.Game.Input.Bindings;
using osu.Game.Overlays;
using osuTK;
using osuTK.Graphics;
@@ -31,7 +34,7 @@ namespace osu.Game.Graphics.UserInterface
#region OsuDropdownMenu
- protected class OsuDropdownMenu : DropdownMenu
+ protected class OsuDropdownMenu : DropdownMenu, IKeyBindingHandler
{
public override bool HandleNonPositionalInput => State == MenuState.Open;
@@ -275,6 +278,23 @@ namespace osu.Game.Graphics.UserInterface
}
#endregion
+
+ public bool OnPressed(KeyBindingPressEvent e)
+ {
+ if (e.Repeat) return false;
+
+ if (e.Action == GlobalAction.Back)
+ {
+ State = MenuState.Closed;
+ return true;
+ }
+
+ return false;
+ }
+
+ public void OnReleased(KeyBindingReleaseEvent e)
+ {
+ }
}
#endregion
diff --git a/osu.Game/Graphics/UserInterfaceV2/LabelledDrawable.cs b/osu.Game/Graphics/UserInterfaceV2/LabelledDrawable.cs
index 066e1a7978..2353d9e0e8 100644
--- a/osu.Game/Graphics/UserInterfaceV2/LabelledDrawable.cs
+++ b/osu.Game/Graphics/UserInterfaceV2/LabelledDrawable.cs
@@ -154,7 +154,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
[BackgroundDependencyLoader(true)]
private void load(OverlayColourProvider? colourProvider, OsuColour osuColour)
{
- background.Colour = colourProvider?.Background4 ?? Color4Extensions.FromHex(@"1c2125");
+ background.Colour = colourProvider?.Background5 ?? Color4Extensions.FromHex(@"1c2125");
descriptionText.Colour = osuColour.Yellow;
}
diff --git a/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs b/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs
index 3c0c3b69e8..cb8c63371d 100644
--- a/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs
+++ b/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs
@@ -2,13 +2,11 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
-using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterface;
-using osu.Game.Overlays;
namespace osu.Game.Graphics.UserInterfaceV2
{
@@ -27,9 +25,12 @@ namespace osu.Game.Graphics.UserInterfaceV2
}
[BackgroundDependencyLoader(true)]
- private void load([CanBeNull] OverlayColourProvider overlayColourProvider, OsuColour colours)
+ private void load(OsuColour colours)
{
- DefaultBackgroundColour = overlayColourProvider?.Highlight1 ?? colours.Blue3;
+ // According to flyte, buttons are supposed to have explicit colours for now.
+ // Not sure this is the correct direction, but we haven't decided on an `OverlayColourProvider` stand-in yet.
+ // This is a better default. See `SettingsButton` for an override which uses `OverlayColourProvider`.
+ DefaultBackgroundColour = colours.Blue3;
}
protected override void LoadComplete()
diff --git a/osu.Game/Online/Chat/ChannelType.cs b/osu.Game/Online/Chat/ChannelType.cs
index 151efc4645..bd628e90c4 100644
--- a/osu.Game/Online/Chat/ChannelType.cs
+++ b/osu.Game/Online/Chat/ChannelType.cs
@@ -13,5 +13,6 @@ namespace osu.Game.Online.Chat
PM,
Group,
System,
+ Announce,
}
}
diff --git a/osu.Game/Overlays/BeatmapListing/SearchCategory.cs b/osu.Game/Overlays/BeatmapListing/SearchCategory.cs
index d6ae41aba1..b52df6234f 100644
--- a/osu.Game/Overlays/BeatmapListing/SearchCategory.cs
+++ b/osu.Game/Overlays/BeatmapListing/SearchCategory.cs
@@ -32,6 +32,9 @@ namespace osu.Game.Overlays.BeatmapListing
[Description("Pending & WIP")]
Pending,
+ [LocalisableDescription(typeof(BeatmapsStrings), nameof(BeatmapsStrings.StatusWip))]
+ Wip,
+
[LocalisableDescription(typeof(BeatmapsStrings), nameof(BeatmapsStrings.StatusGraveyard))]
Graveyard,
diff --git a/osu.Game/Overlays/BeatmapListing/SearchGeneral.cs b/osu.Game/Overlays/BeatmapListing/SearchGeneral.cs
index 9387020bdf..34ff5b9840 100644
--- a/osu.Game/Overlays/BeatmapListing/SearchGeneral.cs
+++ b/osu.Game/Overlays/BeatmapListing/SearchGeneral.cs
@@ -21,6 +21,9 @@ namespace osu.Game.Overlays.BeatmapListing
[Description("Subscribed mappers")]
Follows,
+ [LocalisableDescription(typeof(BeatmapsStrings), nameof(BeatmapsStrings.GeneralSpotlights))]
+ Spotlights,
+
[LocalisableDescription(typeof(BeatmapsStrings), nameof(BeatmapsStrings.GeneralFeaturedArtists))]
[Description("Featured artists")]
FeaturedArtists
diff --git a/osu.Game/Overlays/FirstRunSetupOverlay.cs b/osu.Game/Overlays/FirstRunSetupOverlay.cs
index 7b0de4affe..a5bece0832 100644
--- a/osu.Game/Overlays/FirstRunSetupOverlay.cs
+++ b/osu.Game/Overlays/FirstRunSetupOverlay.cs
@@ -76,10 +76,10 @@ namespace osu.Game.Overlays
private void load(OsuColour colours, LegacyImportManager? legacyImportManager)
{
steps.Add(typeof(ScreenWelcome));
+ steps.Add(typeof(ScreenUIScale));
steps.Add(typeof(ScreenBeatmaps));
if (legacyImportManager?.SupportsImportFromStable == true)
steps.Add(typeof(ScreenImportFromStable));
- steps.Add(typeof(ScreenUIScale));
steps.Add(typeof(ScreenBehaviour));
Header.Title = FirstRunSetupOverlayStrings.FirstRunSetupTitle;
diff --git a/osu.Game/Overlays/Mods/DeselectAllModsButton.cs b/osu.Game/Overlays/Mods/DeselectAllModsButton.cs
new file mode 100644
index 0000000000..8288d34c95
--- /dev/null
+++ b/osu.Game/Overlays/Mods/DeselectAllModsButton.cs
@@ -0,0 +1,54 @@
+// 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.Linq;
+using osu.Framework.Bindables;
+using osu.Framework.Input.Bindings;
+using osu.Framework.Input.Events;
+using osu.Game.Graphics.UserInterface;
+using osu.Game.Input.Bindings;
+using osu.Game.Localisation;
+using osu.Game.Rulesets.Mods;
+
+namespace osu.Game.Overlays.Mods
+{
+ public class DeselectAllModsButton : ShearedButton, IKeyBindingHandler
+ {
+ private readonly Bindable> selectedMods = new Bindable>();
+
+ public DeselectAllModsButton(ModSelectOverlay modSelectOverlay)
+ : base(ModSelectOverlay.BUTTON_WIDTH)
+ {
+ Text = CommonStrings.DeselectAll;
+ Action = modSelectOverlay.DeselectAll;
+
+ selectedMods.BindTo(modSelectOverlay.SelectedMods);
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ selectedMods.BindValueChanged(_ => updateEnabledState(), true);
+ }
+
+ private void updateEnabledState()
+ {
+ Enabled.Value = selectedMods.Value.Any();
+ }
+
+ public bool OnPressed(KeyBindingPressEvent e)
+ {
+ if (e.Repeat || e.Action != GlobalAction.DeselectAllMods)
+ return false;
+
+ TriggerClick();
+ return true;
+ }
+
+ public void OnReleased(KeyBindingReleaseEvent e)
+ {
+ }
+ }
+}
diff --git a/osu.Game/Overlays/Mods/ModColumn.cs b/osu.Game/Overlays/Mods/ModColumn.cs
index 9bb3f8bd9e..42f9daec4d 100644
--- a/osu.Game/Overlays/Mods/ModColumn.cs
+++ b/osu.Game/Overlays/Mods/ModColumn.cs
@@ -267,7 +267,7 @@ namespace osu.Game.Overlays.Mods
{
cancellationTokenSource?.Cancel();
- var panels = availableMods.Select(mod => CreateModPanel(mod).With(panel => panel.Shear = new Vector2(-ShearedOverlayContainer.SHEAR, 0)));
+ var panels = availableMods.Select(mod => CreateModPanel(mod).With(panel => panel.Shear = Vector2.Zero));
Task? loadTask;
diff --git a/osu.Game/Overlays/Mods/ModPanel.cs b/osu.Game/Overlays/Mods/ModPanel.cs
index 7010342bd8..358bdd3202 100644
--- a/osu.Game/Overlays/Mods/ModPanel.cs
+++ b/osu.Game/Overlays/Mods/ModPanel.cs
@@ -70,7 +70,7 @@ namespace osu.Game.Overlays.Mods
Content.Masking = true;
Content.CornerRadius = CORNER_RADIUS;
Content.BorderThickness = 2;
- Content.Shear = new Vector2(ShearedOverlayContainer.SHEAR, 0);
+ Shear = new Vector2(ShearedOverlayContainer.SHEAR, 0);
Children = new Drawable[]
{
diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs
index f1a998bd3c..4bad34d94f 100644
--- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs
+++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs
@@ -29,11 +29,20 @@ namespace osu.Game.Overlays.Mods
{
public abstract class ModSelectOverlay : ShearedOverlayContainer, ISamplePlaybackDisabler
{
- protected const int BUTTON_WIDTH = 200;
+ public const int BUTTON_WIDTH = 200;
[Cached]
public Bindable> SelectedMods { get; private set; } = new Bindable>(Array.Empty());
+ ///
+ /// Contains a dictionary with the current of all mods applicable for the current ruleset.
+ ///
+ ///
+ /// Contrary to and , the instances
+ /// inside the objects are owned solely by this instance.
+ ///
+ public Bindable>> AvailableMods { get; } = new Bindable>>(new Dictionary>());
+
private Func isValidMod = m => true;
///
@@ -76,16 +85,12 @@ namespace osu.Game.Overlays.Mods
};
}
- yield return deselectAllButton = new ShearedButton(BUTTON_WIDTH)
- {
- Text = CommonStrings.DeselectAll,
- Action = DeselectAll
- };
+ yield return new DeselectAllModsButton(this);
}
- private readonly Bindable>> availableMods = new Bindable>>();
- private readonly Dictionary> localAvailableMods = new Dictionary>();
- private IEnumerable allLocalAvailableMods => localAvailableMods.SelectMany(pair => pair.Value);
+ private readonly Bindable>> globalAvailableMods = new Bindable>>();
+
+ private IEnumerable allAvailableMods => AvailableMods.Value.SelectMany(pair => pair.Value);
private readonly BindableBool customisationVisible = new BindableBool();
@@ -98,7 +103,6 @@ namespace osu.Game.Overlays.Mods
private DifficultyMultiplierDisplay? multiplierDisplay;
private ShearedToggleButton? customisationButton;
- private ShearedButton? deselectAllButton;
protected ModSelectOverlay(OverlayColourScheme colourScheme = OverlayColourScheme.Green)
: base(colourScheme)
@@ -209,13 +213,13 @@ namespace osu.Game.Overlays.Mods
})
};
- availableMods.BindTo(game.AvailableMods);
+ globalAvailableMods.BindTo(game.AvailableMods);
}
protected override void LoadComplete()
{
// this is called before base call so that the mod state is populated early, and the transition in `PopIn()` can play out properly.
- availableMods.BindValueChanged(_ => createLocalMods(), true);
+ globalAvailableMods.BindValueChanged(_ => createLocalMods(), true);
base.LoadComplete();
@@ -247,7 +251,7 @@ namespace osu.Game.Overlays.Mods
///
/// Select all visible mods in all columns.
///
- protected void SelectAll()
+ public void SelectAll()
{
foreach (var column in columnFlow.Columns)
column.SelectAll();
@@ -256,7 +260,7 @@ namespace osu.Game.Overlays.Mods
///
/// Deselect all visible mods in all columns.
///
- protected void DeselectAll()
+ public void DeselectAll()
{
foreach (var column in columnFlow.Columns)
column.DeselectAll();
@@ -280,9 +284,9 @@ namespace osu.Game.Overlays.Mods
private void createLocalMods()
{
- localAvailableMods.Clear();
+ var newLocalAvailableMods = new Dictionary>();
- foreach (var (modType, mods) in availableMods.Value)
+ foreach (var (modType, mods) in globalAvailableMods.Value)
{
var modStates = mods.SelectMany(ModUtils.FlattenMod)
.Select(mod => new ModState(mod.DeepClone()))
@@ -291,18 +295,19 @@ namespace osu.Game.Overlays.Mods
foreach (var modState in modStates)
modState.Active.BindValueChanged(_ => updateFromInternalSelection());
- localAvailableMods[modType] = modStates;
+ newLocalAvailableMods[modType] = modStates;
}
+ AvailableMods.Value = newLocalAvailableMods;
filterMods();
foreach (var column in columnFlow.Columns)
- column.AvailableMods = localAvailableMods.GetValueOrDefault(column.ModType, Array.Empty());
+ column.AvailableMods = AvailableMods.Value.GetValueOrDefault(column.ModType, Array.Empty());
}
private void filterMods()
{
- foreach (var modState in allLocalAvailableMods)
+ foreach (var modState in allAvailableMods)
modState.Filtered.Value = !modState.Mod.HasImplementation || !IsValidMod.Invoke(modState.Mod);
}
@@ -383,7 +388,7 @@ namespace osu.Game.Overlays.Mods
var newSelection = new List();
- foreach (var modState in allLocalAvailableMods)
+ foreach (var modState in allAvailableMods)
{
var matchingSelectedMod = SelectedMods.Value.SingleOrDefault(selected => selected.GetType() == modState.Mod.GetType());
@@ -410,9 +415,9 @@ namespace osu.Game.Overlays.Mods
if (externalSelectionUpdateInProgress)
return;
- var candidateSelection = allLocalAvailableMods.Where(modState => modState.Active.Value)
- .Select(modState => modState.Mod)
- .ToArray();
+ var candidateSelection = allAvailableMods.Where(modState => modState.Active.Value)
+ .Select(modState => modState.Mod)
+ .ToArray();
SelectedMods.Value = ComputeNewModsFromSelection(SelectedMods.Value, candidateSelection);
}
@@ -514,10 +519,6 @@ namespace osu.Game.Overlays.Mods
hideOverlay(true);
return true;
}
-
- case GlobalAction.DeselectAllMods:
- deselectAllButton?.TriggerClick();
- return true;
}
return base.OnPressed(e);
diff --git a/osu.Game/Overlays/Mods/SelectAllModsButton.cs b/osu.Game/Overlays/Mods/SelectAllModsButton.cs
new file mode 100644
index 0000000000..f7078b2fa5
--- /dev/null
+++ b/osu.Game/Overlays/Mods/SelectAllModsButton.cs
@@ -0,0 +1,61 @@
+// 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.Linq;
+using osu.Framework.Bindables;
+using osu.Framework.Input;
+using osu.Framework.Input.Bindings;
+using osu.Framework.Input.Events;
+using osu.Game.Graphics.UserInterface;
+using osu.Game.Localisation;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Screens.OnlinePlay;
+
+namespace osu.Game.Overlays.Mods
+{
+ public class SelectAllModsButton : ShearedButton, IKeyBindingHandler
+ {
+ private readonly Bindable> selectedMods = new Bindable>();
+ private readonly Bindable>> availableMods = new Bindable>>();
+
+ public SelectAllModsButton(FreeModSelectOverlay modSelectOverlay)
+ : base(ModSelectOverlay.BUTTON_WIDTH)
+ {
+ Text = CommonStrings.SelectAll;
+ Action = modSelectOverlay.SelectAll;
+
+ selectedMods.BindTo(modSelectOverlay.SelectedMods);
+ availableMods.BindTo(modSelectOverlay.AvailableMods);
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ selectedMods.BindValueChanged(_ => Scheduler.AddOnce(updateEnabledState));
+ availableMods.BindValueChanged(_ => Scheduler.AddOnce(updateEnabledState));
+ updateEnabledState();
+ }
+
+ private void updateEnabledState()
+ {
+ Enabled.Value = availableMods.Value
+ .SelectMany(pair => pair.Value)
+ .Any(modState => !modState.Active.Value && !modState.Filtered.Value);
+ }
+
+ public bool OnPressed(KeyBindingPressEvent e)
+ {
+ if (e.Repeat || e.Action != PlatformAction.SelectAll)
+ return false;
+
+ TriggerClick();
+ return true;
+ }
+
+ public void OnReleased(KeyBindingReleaseEvent e)
+ {
+ }
+ }
+}
diff --git a/osu.Game/Overlays/OverlayColourProvider.cs b/osu.Game/Overlays/OverlayColourProvider.cs
index 7bddb924a0..a4f6527024 100644
--- a/osu.Game/Overlays/OverlayColourProvider.cs
+++ b/osu.Game/Overlays/OverlayColourProvider.cs
@@ -72,6 +72,9 @@ namespace osu.Game.Overlays
case OverlayColourScheme.Green:
return 125 / 360f;
+ case OverlayColourScheme.Aquamarine:
+ return 160 / 360f;
+
case OverlayColourScheme.Purple:
return 255 / 360f;
@@ -94,5 +97,6 @@ namespace osu.Game.Overlays
Purple,
Blue,
Plum,
+ Aquamarine
}
}
diff --git a/osu.Game/Overlays/Settings/SettingsButton.cs b/osu.Game/Overlays/Settings/SettingsButton.cs
index 10aea92b22..9e4dc763ec 100644
--- a/osu.Game/Overlays/Settings/SettingsButton.cs
+++ b/osu.Game/Overlays/Settings/SettingsButton.cs
@@ -3,9 +3,12 @@
using System.Collections.Generic;
using System.Linq;
+using JetBrains.Annotations;
+using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Localisation;
+using osu.Game.Graphics;
using osu.Game.Graphics.UserInterfaceV2;
namespace osu.Game.Overlays.Settings
@@ -18,6 +21,12 @@ namespace osu.Game.Overlays.Settings
Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS, Right = SettingsPanel.CONTENT_MARGINS };
}
+ [BackgroundDependencyLoader(true)]
+ private void load([CanBeNull] OverlayColourProvider overlayColourProvider, OsuColour colours)
+ {
+ DefaultBackgroundColour = overlayColourProvider?.Highlight1 ?? colours.Blue3;
+ }
+
public LocalisableString TooltipText { get; set; }
public override IEnumerable FilterTerms
diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs
index 5e6d9dbe34..7019dad803 100644
--- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs
+++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs
@@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Edit
{
AddInternal(RightSideToolboxContainer = new ExpandingToolboxContainer(130, 250)
{
- Padding = new MarginPadding { Right = 10 },
+ Padding = new MarginPadding(10),
Alpha = DistanceSpacingMultiplier.Disabled ? 0 : 1,
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs
index f8d796a778..f6fdb228ce 100644
--- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs
+++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs
@@ -114,9 +114,9 @@ namespace osu.Game.Rulesets.Edit
.WithChild(BlueprintContainer = CreateBlueprintContainer())
}
},
- new ExpandingToolboxContainer(80, 200)
+ new ExpandingToolboxContainer(90, 200)
{
- Padding = new MarginPadding { Left = 10 },
+ Padding = new MarginPadding(10),
Children = new Drawable[]
{
new EditorToolboxGroup("toolbox (1-9)")
diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs
index 7cf68a2df7..d3d1196eae 100644
--- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs
+++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs
@@ -340,8 +340,10 @@ namespace osu.Game.Rulesets.Objects.Legacy
if (vertices[endIndex].Position != vertices[endIndex - 1].Position)
continue;
- // Adjacent legacy Catmull segments should be treated as a single segment.
- if (FormatVersion < LegacyBeatmapEncoder.FIRST_LAZER_VERSION && type == PathType.Catmull)
+ // Legacy Catmull sliders don't support multiple segments, so adjacent Catmull segments should be treated as a single one.
+ // Importantly, this is not applied to the first control point, which may duplicate the slider path's position
+ // resulting in a duplicate (0,0) control point in the resultant list.
+ if (type == PathType.Catmull && endIndex > 1 && FormatVersion < LegacyBeatmapEncoder.FIRST_LAZER_VERSION)
continue;
// The last control point of each segment is not allowed to start a new implicit segment.
diff --git a/osu.Game/Screens/Edit/BindableBeatDivisor.cs b/osu.Game/Screens/Edit/BindableBeatDivisor.cs
index af958e3448..8f430dce77 100644
--- a/osu.Game/Screens/Edit/BindableBeatDivisor.cs
+++ b/osu.Game/Screens/Edit/BindableBeatDivisor.cs
@@ -5,6 +5,7 @@ using System.Linq;
using osu.Framework.Bindables;
using osu.Game.Graphics;
using osu.Game.Screens.Edit.Compose.Components;
+using osuTK;
using osuTK.Graphics;
namespace osu.Game.Screens.Edit
@@ -100,6 +101,32 @@ namespace osu.Game.Screens.Edit
}
}
+ ///
+ /// Get a relative display size for the specified divisor.
+ ///
+ /// The beat divisor.
+ /// A relative size which can be used to display ticks.
+ public static Vector2 GetSize(int beatDivisor)
+ {
+ switch (beatDivisor)
+ {
+ case 1:
+ case 2:
+ return new Vector2(0.6f, 0.9f);
+
+ case 3:
+ case 4:
+ return new Vector2(0.5f, 0.8f);
+
+ case 6:
+ case 8:
+ return new Vector2(0.4f, 0.7f);
+
+ default:
+ return new Vector2(0.3f, 0.6f);
+ }
+ }
+
///
/// Retrieves the applicable divisor for a specific beat index.
///
diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs
index 2a8435ff47..440071bc4c 100644
--- a/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs
+++ b/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs
@@ -2,16 +2,13 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Overlays;
using osuTK;
-using osuTK.Graphics;
namespace osu.Game.Screens.Edit.Components.Menus
{
@@ -24,7 +21,12 @@ namespace osu.Game.Screens.Edit.Components.Menus
MaskingContainer.CornerRadius = 0;
ItemsContainer.Padding = new MarginPadding { Left = 100 };
- BackgroundColour = Color4Extensions.FromHex("111");
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OverlayColourProvider colourProvider)
+ {
+ BackgroundColour = colourProvider.Background3;
}
protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu();
@@ -33,29 +35,26 @@ namespace osu.Game.Screens.Edit.Components.Menus
private class DrawableEditorBarMenuItem : DrawableOsuMenuItem
{
- private BackgroundBox background;
-
public DrawableEditorBarMenuItem(MenuItem item)
: base(item)
{
- Anchor = Anchor.CentreLeft;
- Origin = Anchor.CentreLeft;
-
- StateChanged += stateChanged;
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
- ForegroundColour = colours.BlueLight;
- BackgroundColour = Color4.Transparent;
- ForegroundColourHover = Color4.White;
- BackgroundColourHover = colours.Gray3;
+ ForegroundColour = colourProvider.Light3;
+ BackgroundColour = colourProvider.Background2;
+ ForegroundColourHover = colourProvider.Content1;
+ BackgroundColourHover = colourProvider.Background1;
}
- public override void SetFlowDirection(Direction direction)
+ protected override void LoadComplete()
{
- AutoSizeAxes = Axes.Both;
+ base.LoadComplete();
+
+ Foreground.Anchor = Anchor.CentreLeft;
+ Foreground.Origin = Anchor.CentreLeft;
}
protected override void UpdateBackgroundColour()
@@ -74,54 +73,16 @@ namespace osu.Game.Screens.Edit.Components.Menus
base.UpdateForegroundColour();
}
- private void stateChanged(MenuItemState newState)
- {
- if (newState == MenuItemState.Selected)
- background.Expand();
- else
- background.Contract();
- }
-
- protected override Drawable CreateBackground() => background = new BackgroundBox();
protected override DrawableOsuMenuItem.TextContainer CreateTextContainer() => new TextContainer();
private new class TextContainer : DrawableOsuMenuItem.TextContainer
{
public TextContainer()
{
- NormalText.Font = NormalText.Font.With(size: 14);
- BoldText.Font = BoldText.Font.With(size: 14);
- NormalText.Margin = BoldText.Margin = new MarginPadding { Horizontal = 10, Vertical = MARGIN_VERTICAL };
+ NormalText.Font = OsuFont.TorusAlternate;
+ BoldText.Font = OsuFont.TorusAlternate.With(weight: FontWeight.Bold);
}
}
-
- private class BackgroundBox : CompositeDrawable
- {
- private readonly Container innerBackground;
-
- public BackgroundBox()
- {
- RelativeSizeAxes = Axes.Both;
- Masking = true;
- InternalChild = innerBackground = new Container
- {
- RelativeSizeAxes = Axes.Both,
- Masking = true,
- CornerRadius = 4,
- Child = new Box { RelativeSizeAxes = Axes.Both }
- };
- }
-
- ///
- /// Expands the background such that it doesn't show the bottom corners.
- ///
- public void Expand() => innerBackground.Height = 2;
-
- ///
- /// Contracts the background such that it shows the bottom corners.
- ///
- public void Contract() => innerBackground.Height = 1;
- }
}
private class SubMenu : OsuMenu
@@ -129,14 +90,15 @@ namespace osu.Game.Screens.Edit.Components.Menus
public SubMenu()
: base(Direction.Vertical)
{
- OriginPosition = new Vector2(5, 1);
- ItemsContainer.Padding = new MarginPadding { Top = 5, Bottom = 5 };
+ ItemsContainer.Padding = new MarginPadding();
+
+ MaskingContainer.CornerRadius = 0;
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
- BackgroundColour = colours.Gray3;
+ BackgroundColour = colourProvider.Background2;
}
protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu();
@@ -147,9 +109,27 @@ namespace osu.Game.Screens.Edit.Components.Menus
{
case EditorMenuItemSpacer spacer:
return new DrawableSpacer(spacer);
+
+ default:
+ return new EditorMenuItem(item);
+ }
+ }
+
+ private class EditorMenuItem : DrawableOsuMenuItem
+ {
+ public EditorMenuItem(MenuItem item)
+ : base(item)
+ {
}
- return base.CreateDrawableMenuItem(item);
+ [BackgroundDependencyLoader]
+ private void load(OverlayColourProvider colourProvider)
+ {
+ BackgroundColour = colourProvider.Background2;
+ BackgroundColourHover = colourProvider.Background1;
+
+ Foreground.Padding = new MarginPadding { Vertical = 2 };
+ }
}
private class DrawableSpacer : DrawableOsuMenuItem
@@ -157,6 +137,7 @@ namespace osu.Game.Screens.Edit.Components.Menus
public DrawableSpacer(MenuItem item)
: base(item)
{
+ Scale = new Vector2(1, 0.3f);
}
protected override bool OnHover(HoverEvent e) => true;
diff --git a/osu.Game/Screens/Edit/Components/Menus/ScreenSelectionTabControl.cs b/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs
similarity index 72%
rename from osu.Game/Screens/Edit/Components/Menus/ScreenSelectionTabControl.cs
rename to osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs
index b8bc5cdf36..8b868a4649 100644
--- a/osu.Game/Screens/Edit/Components/Menus/ScreenSelectionTabControl.cs
+++ b/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs
@@ -2,42 +2,38 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Overlays;
using osuTK;
-using osuTK.Graphics;
namespace osu.Game.Screens.Edit.Components.Menus
{
- public class ScreenSelectionTabControl : OsuTabControl
+ public class EditorScreenSwitcherControl : OsuTabControl
{
- public ScreenSelectionTabControl()
+ public EditorScreenSwitcherControl()
{
AutoSizeAxes = Axes.X;
RelativeSizeAxes = Axes.Y;
TabContainer.RelativeSizeAxes &= ~Axes.X;
TabContainer.AutoSizeAxes = Axes.X;
- TabContainer.Padding = new MarginPadding();
-
- AddInternal(new Box
- {
- Anchor = Anchor.BottomLeft,
- Origin = Anchor.BottomLeft,
- RelativeSizeAxes = Axes.X,
- Height = 1,
- Colour = Color4.White.Opacity(0.2f),
- });
+ TabContainer.Padding = new MarginPadding(10);
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
- AccentColour = colours.Yellow;
+ AccentColour = colourProvider.Light3;
+
+ AddInternal(new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = colourProvider.Background2,
+ });
}
protected override Dropdown CreateDropdown() => null;
@@ -54,6 +50,15 @@ namespace osu.Game.Screens.Edit.Components.Menus
Text.Margin = new MarginPadding();
Text.Anchor = Anchor.CentreLeft;
Text.Origin = Anchor.CentreLeft;
+
+ Text.Font = OsuFont.TorusAlternate;
+
+ Bar.Expire();
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OverlayColourProvider colourProvider)
+ {
}
protected override void OnActivated()
diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs
index 370c9016c7..bf4d70baa6 100644
--- a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs
@@ -8,9 +8,7 @@ using Humanizer;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
-using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
-using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
@@ -22,6 +20,7 @@ using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Graphics.UserInterfaceV2;
+using osu.Game.Overlays;
using osuTK;
using osuTK.Graphics;
using osuTK.Input;
@@ -38,18 +37,17 @@ namespace osu.Game.Screens.Edit.Compose.Components
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
Masking = true;
- CornerRadius = 5;
InternalChildren = new Drawable[]
{
new Box
{
- Name = "Gray Background",
+ Name = "Main background",
RelativeSizeAxes = Axes.Both,
- Colour = colours.Gray4
+ Colour = colourProvider.Background3,
},
new GridContainer
{
@@ -65,9 +63,9 @@ namespace osu.Game.Screens.Edit.Compose.Components
{
new Box
{
- Name = "Black Background",
+ Name = "Tick area background",
RelativeSizeAxes = Axes.Both,
- Colour = Color4.Black
+ Colour = colourProvider.Background5,
},
new TickSliderBar(beatDivisor)
{
@@ -86,7 +84,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = colours.Gray4
+ Colour = colourProvider.Background3
},
new Container
{
@@ -139,11 +137,6 @@ namespace osu.Game.Screens.Edit.Compose.Components
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
- new Box
- {
- RelativeSizeAxes = Axes.Both,
- Colour = colours.Gray4
- },
new Container
{
RelativeSizeAxes = Axes.Both,
@@ -402,15 +395,15 @@ namespace osu.Game.Screens.Edit.Compose.Components
ClearInternal();
CurrentNumber.ValueChanged -= moveMarker;
- foreach (int t in beatDivisor.ValidDivisors.Value.Presets)
+ foreach (int divisor in beatDivisor.ValidDivisors.Value.Presets)
{
- AddInternal(new Tick
+ AddInternal(new Tick(divisor)
{
- Anchor = Anchor.TopLeft,
- Origin = Anchor.TopCentre,
- RelativePositionAxes = Axes.X,
- Colour = BindableBeatDivisor.GetColourFor(t, colours),
- X = getMappedPosition(t)
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.Centre,
+ RelativePositionAxes = Axes.Both,
+ Colour = BindableBeatDivisor.GetColourFor(divisor, colours),
+ X = getMappedPosition(divisor),
});
}
@@ -422,7 +415,6 @@ namespace osu.Game.Screens.Edit.Compose.Components
private void moveMarker(ValueChangedEvent divisor)
{
marker.MoveToX(getMappedPosition(divisor.NewValue), 100, Easing.OutQuint);
- marker.Flash();
}
protected override void UpdateValue(float value)
@@ -453,6 +445,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
protected override bool OnMouseDown(MouseDownEvent e)
{
marker.Active = true;
+ handleMouseInput(e.ScreenSpaceMousePosition);
return base.OnMouseDown(e);
}
@@ -489,52 +482,36 @@ namespace osu.Game.Screens.Edit.Compose.Components
private float getMappedPosition(float divisor) => MathF.Pow((divisor - 1) / (beatDivisor.ValidDivisors.Value.Presets.Last() - 1), 0.90f);
- private class Tick : CompositeDrawable
+ private class Tick : Circle
{
- public Tick()
+ public Tick(int divisor)
{
- Size = new Vector2(2.5f, 10);
-
+ Size = new Vector2(6f, 12) * BindableBeatDivisor.GetSize(divisor);
InternalChild = new Box { RelativeSizeAxes = Axes.Both };
-
- CornerRadius = 0.5f;
- Masking = true;
}
}
private class Marker : CompositeDrawable
{
- private Color4 defaultColour;
-
- private const float size = 7;
+ [Resolved]
+ private OverlayColourProvider colourProvider { get; set; }
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load()
{
- Colour = defaultColour = colours.Gray4;
- Anchor = Anchor.TopLeft;
- Origin = Anchor.TopCentre;
+ Colour = colourProvider.Background3;
+ Anchor = Anchor.BottomLeft;
+ Origin = Anchor.BottomCentre;
+
+ Size = new Vector2(8, 6.5f);
- Width = size;
- RelativeSizeAxes = Axes.Y;
RelativePositionAxes = Axes.X;
InternalChildren = new Drawable[]
{
- new Box
+ new Triangle
{
- Width = 2,
- RelativeSizeAxes = Axes.Y,
- Origin = Anchor.BottomCentre,
- Anchor = Anchor.BottomCentre,
- Colour = ColourInfo.GradientVertical(Color4.White.Opacity(0.2f), Color4.White),
- Blending = BlendingParameters.Additive,
- },
- new EquilateralTriangle
- {
- Origin = Anchor.BottomCentre,
- Anchor = Anchor.BottomCentre,
- Height = size,
+ RelativeSizeAxes = Axes.Both,
EdgeSmoothness = new Vector2(1),
Colour = Color4.White,
}
@@ -548,22 +525,10 @@ namespace osu.Game.Screens.Edit.Compose.Components
get => active;
set
{
- this.FadeColour(value ? Color4.White : defaultColour, 500, Easing.OutQuint);
+ this.FadeColour(value ? colourProvider.Background1 : colourProvider.Background3, 500, Easing.OutQuint);
active = value;
}
}
-
- public void Flash()
- {
- bool wasActive = active;
-
- Active = true;
-
- if (wasActive) return;
-
- using (BeginDelayedSequence(50))
- Active = false;
- }
}
}
}
diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs
index 992ab7947e..6812bbb72d 100644
--- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs
@@ -163,10 +163,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
base.LoadComplete();
+ WaveformVisible.BindValueChanged(_ => updateWaveformOpacity());
waveformOpacity.BindValueChanged(_ => updateWaveformOpacity(), true);
- WaveformVisible.ValueChanged += _ => updateWaveformOpacity();
- TicksVisible.ValueChanged += visible => ticks.FadeTo(visible.NewValue ? 1 : 0, 200, Easing.OutQuint);
+ TicksVisible.BindValueChanged(visible => ticks.FadeTo(visible.NewValue ? 1 : 0, 200, Easing.OutQuint), true);
+
ControlPointsVisible.BindValueChanged(visible =>
{
if (visible.NewValue)
diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs
index 1541ceade5..4cffebc57c 100644
--- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs
@@ -2,12 +2,12 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Overlays;
using osuTK;
namespace osu.Game.Screens.Edit.Compose.Components.Timeline
@@ -27,10 +27,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
}
[BackgroundDependencyLoader]
- private void load()
+ private void load(OverlayColourProvider colourProvider)
{
Masking = true;
- CornerRadius = 5;
OsuCheckbox waveformCheckbox;
OsuCheckbox controlPointsCheckbox;
@@ -41,7 +40,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = Color4Extensions.FromHex("111")
+ Colour = colourProvider.Background5
},
new GridContainer
{
@@ -55,12 +54,13 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X,
+ Name = @"Toggle controls",
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = Color4Extensions.FromHex("222")
+ Colour = colourProvider.Background2,
},
new FillFlowContainer
{
@@ -94,12 +94,13 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X,
+ Name = @"Zoom controls",
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = Color4Extensions.FromHex("333")
+ Colour = colourProvider.Background3,
},
new Container
{
diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs
index 3a32dc18e5..fda8416ecd 100644
--- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs
@@ -11,6 +11,7 @@ using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts;
using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations;
+using osuTK;
namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
@@ -132,10 +133,15 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
// even though "bar lines" take up the full vertical space, we render them in two pieces because it allows for less anchor/origin churn.
+ Vector2 size = Vector2.One;
+
+ if (indexInBar != 1)
+ size = BindableBeatDivisor.GetSize(divisor);
+
var line = getNextUsableLine();
line.X = xPos;
- line.Width = PointVisualisation.MAX_WIDTH * getWidth(indexInBar, divisor);
- line.Height = 0.9f * getHeight(indexInBar, divisor);
+ line.Width = PointVisualisation.MAX_WIDTH * size.X;
+ line.Height = 0.9f * size.Y;
line.Colour = colour;
}
@@ -170,54 +176,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
}
}
- private static float getWidth(int indexInBar, int divisor)
- {
- if (indexInBar == 0)
- return 1;
-
- switch (divisor)
- {
- case 1:
- case 2:
- return 0.6f;
-
- case 3:
- case 4:
- return 0.5f;
-
- case 6:
- case 8:
- return 0.4f;
-
- default:
- return 0.3f;
- }
- }
-
- private static float getHeight(int indexInBar, int divisor)
- {
- if (indexInBar == 0)
- return 1;
-
- switch (divisor)
- {
- case 1:
- case 2:
- return 0.9f;
-
- case 3:
- case 4:
- return 0.8f;
-
- case 6:
- case 8:
- return 0.7f;
-
- default:
- return 0.6f;
- }
- }
-
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs
index 0bb3f51903..bdf204c1b6 100644
--- a/osu.Game/Screens/Edit/Editor.cs
+++ b/osu.Game/Screens/Edit/Editor.cs
@@ -140,7 +140,7 @@ namespace osu.Game.Screens.Edit
public readonly EditorClipboard Clipboard = new EditorClipboard();
[Cached]
- private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
+ private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Aquamarine);
public Editor(EditorLoader loader = null)
{
@@ -278,7 +278,7 @@ namespace osu.Game.Screens.Edit
}
}
},
- new ScreenSelectionTabControl
+ new EditorScreenSwitcherControl
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
@@ -777,6 +777,7 @@ namespace osu.Game.Screens.Edit
if ((currentScreen = screenContainer.SingleOrDefault(s => s.Type == e.NewValue)) != null)
{
screenContainer.ChangeChildDepth(currentScreen, lastScreen?.Depth + 1 ?? 0);
+
currentScreen.Show();
return;
}
diff --git a/osu.Game/Screens/Edit/EditorRoundedScreen.cs b/osu.Game/Screens/Edit/EditorRoundedScreen.cs
deleted file mode 100644
index 62f40f0325..0000000000
--- a/osu.Game/Screens/Edit/EditorRoundedScreen.cs
+++ /dev/null
@@ -1,53 +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.Allocation;
-using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Shapes;
-using osu.Game.Overlays;
-
-namespace osu.Game.Screens.Edit
-{
- public class EditorRoundedScreen : EditorScreen
- {
- public const int HORIZONTAL_PADDING = 100;
-
- private Container roundedContent;
-
- protected override Container Content => roundedContent;
-
- public EditorRoundedScreen(EditorScreenMode mode)
- : base(mode)
- {
- }
-
- [BackgroundDependencyLoader]
- private void load(OverlayColourProvider colourProvider)
- {
- base.Content.Add(new Container
- {
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding(50),
- Child = new Container
- {
- RelativeSizeAxes = Axes.Both,
- Masking = true,
- CornerRadius = 10,
- Children = new Drawable[]
- {
- new Box
- {
- Colour = colourProvider.Background3,
- RelativeSizeAxes = Axes.Both,
- },
- roundedContent = new Container
- {
- RelativeSizeAxes = Axes.Both,
- },
- }
- }
- });
- }
- }
-}
diff --git a/osu.Game/Screens/Edit/EditorRoundedScreenSettings.cs b/osu.Game/Screens/Edit/EditorRoundedScreenSettings.cs
index cb17484d27..94a83a82aa 100644
--- a/osu.Game/Screens/Edit/EditorRoundedScreenSettings.cs
+++ b/osu.Game/Screens/Edit/EditorRoundedScreenSettings.cs
@@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
using osu.Game.Overlays;
+using osuTK;
namespace osu.Game.Screens.Edit
{
@@ -22,7 +23,7 @@ namespace osu.Game.Screens.Edit
{
new Box
{
- Colour = colours.Background4,
+ Colour = colours.Background6,
RelativeSizeAxes = Axes.Both,
},
new OsuScrollContainer
@@ -33,6 +34,8 @@ namespace osu.Game.Screens.Edit
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
+ Padding = new MarginPadding(10),
+ Spacing = new Vector2(10),
Children = CreateSections()
},
}
diff --git a/osu.Game/Screens/Edit/EditorScreen.cs b/osu.Game/Screens/Edit/EditorScreen.cs
index 2837cdcd9a..31c34edd7c 100644
--- a/osu.Game/Screens/Edit/EditorScreen.cs
+++ b/osu.Game/Screens/Edit/EditorScreen.cs
@@ -33,17 +33,9 @@ namespace osu.Game.Screens.Edit
InternalChild = content = new PopoverContainer { RelativeSizeAxes = Axes.Both };
}
- protected override void PopIn()
- {
- this.ScaleTo(1f, 200, Easing.OutQuint)
- .FadeIn(200, Easing.OutQuint);
- }
+ protected override void PopIn() => this.FadeIn();
- protected override void PopOut()
- {
- this.ScaleTo(0.98f, 200, Easing.OutQuint)
- .FadeOut(200, Easing.OutQuint);
- }
+ protected override void PopOut() => this.FadeOut();
#region Clipboard operations
diff --git a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs
index 0d59a7a1a8..0b80af68f2 100644
--- a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs
+++ b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs
@@ -3,21 +3,19 @@
using JetBrains.Annotations;
using osu.Framework.Allocation;
-using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Overlays;
using osu.Game.Screens.Edit.Compose.Components;
using osu.Game.Screens.Edit.Compose.Components.Timeline;
-using osuTK.Graphics;
namespace osu.Game.Screens.Edit
{
public abstract class EditorScreenWithTimeline : EditorScreen
{
- private const float vertical_margins = 10;
- private const float horizontal_margins = 20;
+ private const float padding = 10;
private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor();
@@ -33,7 +31,7 @@ namespace osu.Game.Screens.Edit
private LoadingSpinner spinner;
[BackgroundDependencyLoader(true)]
- private void load([CanBeNull] BindableBeatDivisor beatDivisor)
+ private void load(OverlayColourProvider colourProvider, [CanBeNull] BindableBeatDivisor beatDivisor)
{
if (beatDivisor != null)
this.beatDivisor.BindTo(beatDivisor);
@@ -60,14 +58,14 @@ namespace osu.Game.Screens.Edit
new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = Color4.Black.Opacity(0.5f)
+ Colour = colourProvider.Background4
},
new Container
{
Name = "Timeline content",
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
- Padding = new MarginPadding { Horizontal = horizontal_margins, Vertical = vertical_margins },
+ Padding = new MarginPadding { Horizontal = padding, Top = padding },
Child = new GridContainer
{
RelativeSizeAxes = Axes.X,
@@ -106,12 +104,6 @@ namespace osu.Game.Screens.Edit
Name = "Main content",
RelativeSizeAxes = Axes.Both,
Depth = float.MaxValue,
- Padding = new MarginPadding
- {
- Horizontal = horizontal_margins,
- Top = vertical_margins,
- Bottom = vertical_margins
- },
Child = spinner = new LoadingSpinner(true)
{
State = { Value = Visibility.Visible },
@@ -133,18 +125,10 @@ namespace osu.Game.Screens.Edit
mainContent.Add(content);
content.FadeInFromZero(300, Easing.OutQuint);
- LoadComponentAsync(new TimelineArea(CreateTimelineContent()), t =>
- {
- timelineContainer.Add(t);
- OnTimelineLoaded(t);
- });
+ LoadComponentAsync(new TimelineArea(CreateTimelineContent()), timelineContainer.Add);
});
}
- protected virtual void OnTimelineLoaded(TimelineArea timelineArea)
- {
- }
-
protected abstract Drawable CreateMainContent();
protected virtual Drawable CreateTimelineContent() => new Container();
diff --git a/osu.Game/Screens/Edit/Setup/SetupScreen.cs b/osu.Game/Screens/Edit/Setup/SetupScreen.cs
index 231d977aab..b95aabc1c4 100644
--- a/osu.Game/Screens/Edit/Setup/SetupScreen.cs
+++ b/osu.Game/Screens/Edit/Setup/SetupScreen.cs
@@ -4,11 +4,13 @@
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
+using osu.Game.Overlays;
namespace osu.Game.Screens.Edit.Setup
{
- public class SetupScreen : EditorRoundedScreen
+ public class SetupScreen : EditorScreen
{
[Cached]
private SectionsContainer sections { get; } = new SetupScreenSectionsContainer();
@@ -22,7 +24,7 @@ namespace osu.Game.Screens.Edit.Setup
}
[BackgroundDependencyLoader]
- private void load(EditorBeatmap beatmap)
+ private void load(EditorBeatmap beatmap, OverlayColourProvider colourProvider)
{
var sectionsEnumerable = new List
{
@@ -37,6 +39,12 @@ namespace osu.Game.Screens.Edit.Setup
if (rulesetSpecificSection != null)
sectionsEnumerable.Add(rulesetSpecificSection);
+ Add(new Box
+ {
+ Colour = colourProvider.Background2,
+ RelativeSizeAxes = Axes.Both,
+ });
+
Add(sections.With(s =>
{
s.RelativeSizeAxes = Axes.Both;
diff --git a/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs b/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs
index 2d0afda001..2412f1c4ed 100644
--- a/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs
+++ b/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs
@@ -93,7 +93,7 @@ namespace osu.Game.Screens.Edit.Setup
public SetupScreenTabControl()
{
- TabContainer.Margin = new MarginPadding { Horizontal = EditorRoundedScreen.HORIZONTAL_PADDING };
+ TabContainer.Margin = new MarginPadding { Horizontal = 100 };
AddInternal(background = new Box
{
diff --git a/osu.Game/Screens/Edit/Setup/SetupSection.cs b/osu.Game/Screens/Edit/Setup/SetupSection.cs
index 1dde6fb926..02bb05d227 100644
--- a/osu.Game/Screens/Edit/Setup/SetupSection.cs
+++ b/osu.Game/Screens/Edit/Setup/SetupSection.cs
@@ -40,7 +40,7 @@ namespace osu.Game.Screens.Edit.Setup
Padding = new MarginPadding
{
Vertical = 10,
- Horizontal = EditorRoundedScreen.HORIZONTAL_PADDING
+ Horizontal = 100
};
InternalChild = new FillFlowContainer
diff --git a/osu.Game/Screens/Edit/Timing/GroupSection.cs b/osu.Game/Screens/Edit/Timing/GroupSection.cs
index 03059ff6e1..bb2dd35a9c 100644
--- a/osu.Game/Screens/Edit/Timing/GroupSection.cs
+++ b/osu.Game/Screens/Edit/Timing/GroupSection.cs
@@ -17,7 +17,7 @@ namespace osu.Game.Screens.Edit.Timing
{
private LabelledTextBox textBox;
- private TriangleButton button;
+ private OsuButton button;
[Resolved]
protected Bindable SelectedGroup { get; private set; }
@@ -53,7 +53,7 @@ namespace osu.Game.Screens.Edit.Timing
{
Label = "Time"
},
- button = new TriangleButton
+ button = new RoundedButton
{
Text = "Use current time",
RelativeSizeAxes = Axes.X,
diff --git a/osu.Game/Screens/Edit/Timing/Section.cs b/osu.Game/Screens/Edit/Timing/Section.cs
index 8659b7aff6..139abfb187 100644
--- a/osu.Game/Screens/Edit/Timing/Section.cs
+++ b/osu.Game/Screens/Edit/Timing/Section.cs
@@ -44,9 +44,15 @@ namespace osu.Game.Screens.Edit.Timing
AutoSizeAxes = Axes.Y;
Masking = true;
+ CornerRadius = 5;
InternalChildren = new Drawable[]
{
+ new Box
+ {
+ Colour = colours.Background4,
+ RelativeSizeAxes = Axes.Both,
+ },
new Container
{
RelativeSizeAxes = Axes.X,
@@ -69,11 +75,6 @@ namespace osu.Game.Screens.Edit.Timing
AutoSizeAxes = Axes.Y,
Children = new Drawable[]
{
- new Box
- {
- Colour = colours.Background3,
- RelativeSizeAxes = Axes.Both,
- },
Flow = new FillFlowContainer
{
Padding = new MarginPadding(20),
diff --git a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs
index 67f1dacec4..9f036f0215 100644
--- a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs
+++ b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs
@@ -11,6 +11,7 @@ using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Overlays.Settings;
using osu.Game.Utils;
+using osuTK;
namespace osu.Game.Screens.Edit.Timing
{
@@ -33,6 +34,7 @@ namespace osu.Game.Screens.Edit.Timing
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
+ Spacing = new Vector2(20),
Children = new Drawable[]
{
textBox = new LabelledTextBox
diff --git a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs
index 1b0f0a3f5e..d0ab4d1f98 100644
--- a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs
+++ b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs
@@ -24,8 +24,8 @@ namespace osu.Game.Screens.Edit.Timing
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider, OsuColour colours)
{
- Height = 200;
RelativeSizeAxes = Axes.X;
+ AutoSizeAxes = Axes.Y;
CornerRadius = LabelledDrawable.CORNER_RADIUS;
Masking = true;
@@ -39,20 +39,44 @@ namespace osu.Game.Screens.Edit.Timing
},
new GridContainer
{
- RelativeSizeAxes = Axes.Both,
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
RowDimensions = new[]
{
- new Dimension(),
+ new Dimension(GridSizeMode.Absolute, 200),
new Dimension(GridSizeMode.Absolute, 60),
},
Content = new[]
{
new Drawable[]
{
- new MetronomeDisplay
+ new Container
{
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
+ {
+ new GridContainer
+ {
+ RelativeSizeAxes = Axes.Both,
+ ColumnDimensions = new[]
+ {
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension()
+ },
+ Content = new[]
+ {
+ new Drawable[]
+ {
+ new MetronomeDisplay
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ },
+ new WaveformComparisonDisplay(),
+ }
+ },
+ }
+ }
}
},
new Drawable[]
diff --git a/osu.Game/Screens/Edit/Timing/TimingScreen.cs b/osu.Game/Screens/Edit/Timing/TimingScreen.cs
index a4193d5084..f71a8d7d22 100644
--- a/osu.Game/Screens/Edit/Timing/TimingScreen.cs
+++ b/osu.Game/Screens/Edit/Timing/TimingScreen.cs
@@ -10,12 +10,13 @@ using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Overlays;
using osuTK;
namespace osu.Game.Screens.Edit.Timing
{
- public class TimingScreen : EditorRoundedScreen
+ public class TimingScreen : EditorScreenWithTimeline
{
[Cached]
private Bindable selectedGroup = new Bindable();
@@ -25,27 +26,23 @@ namespace osu.Game.Screens.Edit.Timing
{
}
- [BackgroundDependencyLoader]
- private void load()
+ protected override Drawable CreateMainContent() => new GridContainer
{
- Add(new GridContainer
+ RelativeSizeAxes = Axes.Both,
+ ColumnDimensions = new[]
{
- RelativeSizeAxes = Axes.Both,
- ColumnDimensions = new[]
+ new Dimension(),
+ new Dimension(GridSizeMode.Absolute, 350),
+ },
+ Content = new[]
+ {
+ new Drawable[]
{
- new Dimension(),
- new Dimension(GridSizeMode.Absolute, 350),
+ new ControlPointList(),
+ new ControlPointSettings(),
},
- Content = new[]
- {
- new Drawable[]
- {
- new ControlPointList(),
- new ControlPointSettings(),
- },
- }
- });
- }
+ }
+ };
public class ControlPointList : CompositeDrawable
{
@@ -76,12 +73,12 @@ namespace osu.Game.Screens.Edit.Timing
{
new Box
{
- Colour = colours.Background3,
+ Colour = colours.Background4,
RelativeSizeAxes = Axes.Both,
},
new Box
{
- Colour = colours.Background2,
+ Colour = colours.Background3,
RelativeSizeAxes = Axes.Y,
Width = ControlPointTable.TIMING_COLUMN_WIDTH + margins,
},
@@ -100,7 +97,7 @@ namespace osu.Game.Screens.Edit.Timing
Spacing = new Vector2(5),
Children = new Drawable[]
{
- deleteButton = new OsuButton
+ deleteButton = new RoundedButton
{
Text = "-",
Size = new Vector2(30, 30),
@@ -108,7 +105,7 @@ namespace osu.Game.Screens.Edit.Timing
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight,
},
- new OsuButton
+ new RoundedButton
{
Text = "+ Add at current time",
Action = addNew,
diff --git a/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs b/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs
new file mode 100644
index 0000000000..c80d3c4261
--- /dev/null
+++ b/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs
@@ -0,0 +1,218 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+#nullable enable
+
+using System;
+using System.Linq;
+using osu.Framework.Allocation;
+using osu.Framework.Bindables;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Audio;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Shapes;
+using osu.Framework.Input.Events;
+using osu.Game.Beatmaps;
+using osu.Game.Beatmaps.ControlPoints;
+using osu.Game.Graphics.Sprites;
+using osu.Game.Graphics.UserInterfaceV2;
+using osu.Game.Overlays;
+using osuTK;
+using osuTK.Graphics;
+
+namespace osu.Game.Screens.Edit.Timing
+{
+ internal class WaveformComparisonDisplay : CompositeDrawable
+ {
+ private const int total_waveforms = 8;
+
+ private readonly BindableNumber beatLength = new BindableDouble();
+
+ [Resolved]
+ private IBindable beatmap { get; set; } = null!;
+
+ [Resolved]
+ private EditorBeatmap editorBeatmap { get; set; } = null!;
+
+ [Resolved]
+ private Bindable selectedGroup { get; set; } = null!;
+
+ [Resolved]
+ private EditorClock editorClock { get; set; } = null!;
+
+ private TimingControlPoint timingPoint = TimingControlPoint.DEFAULT;
+
+ private int lastDisplayedBeatIndex;
+
+ private double selectedGroupStartTime;
+ private double selectedGroupEndTime;
+
+ private readonly IBindableList controlPointGroups = new BindableList();
+
+ public WaveformComparisonDisplay()
+ {
+ RelativeSizeAxes = Axes.Both;
+
+ CornerRadius = LabelledDrawable.CORNER_RADIUS;
+ Masking = true;
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ for (int i = 0; i < total_waveforms; i++)
+ {
+ AddInternal(new WaveformRow
+ {
+ RelativeSizeAxes = Axes.Both,
+ RelativePositionAxes = Axes.Both,
+ Height = 1f / total_waveforms,
+ Y = (float)i / total_waveforms,
+ });
+ }
+
+ AddInternal(new Circle
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Colour = Color4.White,
+ RelativeSizeAxes = Axes.Y,
+ Width = 3,
+ });
+
+ selectedGroup.BindValueChanged(_ => updateTimingGroup(), true);
+
+ controlPointGroups.BindTo(editorBeatmap.ControlPointInfo.Groups);
+ controlPointGroups.BindCollectionChanged((_, __) => updateTimingGroup());
+
+ beatLength.BindValueChanged(_ => showFrom(lastDisplayedBeatIndex), true);
+ }
+
+ private void updateTimingGroup()
+ {
+ beatLength.UnbindBindings();
+
+ selectedGroupStartTime = 0;
+ selectedGroupEndTime = beatmap.Value.Track.Length;
+
+ var tcp = selectedGroup.Value?.ControlPoints.OfType().FirstOrDefault();
+
+ if (tcp == null)
+ {
+ timingPoint = new TimingControlPoint();
+ return;
+ }
+
+ timingPoint = tcp;
+ beatLength.BindTo(timingPoint.BeatLengthBindable);
+
+ selectedGroupStartTime = selectedGroup.Value?.Time ?? 0;
+
+ var nextGroup = editorBeatmap.ControlPointInfo.TimingPoints
+ .SkipWhile(g => g != tcp)
+ .Skip(1)
+ .FirstOrDefault();
+
+ if (nextGroup != null)
+ selectedGroupEndTime = nextGroup.Time;
+ }
+
+ protected override bool OnHover(HoverEvent e) => true;
+
+ protected override bool OnMouseMove(MouseMoveEvent e)
+ {
+ float trackLength = (float)beatmap.Value.Track.Length;
+ int totalBeatsAvailable = (int)(trackLength / timingPoint.BeatLength);
+
+ Scheduler.AddOnce(showFrom, (int)(e.MousePosition.X / DrawWidth * totalBeatsAvailable));
+
+ return base.OnMouseMove(e);
+ }
+
+ protected override void Update()
+ {
+ base.Update();
+
+ if (!IsHovered)
+ {
+ int currentBeat = (int)Math.Floor((editorClock.CurrentTimeAccurate - selectedGroupStartTime) / timingPoint.BeatLength);
+
+ showFrom(currentBeat);
+ }
+ }
+
+ private void showFrom(int beatIndex)
+ {
+ if (lastDisplayedBeatIndex == beatIndex)
+ return;
+
+ // Chosen as a pretty usable number across all BPMs.
+ // Optimally we'd want this to scale with the BPM in question, but performing
+ // scaling of the display is both expensive in resampling, and decreases usability
+ // (as it is harder to track the waveform when making realtime adjustments).
+ const float visible_width = 300;
+
+ float trackLength = (float)beatmap.Value.Track.Length;
+ float scale = trackLength / visible_width;
+
+ // Start displaying from before the current beat
+ beatIndex -= total_waveforms / 2;
+
+ foreach (var row in InternalChildren.OfType())
+ {
+ // offset to the required beat index.
+ double time = selectedGroupStartTime + beatIndex * timingPoint.BeatLength;
+
+ float offset = (float)(time - visible_width / 2) / trackLength * scale;
+
+ row.Alpha = time < selectedGroupStartTime || time > selectedGroupEndTime ? 0.2f : 1;
+ row.WaveformOffset = -offset;
+ row.WaveformScale = new Vector2(scale, 1);
+ row.BeatIndex = beatIndex++;
+ }
+
+ lastDisplayedBeatIndex = beatIndex;
+ }
+
+ internal class WaveformRow : CompositeDrawable
+ {
+ private OsuSpriteText beatIndexText = null!;
+ private WaveformGraph waveformGraph = null!;
+
+ [Resolved]
+ private OverlayColourProvider colourProvider { get; set; } = null!;
+
+ [BackgroundDependencyLoader]
+ private void load(IBindable beatmap)
+ {
+ InternalChildren = new Drawable[]
+ {
+ waveformGraph = new WaveformGraph
+ {
+ RelativeSizeAxes = Axes.Both,
+ RelativePositionAxes = Axes.Both,
+ Waveform = beatmap.Value.Waveform,
+ Resolution = 1,
+
+ BaseColour = colourProvider.Colour0,
+ LowColour = colourProvider.Colour1,
+ MidColour = colourProvider.Colour2,
+ HighColour = colourProvider.Colour4,
+ },
+ beatIndexText = new OsuSpriteText
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ Padding = new MarginPadding(5),
+ Colour = colourProvider.Content2
+ }
+ };
+ }
+
+ public int BeatIndex { set => beatIndexText.Text = value.ToString(); }
+ public Vector2 WaveformScale { set => waveformGraph.Scale = value; }
+ public float WaveformOffset { set => waveformGraph.X = value; }
+ }
+ }
+}
diff --git a/osu.Game/Screens/Edit/Verify/IssueList.cs b/osu.Game/Screens/Edit/Verify/IssueList.cs
index 5fe43199cc..415acc0e22 100644
--- a/osu.Game/Screens/Edit/Verify/IssueList.cs
+++ b/osu.Game/Screens/Edit/Verify/IssueList.cs
@@ -10,7 +10,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps;
using osu.Game.Graphics.Containers;
-using osu.Game.Graphics.UserInterface;
+using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Overlays;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Checks.Components;
@@ -67,7 +67,7 @@ namespace osu.Game.Screens.Edit.Verify
Margin = new MarginPadding(20),
Children = new Drawable[]
{
- new TriangleButton
+ new RoundedButton
{
Text = "Refresh",
Action = refresh,
diff --git a/osu.Game/Screens/Edit/Verify/VerifyScreen.cs b/osu.Game/Screens/Edit/Verify/VerifyScreen.cs
index 08643eb8c1..9dc5a53907 100644
--- a/osu.Game/Screens/Edit/Verify/VerifyScreen.cs
+++ b/osu.Game/Screens/Edit/Verify/VerifyScreen.cs
@@ -11,7 +11,7 @@ using osu.Game.Rulesets.Edit.Checks.Components;
namespace osu.Game.Screens.Edit.Verify
{
[Cached]
- public class VerifyScreen : EditorRoundedScreen
+ public class VerifyScreen : EditorScreen
{
public readonly Bindable SelectedIssue = new Bindable();
@@ -32,7 +32,6 @@ namespace osu.Game.Screens.Edit.Verify
InterpretedDifficulty.Default = BeatmapDifficultyCache.GetDifficultyRating(EditorBeatmap.BeatmapInfo.StarRating);
InterpretedDifficulty.SetDefault();
- IssueList = new IssueList();
Child = new Container
{
RelativeSizeAxes = Axes.Both,
@@ -48,7 +47,7 @@ namespace osu.Game.Screens.Edit.Verify
{
new Drawable[]
{
- IssueList,
+ IssueList = new IssueList(),
new IssueSettings(),
},
}
diff --git a/osu.Game/Screens/OnlinePlay/FreeModSelectOverlay.cs b/osu.Game/Screens/OnlinePlay/FreeModSelectOverlay.cs
index f494f9799a..7c9184cc0f 100644
--- a/osu.Game/Screens/OnlinePlay/FreeModSelectOverlay.cs
+++ b/osu.Game/Screens/OnlinePlay/FreeModSelectOverlay.cs
@@ -6,18 +6,14 @@ using osu.Game.Overlays;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics;
-using osu.Framework.Input;
-using osu.Framework.Input.Bindings;
-using osu.Framework.Input.Events;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Mods;
using osu.Game.Rulesets.Mods;
using osuTK.Input;
-using osu.Game.Localisation;
namespace osu.Game.Screens.OnlinePlay
{
- public class FreeModSelectOverlay : ModSelectOverlay, IKeyBindingHandler
+ public class FreeModSelectOverlay : ModSelectOverlay
{
protected override bool ShowTotalMultiplier => false;
@@ -29,8 +25,6 @@ namespace osu.Game.Screens.OnlinePlay
set => base.IsValidMod = m => m.UserPlayable && value.Invoke(m);
}
- private ShearedButton selectAllButton;
-
public FreeModSelectOverlay()
: base(OverlayColourScheme.Plum)
{
@@ -40,31 +34,10 @@ namespace osu.Game.Screens.OnlinePlay
protected override ModColumn CreateModColumn(ModType modType, Key[] toggleKeys = null) => new ModColumn(modType, true, toggleKeys);
protected override IEnumerable CreateFooterButtons() => base.CreateFooterButtons().Prepend(
- selectAllButton = new ShearedButton(BUTTON_WIDTH)
+ new SelectAllModsButton(this)
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
- Text = CommonStrings.SelectAll,
- Action = SelectAll
});
-
- public bool OnPressed(KeyBindingPressEvent e)
- {
- if (e.Repeat)
- return false;
-
- switch (e.Action)
- {
- case PlatformAction.SelectAll:
- selectAllButton.TriggerClick();
- return true;
- }
-
- return false;
- }
-
- public void OnReleased(KeyBindingReleaseEvent e)
- {
- }
}
}
diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs
index 66ab427565..542f06f86b 100644
--- a/osu.Game/Tests/Visual/EditorClockTestScene.cs
+++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs
@@ -5,6 +5,7 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Input.Events;
using osu.Game.Beatmaps;
+using osu.Game.Overlays;
using osu.Game.Screens.Edit;
namespace osu.Game.Tests.Visual
@@ -15,6 +16,9 @@ namespace osu.Game.Tests.Visual
///
public abstract class EditorClockTestScene : OsuManualInputManagerTestScene
{
+ [Cached]
+ private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Aquamarine);
+
protected readonly BindableBeatDivisor BeatDivisor = new BindableBeatDivisor();
protected new readonly EditorClock Clock;
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 5bc65ca507..32a0adb859 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -35,7 +35,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 3597e7e5c0..112b5b4615 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -61,7 +61,7 @@
-
+
@@ -84,7 +84,7 @@
-
+