diff --git a/osu.Android.props b/osu.Android.props
index 8b22df418f..8d79eb94a8 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -51,8 +51,8 @@
-
-
+
+
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
index a1c8879105..fa2d2ba38c 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
@@ -6,10 +6,10 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Primitives;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Osu.Judgements;
using osu.Game.Graphics.Containers;
-using osu.Game.Rulesets.Osu.UI;
using osuTK;
namespace osu.Game.Rulesets.Osu.Objects.Drawables
@@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
// Must be set to update IsHovered as it's used in relax mod to detect osu hit objects.
public override bool HandlePositionalInput => true;
- protected override float SamplePlaybackPosition => HitObject.X / OsuPlayfield.BASE_SIZE.X;
+ protected override float SamplePlaybackPosition => CalculateDrawableRelativePosition(this);
///
/// Whether this can be hit, given a time value.
@@ -89,6 +89,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
///
public void MissForcefully() => ApplyResult(r => r.Type = r.Judgement.MinResult);
+ private RectangleF parentScreenSpaceRectangle => ((DrawableOsuHitObject)ParentHitObject)?.parentScreenSpaceRectangle ?? Parent.ScreenSpaceDrawQuad.AABBFloat;
+
+ ///
+ /// Calculates the position of the given relative to the playfield area.
+ ///
+ /// The drawable to calculate its relative position.
+ protected float CalculateDrawableRelativePosition(Drawable drawable) => (drawable.ScreenSpaceDrawQuad.Centre.X - parentScreenSpaceRectangle.X) / parentScreenSpaceRectangle.Width;
+
protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(HitObject, judgement);
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
index 1447f131c6..c48ab998ba 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
@@ -13,7 +13,6 @@ using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Skinning;
using osu.Game.Rulesets.Osu.Skinning.Default;
-using osu.Game.Rulesets.Osu.UI;
using osu.Game.Rulesets.Scoring;
using osu.Game.Skinning;
using osuTK;
@@ -208,7 +207,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
if (Tracking.Value && slidingSample != null)
// keep the sliding sample playing at the current tracking position
- slidingSample.Balance.Value = CalculateSamplePlaybackBalance(Ball.X / OsuPlayfield.BASE_SIZE.X);
+ slidingSample.Balance.Value = CalculateSamplePlaybackBalance(CalculateDrawableRelativePosition(Ball));
double completionProgress = Math.Clamp((Time.Current - HitObject.StartTime) / HitObject.Duration, 0, 1);
diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
index 9f708ace70..f7140537ee 100644
--- a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
+++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
@@ -359,9 +359,9 @@ namespace osu.Game.Tests.Visual.Background
protected override BackgroundScreen CreateBackground() =>
new FadeAccessibleBackground(Beatmap.Value);
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
ApplyToBackground(b => ReplacesBackground.BindTo(b.StoryboardReplacesBackground));
}
diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs
index ea0255ab76..a224a78531 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs
@@ -389,9 +389,9 @@ namespace osu.Game.Tests.Visual.Gameplay
public void ExitViaQuickExit() => PerformExit(false);
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
GameplayClockContainer.Stop();
}
}
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs
index ccf13e1e8f..64afe1235b 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs
@@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private TestSkinSourceContainer skinSource;
private PausableSkinnableSound skinnableSound;
- [SetUp]
+ [SetUpSteps]
public void SetUpSteps()
{
AddStep("setup hierarchy", () =>
diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneFreeModSelectScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneFreeModSelectScreen.cs
index 0db05e3a6a..b5f901e51d 100644
--- a/osu.Game.Tests/Visual/Multiplayer/TestSceneFreeModSelectScreen.cs
+++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneFreeModSelectScreen.cs
@@ -21,8 +21,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
{
State = { Value = Visibility.Visible }
});
+ AddUntilStep("all column content loaded",
+ () => freeModSelectScreen.ChildrenOfType().Any()
+ && freeModSelectScreen.ChildrenOfType().All(column => column.IsLoaded && column.ItemsLoaded));
- AddAssert("all visible mods are playable",
+ AddUntilStep("all visible mods are playable",
() => this.ChildrenOfType()
.Where(panel => panel.IsPresent)
.All(panel => panel.Mod.HasImplementation && panel.Mod.UserPlayable));
diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs b/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs
index 559e6ddd89..2ce914ba3d 100644
--- a/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs
@@ -230,7 +230,7 @@ namespace osu.Game.Tests.Visual.Navigation
public int ExitAttempts { get; private set; }
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
ExitAttempts++;
@@ -240,7 +240,7 @@ namespace osu.Game.Tests.Visual.Navigation
return true;
}
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
}
@@ -257,7 +257,7 @@ namespace osu.Game.Tests.Visual.Navigation
SubScreenStack.Push(Blocker = new DialogBlockingScreen());
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
if (SubScreenStack.CurrentScreen != null)
{
@@ -265,7 +265,7 @@ namespace osu.Game.Tests.Visual.Navigation
return true;
}
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
}
}
diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs
index 2106043544..cdeaafd828 100644
--- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs
+++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs
@@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
+using osu.Game.Overlays.Settings;
using osu.Game.Overlays.Settings.Sections;
using osu.Game.Overlays.Settings.Sections.Input;
using osuTK.Input;
@@ -34,6 +35,29 @@ namespace osu.Game.Tests.Visual.Settings
});
}
+ [Test]
+ public void TestQuickFiltering()
+ {
+ AddStep("set filter", () =>
+ {
+ settings.SectionsContainer.ChildrenOfType().First().Current.Value = "scaling";
+ });
+
+ AddUntilStep("wait for items to load", () => settings.SectionsContainer.ChildrenOfType().Any());
+
+ AddAssert("ensure all items match filter", () => settings.SectionsContainer
+ .ChildrenOfType().Where(f => f.IsPresent)
+ .All(section =>
+ section.Children.Where(f => f.IsPresent)
+ .OfType()
+ .OfType()
+ .Where(f => !(f is IHasFilterableChildren))
+ .All(f => f.FilterTerms.Any(t => t.Contains("scaling")))
+ ));
+
+ AddAssert("ensure section is current", () => settings.CurrentSection.Value is GraphicsSection);
+ }
+
[Test]
public void ToggleVisibility()
{
diff --git a/osu.Game.Tests/Visual/TestMultiplayerComponents.cs b/osu.Game.Tests/Visual/TestMultiplayerComponents.cs
index c43ed744bd..4ab201ef46 100644
--- a/osu.Game.Tests/Visual/TestMultiplayerComponents.cs
+++ b/osu.Game.Tests/Visual/TestMultiplayerComponents.cs
@@ -80,10 +80,10 @@ namespace osu.Game.Tests.Visual
public override bool OnBackButton() => (screenStack.CurrentScreen as OsuScreen)?.OnBackButton() ?? base.OnBackButton();
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
if (screenStack.CurrentScreen == null)
- return base.OnExiting(next);
+ return base.OnExiting(e);
screenStack.Exit();
return true;
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenUIScale.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenUIScale.cs
new file mode 100644
index 0000000000..5ca09b34aa
--- /dev/null
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenUIScale.cs
@@ -0,0 +1,19 @@
+// 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.Screens;
+using osu.Game.Overlays.FirstRunSetup;
+
+namespace osu.Game.Tests.Visual.UserInterface
+{
+ public class TestSceneFirstRunScreenUIScale : OsuManualInputManagerTestScene
+ {
+ public TestSceneFirstRunScreenUIScale()
+ {
+ AddStep("load screen", () =>
+ {
+ Child = new ScreenStack(new ScreenUIScale());
+ });
+ }
+ }
+}
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunSetupOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunSetupOverlay.cs
new file mode 100644
index 0000000000..efce4f350b
--- /dev/null
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunSetupOverlay.cs
@@ -0,0 +1,193 @@
+// 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.Linq;
+using Moq;
+using NUnit.Framework;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Screens;
+using osu.Framework.Testing;
+using osu.Game.Configuration;
+using osu.Game.Localisation;
+using osu.Game.Overlays;
+using osu.Game.Overlays.FirstRunSetup;
+using osu.Game.Overlays.Notifications;
+using osu.Game.Screens;
+using osuTK;
+using osuTK.Input;
+
+namespace osu.Game.Tests.Visual.UserInterface
+{
+ public class TestSceneFirstRunSetupOverlay : OsuManualInputManagerTestScene
+ {
+ private FirstRunSetupOverlay overlay;
+
+ private readonly Mock performer = new Mock();
+
+ private readonly Mock notificationOverlay = new Mock();
+
+ private Notification lastNotification;
+
+ protected OsuConfigManager LocalConfig;
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ Dependencies.Cache(LocalConfig = new OsuConfigManager(LocalStorage));
+ Dependencies.CacheAs(performer.Object);
+ Dependencies.CacheAs(notificationOverlay.Object);
+ }
+
+ [SetUpSteps]
+ public void SetUpSteps()
+ {
+ AddStep("setup dependencies", () =>
+ {
+ performer.Reset();
+ notificationOverlay.Reset();
+
+ performer.Setup(g => g.PerformFromScreen(It.IsAny>(), It.IsAny>()))
+ .Callback((Action action, IEnumerable types) => action(null));
+
+ notificationOverlay.Setup(n => n.Post(It.IsAny()))
+ .Callback((Notification n) => lastNotification = n);
+ });
+
+ AddStep("add overlay", () =>
+ {
+ Child = overlay = new FirstRunSetupOverlay
+ {
+ State = { Value = Visibility.Visible }
+ };
+ });
+ }
+
+ [Test]
+ public void TestDoesntOpenOnSecondRun()
+ {
+ AddStep("set first run", () => LocalConfig.SetValue(OsuSetting.ShowFirstRunSetup, true));
+
+ AddUntilStep("step through", () =>
+ {
+ if (overlay.CurrentScreen?.IsLoaded != false) overlay.NextButton.TriggerClick();
+ return overlay.State.Value == Visibility.Hidden;
+ });
+
+ AddAssert("first run false", () => !LocalConfig.Get(OsuSetting.ShowFirstRunSetup));
+
+ AddStep("add overlay", () =>
+ {
+ Child = overlay = new FirstRunSetupOverlay();
+ });
+
+ AddWaitStep("wait some", 5);
+
+ AddAssert("overlay didn't show", () => overlay.State.Value == Visibility.Hidden);
+ }
+
+ [TestCase(false)]
+ [TestCase(true)]
+ public void TestOverlayRunsToFinish(bool keyboard)
+ {
+ AddUntilStep("step through", () =>
+ {
+ if (overlay.CurrentScreen?.IsLoaded != false)
+ {
+ if (keyboard)
+ InputManager.Key(Key.Enter);
+ else
+ overlay.NextButton.TriggerClick();
+ }
+
+ return overlay.State.Value == Visibility.Hidden;
+ });
+
+ AddUntilStep("wait for screens removed", () => !overlay.ChildrenOfType().Any());
+
+ AddStep("no notifications", () => notificationOverlay.VerifyNoOtherCalls());
+
+ AddStep("display again on demand", () => overlay.Show());
+
+ AddUntilStep("back at start", () => overlay.CurrentScreen is ScreenWelcome);
+ }
+
+ [TestCase(false)]
+ [TestCase(true)]
+ public void TestBackButton(bool keyboard)
+ {
+ AddAssert("back button disabled", () => !overlay.BackButton.Enabled.Value);
+
+ AddUntilStep("step to last", () =>
+ {
+ var nextButton = overlay.NextButton;
+
+ if (overlay.CurrentScreen?.IsLoaded != false)
+ nextButton.TriggerClick();
+
+ return nextButton.Text == CommonStrings.Finish;
+ });
+
+ AddUntilStep("step back to start", () =>
+ {
+ if (overlay.CurrentScreen?.IsLoaded != false)
+ {
+ if (keyboard)
+ InputManager.Key(Key.Escape);
+ else
+ overlay.BackButton.TriggerClick();
+ }
+
+ return overlay.CurrentScreen is ScreenWelcome;
+ });
+
+ AddAssert("back button disabled", () => !overlay.BackButton.Enabled.Value);
+
+ if (keyboard)
+ {
+ AddStep("exit via keyboard", () => InputManager.Key(Key.Escape));
+ AddAssert("overlay dismissed", () => overlay.State.Value == Visibility.Hidden);
+ }
+ }
+
+ [Test]
+ public void TestClickAwayToExit()
+ {
+ AddStep("click inside content", () =>
+ {
+ InputManager.MoveMouseTo(overlay.ScreenSpaceDrawQuad.Centre);
+ InputManager.Click(MouseButton.Left);
+ });
+
+ AddAssert("overlay not dismissed", () => overlay.State.Value == Visibility.Visible);
+
+ AddStep("click outside content", () =>
+ {
+ InputManager.MoveMouseTo(overlay.ScreenSpaceDrawQuad.TopLeft - new Vector2(1));
+ InputManager.Click(MouseButton.Left);
+ });
+
+ AddAssert("overlay dismissed", () => overlay.State.Value == Visibility.Hidden);
+ }
+
+ [Test]
+ public void TestResumeViaNotification()
+ {
+ AddStep("step to next", () => overlay.NextButton.TriggerClick());
+
+ AddAssert("is at known screen", () => overlay.CurrentScreen is ScreenUIScale);
+
+ AddStep("hide", () => overlay.Hide());
+ AddAssert("overlay hidden", () => overlay.State.Value == Visibility.Hidden);
+
+ AddStep("notification arrived", () => notificationOverlay.Verify(n => n.Post(It.IsAny()), Times.Once));
+
+ AddStep("run notification action", () => lastNotification.Activated());
+
+ AddAssert("overlay shown", () => overlay.State.Value == Visibility.Visible);
+ AddAssert("is resumed", () => overlay.CurrentScreen is ScreenUIScale);
+ }
+ }
+}
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
index aba01a1294..5479644772 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
@@ -7,7 +7,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osuTK;
@@ -16,11 +15,11 @@ namespace osu.Game.Beatmaps.Drawables
{
internal class DifficultyIconTooltip : VisibilityContainer, ITooltip
{
- private readonly OsuSpriteText difficultyName, starRating;
- private readonly Box background;
- private readonly FillFlowContainer difficultyFlow;
+ private OsuSpriteText difficultyName;
+ private StarRatingDisplay starRating;
- public DifficultyIconTooltip()
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
{
AutoSizeAxes = Axes.Both;
Masking = true;
@@ -28,9 +27,10 @@ namespace osu.Game.Beatmaps.Drawables
Children = new Drawable[]
{
- background = new Box
+ new Box
{
Alpha = 0.9f,
+ Colour = colours.Gray3,
RelativeSizeAxes = Axes.Both
},
new FillFlowContainer
@@ -40,6 +40,7 @@ namespace osu.Game.Beatmaps.Drawables
AutoSizeEasing = Easing.OutQuint,
Direction = FillDirection.Vertical,
Padding = new MarginPadding(10),
+ Spacing = new Vector2(5),
Children = new Drawable[]
{
difficultyName = new OsuSpriteText
@@ -48,57 +49,27 @@ namespace osu.Game.Beatmaps.Drawables
Origin = Anchor.Centre,
Font = OsuFont.GetFont(size: 16, weight: FontWeight.Bold),
},
- difficultyFlow = new FillFlowContainer
+ starRating = new StarRatingDisplay(default, StarRatingDisplaySize.Small)
{
- AutoSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Direction = FillDirection.Horizontal,
- Children = new Drawable[]
- {
- starRating = new OsuSpriteText
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 16, weight: FontWeight.Regular),
- },
- new SpriteIcon
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Margin = new MarginPadding { Left = 4 },
- Icon = FontAwesome.Solid.Star,
- Size = new Vector2(12),
- },
- }
}
}
}
};
}
- [Resolved]
- private OsuColour colours { get; set; }
-
- [BackgroundDependencyLoader]
- private void load()
- {
- background.Colour = colours.Gray3;
- }
-
- private readonly IBindable starDifficulty = new Bindable();
+ private DifficultyIconTooltipContent displayedContent;
public void SetContent(DifficultyIconTooltipContent content)
{
- difficultyName.Text = content.BeatmapInfo.DifficultyName;
+ if (displayedContent != null)
+ starRating.Current.UnbindFrom(displayedContent.Difficulty);
- starDifficulty.UnbindAll();
- starDifficulty.BindTo(content.Difficulty);
- starDifficulty.BindValueChanged(difficulty =>
- {
- starRating.Text = $"{difficulty.NewValue.Stars:0.##}";
- difficultyFlow.Colour = colours.ForStarDifficulty(difficulty.NewValue.Stars);
- }, true);
+ displayedContent = content;
+
+ starRating.Current.BindTarget = displayedContent.Difficulty;
+ difficultyName.Text = displayedContent.BeatmapInfo.DifficultyName;
}
public void Move(Vector2 pos) => Position = pos;
diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs
index 9aacb50684..2c04b03646 100644
--- a/osu.Game/Configuration/OsuConfigManager.cs
+++ b/osu.Game/Configuration/OsuConfigManager.cs
@@ -134,6 +134,8 @@ namespace osu.Game.Configuration
SetDefault(OsuSetting.Version, string.Empty);
+ SetDefault(OsuSetting.ShowFirstRunSetup, true);
+
SetDefault(OsuSetting.ScreenshotFormat, ScreenshotFormat.Jpg);
SetDefault(OsuSetting.ScreenshotCaptureMenuCursor, false);
@@ -308,6 +310,7 @@ namespace osu.Game.Configuration
BeatmapListingCardSize,
ToolbarClockDisplayMode,
Version,
+ ShowFirstRunSetup,
ShowConvertedBeatmaps,
Skin,
ScreenshotFormat,
diff --git a/osu.Game/Graphics/Containers/ScalingContainer.cs b/osu.Game/Graphics/Containers/ScalingContainer.cs
index ca8b6f388f..11bfd80ec1 100644
--- a/osu.Game/Graphics/Containers/ScalingContainer.cs
+++ b/osu.Game/Graphics/Containers/ScalingContainer.cs
@@ -79,12 +79,12 @@ namespace osu.Game.Graphics.Containers
};
}
- private class ScalingDrawSizePreservingFillContainer : DrawSizePreservingFillContainer
+ public class ScalingDrawSizePreservingFillContainer : DrawSizePreservingFillContainer
{
private readonly bool applyUIScale;
private Bindable uiScale;
- private float currentScale = 1;
+ protected float CurrentScale { get; private set; } = 1;
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
@@ -99,14 +99,14 @@ namespace osu.Game.Graphics.Containers
if (applyUIScale)
{
uiScale = osuConfig.GetBindable(OsuSetting.UIScale);
- uiScale.BindValueChanged(args => this.TransformTo(nameof(currentScale), args.NewValue, duration, Easing.OutQuart), true);
+ uiScale.BindValueChanged(args => this.TransformTo(nameof(CurrentScale), args.NewValue, duration, Easing.OutQuart), true);
}
}
protected override void Update()
{
- Scale = new Vector2(currentScale);
- Size = new Vector2(1 / currentScale);
+ Scale = new Vector2(CurrentScale);
+ Size = new Vector2(1 / CurrentScale);
base.Update();
}
@@ -209,7 +209,7 @@ namespace osu.Game.Graphics.Containers
{
protected override bool AllowStoryboardBackground => false;
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
this.FadeInFromZero(4000, Easing.OutQuint);
}
diff --git a/osu.Game/Localisation/CommonStrings.cs b/osu.Game/Localisation/CommonStrings.cs
index b717bb83dd..6da2e4d272 100644
--- a/osu.Game/Localisation/CommonStrings.cs
+++ b/osu.Game/Localisation/CommonStrings.cs
@@ -9,6 +9,16 @@ namespace osu.Game.Localisation
{
private const string prefix = @"osu.Game.Resources.Localisation.Common";
+ ///
+ /// "Back"
+ ///
+ public static LocalisableString Back => new TranslatableString(getKey(@"back"), @"Back");
+
+ ///
+ /// "Finish"
+ ///
+ public static LocalisableString Finish => new TranslatableString(getKey(@"finish"), @"Finish");
+
///
/// "Enabled"
///
diff --git a/osu.Game/Localisation/FirstRunSetupOverlayStrings.cs b/osu.Game/Localisation/FirstRunSetupOverlayStrings.cs
new file mode 100644
index 0000000000..001de93c16
--- /dev/null
+++ b/osu.Game/Localisation/FirstRunSetupOverlayStrings.cs
@@ -0,0 +1,58 @@
+// 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.Localisation;
+
+namespace osu.Game.Localisation
+{
+ public static class FirstRunSetupOverlayStrings
+ {
+ private const string prefix = @"osu.Game.Resources.Localisation.FirstRunSetupOverlay";
+
+ ///
+ /// "Get started"
+ ///
+ public static LocalisableString GetStarted => new TranslatableString(getKey(@"get_started"), @"Get started");
+
+ ///
+ /// "Click to resume first-run setup at any point"
+ ///
+ public static LocalisableString ClickToResumeFirstRunSetupAtAnyPoint => new TranslatableString(getKey(@"click_to_resume_first_run_setup_at_any_point"), @"Click to resume first-run setup at any point");
+
+ ///
+ /// "First-run setup"
+ ///
+ public static LocalisableString FirstRunSetupTitle => new TranslatableString(getKey(@"first_run_setup_title"), @"First-run setup");
+
+ ///
+ /// "Set up osu! to suit you"
+ ///
+ public static LocalisableString FirstRunSetupDescription => new TranslatableString(getKey(@"first_run_setup_description"), @"Set up osu! to suit you");
+
+ ///
+ /// "Welcome"
+ ///
+ public static LocalisableString WelcomeTitle => new TranslatableString(getKey(@"welcome_title"), @"Welcome");
+
+ ///
+ /// "Welcome to the first-run setup guide!
+ ///
+ /// osu! is a very configurable game, and diving straight into the settings can sometimes be overwhelming. This guide will help you get the important choices out of the way to ensure a great first experience!"
+ ///
+ public static LocalisableString WelcomeDescription => new TranslatableString(getKey(@"welcome_description"), @"Welcome to the first-run setup guide!
+
+osu! is a very configurable game, and diving straight into the settings can sometimes be overwhelming. This guide will help you get the important choices out of the way to ensure a great first experience!");
+
+ ///
+ /// "The size of the osu! user interface can be adjusted to your liking."
+ ///
+ public static LocalisableString UIScaleDescription => new TranslatableString(getKey(@"ui_scale_description"), @"The size of the osu! user interface can be adjusted to your liking.");
+
+ ///
+ /// "Next ({0})"
+ ///
+ public static LocalisableString Next(LocalisableString nextStepDescription) => new TranslatableString(getKey(@"next"), @"Next ({0})", nextStepDescription);
+
+ private static string getKey(string key) => $@"{prefix}:{key}";
+ }
+}
diff --git a/osu.Game/Localisation/GeneralSettingsStrings.cs b/osu.Game/Localisation/GeneralSettingsStrings.cs
index c65e6c77f4..2aa91f5245 100644
--- a/osu.Game/Localisation/GeneralSettingsStrings.cs
+++ b/osu.Game/Localisation/GeneralSettingsStrings.cs
@@ -59,6 +59,11 @@ namespace osu.Game.Localisation
///
public static LocalisableString ChangeFolderLocation => new TranslatableString(getKey(@"change_folder_location"), @"Change folder location...");
+ ///
+ /// "Run setup wizard"
+ ///
+ public static LocalisableString RunSetupWizard => new TranslatableString(getKey(@"run_setup_wizard"), @"Run setup wizard");
+
private static string getKey(string key) => $"{prefix}:{key}";
}
}
diff --git a/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs b/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs
index ffb3a3be9b..205fdc9f2b 100644
--- a/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs
+++ b/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs
@@ -29,6 +29,7 @@ namespace osu.Game.Online.API.Requests
Ranked,
Loved,
Pending,
+ Guest,
Graveyard
}
}
diff --git a/osu.Game/Online/API/Requests/Responses/APIUser.cs b/osu.Game/Online/API/Requests/Responses/APIUser.cs
index a87f0811a1..41f486c709 100644
--- a/osu.Game/Online/API/Requests/Responses/APIUser.cs
+++ b/osu.Game/Online/API/Requests/Responses/APIUser.cs
@@ -148,6 +148,9 @@ namespace osu.Game.Online.API.Requests.Responses
[JsonProperty(@"pending_beatmapset_count")]
public int PendingBeatmapsetCount;
+ [JsonProperty(@"guest_beatmapset_count")]
+ public int GuestBeatmapsetCount;
+
[JsonProperty(@"scores_best_count")]
public int ScoresBestCount;
diff --git a/osu.Game/Online/HubClientConnector.cs b/osu.Game/Online/HubClientConnector.cs
index c79660568c..ca9bf00b23 100644
--- a/osu.Game/Online/HubClientConnector.cs
+++ b/osu.Game/Online/HubClientConnector.cs
@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
+using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR.Client;
@@ -144,6 +145,12 @@ namespace osu.Game.Online
var builder = new HubConnectionBuilder()
.WithUrl(endpoint, options =>
{
+ // Use HttpClient.DefaultProxy once on net6 everywhere.
+ // The credential setter can also be removed at this point.
+ options.Proxy = WebRequest.DefaultWebProxy;
+ if (options.Proxy != null)
+ options.Proxy.Credentials = CredentialCache.DefaultCredentials;
+
options.Headers.Add("Authorization", $"Bearer {api.AccessToken}");
options.Headers.Add("OsuVersionHash", versionHash);
});
diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs
index ba87c69d8f..e9fe8c43de 100644
--- a/osu.Game/OsuGame.cs
+++ b/osu.Game/OsuGame.cs
@@ -149,6 +149,8 @@ namespace osu.Game
protected SettingsOverlay Settings;
+ private FirstRunSetupOverlay firstRunOverlay;
+
private VolumeOverlay volume;
private OsuLogo osuLogo;
@@ -799,6 +801,7 @@ namespace osu.Game
loadComponentSingleFile(CreateUpdateManager(), Add, true);
// overlay elements
+ loadComponentSingleFile(firstRunOverlay = new FirstRunSetupOverlay(), overlayContent.Add, true);
loadComponentSingleFile(new ManageCollectionsDialog(), overlayContent.Add, true);
loadComponentSingleFile(beatmapListing = new BeatmapListingOverlay(), overlayContent.Add, true);
loadComponentSingleFile(dashboard = new DashboardOverlay(), overlayContent.Add, true);
@@ -849,7 +852,7 @@ namespace osu.Game
Add(new MusicKeyBindingHandler());
// side overlays which cancel each other.
- var singleDisplaySideOverlays = new OverlayContainer[] { Settings, Notifications };
+ var singleDisplaySideOverlays = new OverlayContainer[] { Settings, Notifications, firstRunOverlay };
foreach (var overlay in singleDisplaySideOverlays)
{
@@ -874,7 +877,7 @@ namespace osu.Game
}
// ensure only one of these overlays are open at once.
- var singleDisplayOverlays = new OverlayContainer[] { chatOverlay, news, dashboard, beatmapListing, changelogOverlay, rankingsOverlay, wikiOverlay };
+ var singleDisplayOverlays = new OverlayContainer[] { firstRunOverlay, chatOverlay, news, dashboard, beatmapListing, changelogOverlay, rankingsOverlay, wikiOverlay };
foreach (var overlay in singleDisplayOverlays)
{
diff --git a/osu.Game/Overlays/AccountCreation/AccountCreationScreen.cs b/osu.Game/Overlays/AccountCreation/AccountCreationScreen.cs
index 7e2ae405cb..6aef358b2e 100644
--- a/osu.Game/Overlays/AccountCreation/AccountCreationScreen.cs
+++ b/osu.Game/Overlays/AccountCreation/AccountCreationScreen.cs
@@ -8,21 +8,21 @@ namespace osu.Game.Overlays.AccountCreation
{
public abstract class AccountCreationScreen : Screen
{
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
this.FadeOut().Delay(200).FadeIn(200);
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
- base.OnResuming(last);
+ base.OnResuming(e);
this.FadeIn(200);
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
- base.OnSuspending(next);
+ base.OnSuspending(e);
this.FadeOut(200);
}
}
diff --git a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs
index 6cf3fb4267..1be1321d85 100644
--- a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs
+++ b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs
@@ -147,9 +147,9 @@ namespace osu.Game.Overlays.AccountCreation
d.Colour = password.Length == 0 ? Color4.White : Interpolation.ValueAt(password.Length, Color4.OrangeRed, Color4.YellowGreen, 0, 8, Easing.In);
}
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
loadingLayer.Hide();
if (host?.OnScreenKeyboardOverlapsGameWindow != true)
diff --git a/osu.Game/Overlays/AccountCreation/ScreenWarning.cs b/osu.Game/Overlays/AccountCreation/ScreenWarning.cs
index 3d46e9ed94..780a79f8f9 100644
--- a/osu.Game/Overlays/AccountCreation/ScreenWarning.cs
+++ b/osu.Game/Overlays/AccountCreation/ScreenWarning.cs
@@ -31,7 +31,7 @@ namespace osu.Game.Overlays.AccountCreation
private const string help_centre_url = "/help/wiki/Help_Centre#login";
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
if (string.IsNullOrEmpty(api?.ProvidedUsername) || game?.UseDevelopmentServer == true)
{
@@ -40,7 +40,7 @@ namespace osu.Game.Overlays.AccountCreation
return;
}
- base.OnEntering(last);
+ base.OnEntering(e);
}
[BackgroundDependencyLoader(true)]
diff --git a/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs b/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs
new file mode 100644
index 0000000000..eb4b97069c
--- /dev/null
+++ b/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs
@@ -0,0 +1,71 @@
+// 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.Screens;
+using osu.Game.Graphics.Containers;
+using osuTK;
+
+namespace osu.Game.Overlays.FirstRunSetup
+{
+ public abstract class FirstRunSetupScreen : Screen
+ {
+ private const float offset = 100;
+
+ protected FillFlowContainer Content { get; private set; }
+
+ protected FirstRunSetupScreen()
+ {
+ InternalChildren = new Drawable[]
+ {
+ new OsuScrollContainer(Direction.Vertical)
+ {
+ RelativeSizeAxes = Axes.Both,
+ Child = Content = new FillFlowContainer
+ {
+ Spacing = new Vector2(20),
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Vertical,
+ },
+ }
+ };
+ }
+
+ public override void OnEntering(ScreenTransitionEvent e)
+ {
+ base.OnEntering(e);
+ this
+ .FadeInFromZero(500)
+ .MoveToX(offset)
+ .MoveToX(0, 500, Easing.OutQuint);
+ }
+
+ public override void OnResuming(ScreenTransitionEvent e)
+ {
+ base.OnResuming(e);
+ this
+ .FadeInFromZero(500)
+ .MoveToX(0, 500, Easing.OutQuint);
+ }
+
+ public override bool OnExiting(ScreenExitEvent e)
+ {
+ this
+ .FadeOut(100)
+ .MoveToX(offset, 500, Easing.OutQuint);
+
+ return base.OnExiting(e);
+ }
+
+ public override void OnSuspending(ScreenTransitionEvent e)
+ {
+ this
+ .FadeOut(100)
+ .MoveToX(-offset, 500, Easing.OutQuint);
+
+ base.OnSuspending(e);
+ }
+ }
+}
diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs b/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs
new file mode 100644
index 0000000000..d9a612ea26
--- /dev/null
+++ b/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs
@@ -0,0 +1,182 @@
+// 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.Linq;
+using osu.Framework.Allocation;
+using osu.Framework.Audio;
+using osu.Framework.Bindables;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Textures;
+using osu.Framework.Localisation;
+using osu.Framework.Screens;
+using osu.Game.Beatmaps;
+using osu.Game.Configuration;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Containers;
+using osu.Game.Graphics.UserInterface;
+using osu.Game.Localisation;
+using osu.Game.Overlays.Settings;
+using osu.Game.Rulesets;
+using osu.Game.Screens;
+using osu.Game.Screens.Menu;
+using osu.Game.Screens.Select;
+using osu.Game.Tests.Visual;
+using osuTK;
+
+namespace osu.Game.Overlays.FirstRunSetup
+{
+ public class ScreenUIScale : FirstRunSetupScreen
+ {
+ [BackgroundDependencyLoader]
+ private void load(OsuConfigManager config)
+ {
+ Content.Children = new Drawable[]
+ {
+ new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: 24))
+ {
+ Text = FirstRunSetupOverlayStrings.UIScaleDescription,
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y
+ },
+ new SettingsSlider
+ {
+ LabelText = GraphicsSettingsStrings.UIScaling,
+ Current = config.GetBindable(OsuSetting.UIScale),
+ KeyboardStep = 0.01f,
+ },
+ new InverseScalingDrawSizePreservingFillContainer
+ {
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ RelativeSizeAxes = Axes.None,
+ Size = new Vector2(960, 960 / 16f * 9 / 2),
+ Children = new Drawable[]
+ {
+ new GridContainer
+ {
+ RelativeSizeAxes = Axes.Both,
+ Content = new[]
+ {
+ new Drawable[]
+ {
+ new SampleScreenContainer(new PinnedMainMenu()),
+ new SampleScreenContainer(new PlaySongSelect()),
+ },
+ // TODO: add more screens here in the future (gameplay / results)
+ // requires a bit more consideration to isolate their behaviour from the "parent" game.
+ }
+ }
+ }
+ }
+ };
+ }
+
+ private class InverseScalingDrawSizePreservingFillContainer : ScalingContainer.ScalingDrawSizePreservingFillContainer
+ {
+ private Vector2 initialSize;
+
+ public InverseScalingDrawSizePreservingFillContainer()
+ : base(true)
+ {
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ initialSize = Size;
+ }
+
+ protected override void Update()
+ {
+ Size = initialSize / CurrentScale;
+ }
+ }
+
+ private class PinnedMainMenu : MainMenu
+ {
+ public override void OnEntering(ScreenTransitionEvent e)
+ {
+ base.OnEntering(e);
+
+ Buttons.ReturnToTopOnIdle = false;
+ Buttons.State = ButtonSystemState.TopLevel;
+ }
+ }
+
+ private class UIScaleSlider : OsuSliderBar
+ {
+ public override LocalisableString TooltipText => base.TooltipText + "x";
+ }
+
+ private class SampleScreenContainer : CompositeDrawable
+ {
+ // Minimal isolation from main game.
+
+ [Cached]
+ [Cached(typeof(IBindable))]
+ protected readonly Bindable Ruleset = new Bindable();
+
+ [Cached]
+ [Cached(typeof(IBindable))]
+ protected Bindable Beatmap { get; private set; } = new Bindable();
+
+ public override bool HandlePositionalInput => false;
+ public override bool HandleNonPositionalInput => false;
+ public override bool PropagatePositionalInputSubTree => false;
+ public override bool PropagateNonPositionalInputSubTree => false;
+
+ [BackgroundDependencyLoader]
+ private void load(AudioManager audio, TextureStore textures, RulesetStore rulesets)
+ {
+ Beatmap.Value = new DummyWorkingBeatmap(audio, textures);
+ Beatmap.Value.LoadTrack();
+
+ Ruleset.Value = rulesets.AvailableRulesets.First();
+ }
+
+ public SampleScreenContainer(Screen screen)
+ {
+ OsuScreenStack stack;
+ RelativeSizeAxes = Axes.Both;
+
+ OsuLogo logo;
+
+ Padding = new MarginPadding(5);
+
+ InternalChildren = new Drawable[]
+ {
+ new DependencyProvidingContainer
+ {
+ CachedDependencies = new (Type, object)[]
+ {
+ (typeof(OsuLogo), logo = new OsuLogo
+ {
+ RelativePositionAxes = Axes.Both,
+ Position = new Vector2(0.5f),
+ })
+ },
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
+ {
+ new ScalingContainer.ScalingDrawSizePreservingFillContainer(true)
+ {
+ Masking = true,
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
+ {
+ stack = new OsuScreenStack(),
+ logo
+ },
+ },
+ }
+ },
+ };
+
+ stack.Push(screen);
+ }
+ }
+ }
+}
diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs
new file mode 100644
index 0000000000..39da180f40
--- /dev/null
+++ b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs
@@ -0,0 +1,26 @@
+// 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.Game.Graphics;
+using osu.Game.Graphics.Containers;
+using osu.Game.Localisation;
+
+namespace osu.Game.Overlays.FirstRunSetup
+{
+ public class ScreenWelcome : FirstRunSetupScreen
+ {
+ public ScreenWelcome()
+ {
+ Content.Children = new Drawable[]
+ {
+ new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: 20))
+ {
+ Text = FirstRunSetupOverlayStrings.WelcomeDescription,
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y
+ },
+ };
+ }
+ }
+}
diff --git a/osu.Game/Overlays/FirstRunSetupOverlay.cs b/osu.Game/Overlays/FirstRunSetupOverlay.cs
new file mode 100644
index 0000000000..a12fec4507
--- /dev/null
+++ b/osu.Game/Overlays/FirstRunSetupOverlay.cs
@@ -0,0 +1,398 @@
+// 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.Diagnostics;
+using osu.Framework.Allocation;
+using osu.Framework.Bindables;
+using osu.Framework.Extensions.Color4Extensions;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Effects;
+using osu.Framework.Graphics.Shapes;
+using osu.Framework.Graphics.Sprites;
+using osu.Framework.Input.Events;
+using osu.Framework.Localisation;
+using osu.Framework.Screens;
+using osu.Game.Configuration;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Containers;
+using osu.Game.Graphics.Sprites;
+using osu.Game.Graphics.UserInterface;
+using osu.Game.Input.Bindings;
+using osu.Game.Localisation;
+using osu.Game.Overlays.FirstRunSetup;
+using osu.Game.Overlays.Notifications;
+using osu.Game.Screens;
+using osu.Game.Screens.Menu;
+using osu.Game.Screens.OnlinePlay.Match.Components;
+using osuTK;
+using osuTK.Graphics;
+
+namespace osu.Game.Overlays
+{
+ [Cached]
+ public class FirstRunSetupOverlay : OsuFocusedOverlayContainer
+ {
+ protected override bool StartHidden => true;
+
+ [Resolved]
+ private IPerformFromScreenRunner performer { get; set; } = null!;
+
+ [Resolved]
+ private INotificationOverlay notificationOverlay { get; set; } = null!;
+
+ [Resolved]
+ private OsuConfigManager config { get; set; } = null!;
+
+ private ScreenStack? stack;
+
+ public PurpleTriangleButton NextButton = null!;
+ public DangerousTriangleButton BackButton = null!;
+
+ [Cached]
+ private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
+
+ private readonly Bindable showFirstRunSetup = new Bindable();
+
+ private int? currentStepIndex;
+
+ private const float scale_when_hidden = 0.9f;
+
+ ///
+ /// The currently displayed screen, if any.
+ ///
+ public FirstRunSetupScreen? CurrentScreen => (FirstRunSetupScreen?)stack?.CurrentScreen;
+
+ private readonly FirstRunStep[] steps =
+ {
+ new FirstRunStep(typeof(ScreenWelcome), FirstRunSetupOverlayStrings.WelcomeTitle),
+ new FirstRunStep(typeof(ScreenUIScale), GraphicsSettingsStrings.UIScaling),
+ };
+
+ private Container stackContainer = null!;
+
+ private Bindable? overlayActivationMode;
+
+ public FirstRunSetupOverlay()
+ {
+ RelativeSizeAxes = Axes.Both;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ Anchor = Anchor.Centre;
+ Origin = Anchor.Centre;
+
+ RelativeSizeAxes = Axes.Both;
+ Size = new Vector2(0.95f);
+
+ EdgeEffect = new EdgeEffectParameters
+ {
+ Type = EdgeEffectType.Shadow,
+ Radius = 5,
+ Colour = Color4.Black.Opacity(0.2f),
+ };
+
+ Masking = true;
+ CornerRadius = 10;
+
+ Children = new Drawable[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = colourProvider.Background6,
+ },
+ new GridContainer
+ {
+ RelativeSizeAxes = Axes.Both,
+ RowDimensions = new[]
+ {
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension(),
+ new Dimension(GridSizeMode.AutoSize),
+ },
+ Content = new[]
+ {
+ new Drawable[]
+ {
+ new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Children = new Drawable[]
+ {
+ new Box
+ {
+ Colour = colourProvider.Background5,
+ RelativeSizeAxes = Axes.Both,
+ },
+ new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ Margin = new MarginPadding(10),
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Vertical,
+ Children = new Drawable[]
+ {
+ new OsuSpriteText
+ {
+ Text = FirstRunSetupOverlayStrings.FirstRunSetupTitle,
+ Font = OsuFont.Default.With(size: 32),
+ Colour = colourProvider.Content1,
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ },
+ new OsuTextFlowContainer
+ {
+ Text = FirstRunSetupOverlayStrings.FirstRunSetupDescription,
+ Colour = colourProvider.Content2,
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ AutoSizeAxes = Axes.Both,
+ },
+ }
+ },
+ }
+ },
+ },
+ new Drawable[]
+ {
+ stackContainer = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding(20),
+ },
+ },
+ new Drawable[]
+ {
+ new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Padding = new MarginPadding(20)
+ {
+ Top = 0 // provided by the stack container above.
+ },
+ Child = new GridContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ ColumnDimensions = new[]
+ {
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension(GridSizeMode.Absolute, 10),
+ new Dimension(),
+ },
+ RowDimensions = new[]
+ {
+ new Dimension(GridSizeMode.AutoSize),
+ },
+ Content = new[]
+ {
+ new[]
+ {
+ BackButton = new DangerousTriangleButton
+ {
+ Width = 200,
+ Text = CommonStrings.Back,
+ Action = showPreviousStep,
+ Enabled = { Value = false },
+ },
+ Empty(),
+ NextButton = new PurpleTriangleButton
+ {
+ RelativeSizeAxes = Axes.X,
+ Width = 1,
+ Text = FirstRunSetupOverlayStrings.GetStarted,
+ Action = showNextStep
+ }
+ },
+ }
+ },
+ }
+ }
+ }
+ },
+ };
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ config.BindWith(OsuSetting.ShowFirstRunSetup, showFirstRunSetup);
+
+ if (showFirstRunSetup.Value) Show();
+ }
+
+ public override bool OnPressed(KeyBindingPressEvent e)
+ {
+ if (!e.Repeat)
+ {
+ switch (e.Action)
+ {
+ case GlobalAction.Select:
+ NextButton.TriggerClick();
+ return true;
+
+ case GlobalAction.Back:
+ if (BackButton.Enabled.Value)
+ {
+ BackButton.TriggerClick();
+ return true;
+ }
+
+ // If back button is disabled, we are at the first step.
+ // The base call will handle dismissal of the overlay.
+ break;
+ }
+ }
+
+ return base.OnPressed(e);
+ }
+
+ public override void Show()
+ {
+ // if we are valid for display, only do so after reaching the main menu.
+ performer.PerformFromScreen(screen =>
+ {
+ MainMenu menu = (MainMenu)screen;
+
+ // Eventually I'd like to replace this with a better method that doesn't access the screen.
+ // Either this dialog would be converted to its own screen, or at very least be "hosted" by a screen pushed to the main menu.
+ // Alternatively, another method of disabling notifications could be added to `INotificationOverlay`.
+ if (menu != null)
+ {
+ overlayActivationMode = menu.OverlayActivationMode.GetBoundCopy();
+ overlayActivationMode.Value = OverlayActivation.UserTriggered;
+ }
+
+ base.Show();
+ }, new[] { typeof(MainMenu) });
+ }
+
+ protected override void PopIn()
+ {
+ base.PopIn();
+
+ this.ScaleTo(scale_when_hidden)
+ .ScaleTo(1, 400, Easing.OutElasticHalf);
+
+ this.FadeIn(400, Easing.OutQuint);
+
+ if (currentStepIndex == null)
+ showFirstStep();
+ }
+
+ protected override void PopOut()
+ {
+ if (overlayActivationMode != null)
+ {
+ // If this is non-null we are guaranteed to have come from the main menu.
+ overlayActivationMode.Value = OverlayActivation.All;
+ overlayActivationMode = null;
+ }
+
+ if (currentStepIndex != null)
+ {
+ notificationOverlay.Post(new SimpleNotification
+ {
+ Text = FirstRunSetupOverlayStrings.ClickToResumeFirstRunSetupAtAnyPoint,
+ Icon = FontAwesome.Solid.Redo,
+ Activated = () =>
+ {
+ Show();
+ return true;
+ },
+ });
+ }
+ else
+ {
+ stack?.FadeOut(100)
+ .Expire();
+ }
+
+ base.PopOut();
+
+ this.ScaleTo(0.96f, 400, Easing.OutQuint);
+ this.FadeOut(200, Easing.OutQuint);
+ }
+
+ private void showFirstStep()
+ {
+ Debug.Assert(currentStepIndex == null);
+
+ stackContainer.Child = stack = new ScreenStack
+ {
+ RelativeSizeAxes = Axes.Both,
+ };
+
+ currentStepIndex = -1;
+ showNextStep();
+ }
+
+ private void showPreviousStep()
+ {
+ if (currentStepIndex == 0)
+ return;
+
+ Debug.Assert(stack != null);
+
+ stack.CurrentScreen.Exit();
+ currentStepIndex--;
+
+ updateButtons();
+ }
+
+ private void showNextStep()
+ {
+ Debug.Assert(currentStepIndex != null);
+ Debug.Assert(stack != null);
+
+ currentStepIndex++;
+
+ if (currentStepIndex < steps.Length)
+ {
+ stack.Push((Screen)Activator.CreateInstance(steps[currentStepIndex.Value].ScreenType));
+ }
+ else
+ {
+ showFirstRunSetup.Value = false;
+ currentStepIndex = null;
+ Hide();
+ }
+
+ updateButtons();
+ }
+
+ private void updateButtons()
+ {
+ BackButton.Enabled.Value = currentStepIndex > 0;
+ NextButton.Enabled.Value = currentStepIndex != null;
+
+ if (currentStepIndex != null)
+ {
+ NextButton.Text = currentStepIndex + 1 < steps.Length
+ ? FirstRunSetupOverlayStrings.Next(steps[currentStepIndex.Value + 1].Description)
+ : CommonStrings.Finish;
+ }
+ }
+
+ private class FirstRunStep
+ {
+ public readonly Type ScreenType;
+ public readonly LocalisableString Description;
+
+ public FirstRunStep(Type screenType, LocalisableString description)
+ {
+ ScreenType = screenType;
+ Description = description;
+ }
+ }
+ }
+}
diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs
index 0424fe8bd9..8224cd5eb5 100644
--- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs
+++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs
@@ -53,6 +53,9 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps
case BeatmapSetType.Pending:
return user.PendingBeatmapsetCount;
+ case BeatmapSetType.Guest:
+ return user.GuestBeatmapsetCount;
+
default:
return 0;
}
diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs
index af6ab4aad1..6b93c24a78 100644
--- a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs
+++ b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs
@@ -21,6 +21,7 @@ namespace osu.Game.Overlays.Profile.Sections
new PaginatedBeatmapContainer(BeatmapSetType.Favourite, User, UsersStrings.ShowExtraBeatmapsFavouriteTitle),
new PaginatedBeatmapContainer(BeatmapSetType.Ranked, User, UsersStrings.ShowExtraBeatmapsRankedTitle),
new PaginatedBeatmapContainer(BeatmapSetType.Loved, User, UsersStrings.ShowExtraBeatmapsLovedTitle),
+ new PaginatedBeatmapContainer(BeatmapSetType.Guest, User, UsersStrings.ShowExtraBeatmapsGuestTitle),
new PaginatedBeatmapContainer(BeatmapSetType.Pending, User, UsersStrings.ShowExtraBeatmapsPendingTitle),
new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, User, UsersStrings.ShowExtraBeatmapsGraveyardTitle)
};
diff --git a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs
index 87e9f34833..ced3116728 100644
--- a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs
+++ b/osu.Game/Overlays/Settings/Sections/GeneralSection.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 osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
@@ -11,6 +12,9 @@ namespace osu.Game.Overlays.Settings.Sections
{
public class GeneralSection : SettingsSection
{
+ [Resolved(CanBeNull = true)]
+ private FirstRunSetupOverlay firstRunSetupOverlay { get; set; }
+
public override LocalisableString Header => GeneralSettingsStrings.GeneralSectionHeader;
public override Drawable CreateIcon() => new SpriteIcon
@@ -22,6 +26,11 @@ namespace osu.Game.Overlays.Settings.Sections
{
Children = new Drawable[]
{
+ new SettingsButton
+ {
+ Text = GeneralSettingsStrings.RunSetupWizard,
+ Action = () => firstRunSetupOverlay?.Show(),
+ },
new LanguageSettings(),
new UpdateSettings(),
};
diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs
index 98bc8d88be..c7fd248842 100644
--- a/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs
+++ b/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs
@@ -124,9 +124,9 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
base.LoadComplete();
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
- base.OnSuspending(next);
+ base.OnSuspending(e);
this.FadeOut(250);
}
diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs
index 10d6f0aef5..b7b797936e 100644
--- a/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs
+++ b/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs
@@ -124,20 +124,20 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
protected virtual bool PerformMigration() => game?.Migrate(destination.FullName) != false;
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
this.FadeOut().Delay(250).Then().FadeIn(250);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
// block until migration is finished
if (migrationTask?.IsCompleted == false)
return true;
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
}
}
diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/StableDirectorySelectScreen.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/StableDirectorySelectScreen.cs
index 4aea05fb14..86934ae514 100644
--- a/osu.Game/Overlays/Settings/Sections/Maintenance/StableDirectorySelectScreen.cs
+++ b/osu.Game/Overlays/Settings/Sections/Maintenance/StableDirectorySelectScreen.cs
@@ -30,10 +30,10 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
this.Exit();
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
taskCompletionSource.TrySetCanceled();
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
}
}
diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs
index 098090bf78..1c5668479f 100644
--- a/osu.Game/Overlays/Settings/SettingsItem.cs
+++ b/osu.Game/Overlays/Settings/SettingsItem.cs
@@ -100,10 +100,9 @@ namespace osu.Game.Overlays.Settings
public IEnumerable Keywords { get; set; }
- public bool MatchingFilter
- {
- set => Alpha = value ? 1 : 0;
- }
+ public override bool IsPresent => base.IsPresent && MatchingFilter;
+
+ public bool MatchingFilter { get; set; } = true;
public bool FilteringActive { get; set; }
diff --git a/osu.Game/Overlays/Settings/SettingsSection.cs b/osu.Game/Overlays/Settings/SettingsSection.cs
index 6645d20dbe..28c42a0e47 100644
--- a/osu.Game/Overlays/Settings/SettingsSection.cs
+++ b/osu.Game/Overlays/Settings/SettingsSection.cs
@@ -21,6 +21,8 @@ namespace osu.Game.Overlays.Settings
protected FillFlowContainer FlowContent;
protected override Container Content => FlowContent;
+ public override bool IsPresent => base.IsPresent && MatchingFilter;
+
private IBindable selectedSection;
private Box dim;
@@ -38,10 +40,7 @@ namespace osu.Game.Overlays.Settings
private const int header_size = 24;
private const int border_size = 4;
- public bool MatchingFilter
- {
- set => this.FadeTo(value ? 1 : 0);
- }
+ public bool MatchingFilter { get; set; } = true;
public bool FilteringActive { get; set; }
diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs
index d5b36713f3..a5a6f9bce7 100644
--- a/osu.Game/Overlays/SettingsPanel.cs
+++ b/osu.Game/Overlays/SettingsPanel.cs
@@ -163,6 +163,7 @@ namespace osu.Game.Overlays
Sidebar?.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint);
this.FadeTo(1, TRANSITION_LENGTH, Easing.OutQuint);
+ searchTextBox.TakeFocus();
searchTextBox.HoldFocus = true;
}
@@ -213,7 +214,6 @@ namespace osu.Game.Overlays
loading.Hide();
searchTextBox.Current.BindValueChanged(term => SectionsContainer.SearchTerm = term.NewValue, true);
- searchTextBox.TakeFocus();
loadSidebarButtons();
});
@@ -284,11 +284,7 @@ namespace osu.Game.Overlays
public string SearchTerm
{
get => SearchContainer.SearchTerm;
- set
- {
- SearchContainer.SearchTerm = value;
- InvalidateScrollPosition();
- }
+ set => SearchContainer.SearchTerm = value;
}
protected override FlowContainer CreateScrollContentContainer()
@@ -307,6 +303,8 @@ namespace osu.Game.Overlays
Colour = colourProvider.Background4,
RelativeSizeAxes = Axes.Both
};
+
+ SearchContainer.FilterCompleted += InvalidateScrollPosition;
}
protected override void UpdateAfterChildren()
diff --git a/osu.Game/Screens/BackgroundScreen.cs b/osu.Game/Screens/BackgroundScreen.cs
index a706934cce..6084ec4b01 100644
--- a/osu.Game/Screens/BackgroundScreen.cs
+++ b/osu.Game/Screens/BackgroundScreen.cs
@@ -48,7 +48,7 @@ namespace osu.Game.Screens
Scale = new Vector2(1 + x_movement_amount / DrawSize.X * 2);
}
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
if (animateOnEnter)
{
@@ -59,16 +59,16 @@ namespace osu.Game.Screens
this.MoveToX(0, TRANSITION_LENGTH, Easing.InOutQuart);
}
- base.OnEntering(last);
+ base.OnEntering(e);
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
this.MoveToX(-x_movement_amount, TRANSITION_LENGTH, Easing.InOutQuart);
- base.OnSuspending(next);
+ base.OnSuspending(e);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
if (IsLoaded)
{
@@ -76,14 +76,14 @@ namespace osu.Game.Screens
this.MoveToX(x_movement_amount, TRANSITION_LENGTH, Easing.OutExpo);
}
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
if (IsLoaded)
this.MoveToX(0, TRANSITION_LENGTH, Easing.OutExpo);
- base.OnResuming(last);
+ base.OnResuming(e);
}
}
}
diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBlack.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBlack.cs
index 9e2559cc56..d946fd41d9 100644
--- a/osu.Game/Screens/Backgrounds/BackgroundScreenBlack.cs
+++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBlack.cs
@@ -19,7 +19,7 @@ namespace osu.Game.Screens.Backgrounds
};
}
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
Show();
}
diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs
index 30c57733ed..3fde033587 100644
--- a/osu.Game/Screens/Edit/Editor.cs
+++ b/osu.Game/Screens/Edit/Editor.cs
@@ -560,16 +560,16 @@ namespace osu.Game.Screens.Edit
{
}
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
dimBackground();
resetTrack(true);
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
- base.OnResuming(last);
+ base.OnResuming(e);
dimBackground();
}
@@ -585,7 +585,7 @@ namespace osu.Game.Screens.Edit
});
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
if (!ExitConfirmed)
{
@@ -613,12 +613,12 @@ namespace osu.Game.Screens.Edit
refetchBeatmap();
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
- base.OnSuspending(next);
+ base.OnSuspending(e);
clock.Stop();
refetchBeatmap();
}
diff --git a/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs b/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs
index d9e19df350..f7e450b0e2 100644
--- a/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs
+++ b/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs
@@ -44,9 +44,9 @@ namespace osu.Game.Screens.Edit.GameplayTest
protected override bool CheckModsAllowFailure() => false; // never fail.
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
// finish alpha transforms on entering to avoid gameplay starting in a half-hidden state.
// the finish calls are purposefully not propagated to children to avoid messing up their state.
@@ -54,13 +54,13 @@ namespace osu.Game.Screens.Edit.GameplayTest
GameplayClockContainer.FinishTransforms(false, nameof(Alpha));
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
musicController.Stop();
editorState.Time = GameplayClockContainer.CurrentTime;
editor.RestoreState(editorState);
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
}
}
diff --git a/osu.Game/Screens/Edit/GameplayTest/EditorPlayerLoader.cs b/osu.Game/Screens/Edit/GameplayTest/EditorPlayerLoader.cs
index addc79ba61..c16bb8677c 100644
--- a/osu.Game/Screens/Edit/GameplayTest/EditorPlayerLoader.cs
+++ b/osu.Game/Screens/Edit/GameplayTest/EditorPlayerLoader.cs
@@ -19,9 +19,9 @@ namespace osu.Game.Screens.Edit.GameplayTest
{
}
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
MetadataInfo.FinishTransforms(true);
}
diff --git a/osu.Game/Screens/Import/FileImportScreen.cs b/osu.Game/Screens/Import/FileImportScreen.cs
index 09870e0bab..32ce54aa29 100644
--- a/osu.Game/Screens/Import/FileImportScreen.cs
+++ b/osu.Game/Screens/Import/FileImportScreen.cs
@@ -118,20 +118,20 @@ namespace osu.Game.Screens.Import
fileSelector.CurrentPath.BindValueChanged(directoryChanged);
}
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
contentContainer.ScaleTo(0.95f).ScaleTo(1, duration, Easing.OutQuint);
this.FadeInFromZero(duration);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
contentContainer.ScaleTo(0.95f, duration, Easing.OutQuint);
this.FadeOut(duration, Easing.OutQuint);
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
private void directoryChanged(ValueChangedEvent _)
diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs
index a72ba89dfa..52e83c9e98 100644
--- a/osu.Game/Screens/Loader.cs
+++ b/osu.Game/Screens/Loader.cs
@@ -69,9 +69,9 @@ namespace osu.Game.Screens
private EFToRealmMigrator realmMigrator;
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
LoadComponentAsync(precompiler = CreateShaderPrecompiler(), AddInternal);
diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs
index 2d18dce6da..885f4903b0 100644
--- a/osu.Game/Screens/Menu/ButtonSystem.cs
+++ b/osu.Game/Screens/Menu/ButtonSystem.cs
@@ -87,6 +87,8 @@ namespace osu.Game.Screens.Menu
private readonly LogoTrackingContainer logoTrackingContainer;
+ public bool ReturnToTopOnIdle { get; set; } = true;
+
public ButtonSystem()
{
RelativeSizeAxes = Axes.Both;
@@ -100,7 +102,8 @@ namespace osu.Game.Screens.Menu
buttonArea.AddRange(new Drawable[]
{
new MainMenuButton(ButtonSystemStrings.Settings, string.Empty, FontAwesome.Solid.Cog, new Color4(85, 85, 85, 255), () => OnSettings?.Invoke(), -WEDGE_WIDTH, Key.O),
- backButton = new MainMenuButton(ButtonSystemStrings.Back, @"button-back-select", OsuIcon.LeftCircle, new Color4(51, 58, 94, 255), () => State = ButtonSystemState.TopLevel, -WEDGE_WIDTH)
+ backButton = new MainMenuButton(ButtonSystemStrings.Back, @"button-back-select", OsuIcon.LeftCircle, new Color4(51, 58, 94, 255), () => State = ButtonSystemState.TopLevel,
+ -WEDGE_WIDTH)
{
VisibleState = ButtonSystemState.Play,
},
@@ -127,9 +130,11 @@ namespace osu.Game.Screens.Menu
buttonsPlay.Add(new MainMenuButton(ButtonSystemStrings.Playlists, @"button-generic-select", OsuIcon.Charts, new Color4(94, 63, 186, 255), onPlaylists, 0, Key.L));
buttonsPlay.ForEach(b => b.VisibleState = ButtonSystemState.Play);
- buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Play, @"button-play-select", OsuIcon.Logo, new Color4(102, 68, 204, 255), () => State = ButtonSystemState.Play, WEDGE_WIDTH, Key.P));
+ buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Play, @"button-play-select", OsuIcon.Logo, new Color4(102, 68, 204, 255), () => State = ButtonSystemState.Play, WEDGE_WIDTH,
+ Key.P));
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Edit, @"button-edit-select", OsuIcon.EditCircle, new Color4(238, 170, 0, 255), () => OnEdit?.Invoke(), 0, Key.E));
- buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Browse, @"button-direct-select", OsuIcon.ChevronDownCircle, new Color4(165, 204, 0, 255), () => OnBeatmapListing?.Invoke(), 0, Key.D));
+ buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Browse, @"button-direct-select", OsuIcon.ChevronDownCircle, new Color4(165, 204, 0, 255), () => OnBeatmapListing?.Invoke(), 0,
+ Key.D));
if (host.CanExit)
buttonsTopLevel.Add(new MainMenuButton(ButtonSystemStrings.Exit, string.Empty, OsuIcon.CrossCircle, new Color4(238, 51, 153, 255), () => OnExit?.Invoke(), 0, Key.Q));
@@ -177,6 +182,9 @@ namespace osu.Game.Screens.Menu
private void updateIdleState(bool isIdle)
{
+ if (!ReturnToTopOnIdle)
+ return;
+
if (isIdle && State != ButtonSystemState.Exit && State != ButtonSystemState.EnteringMode)
State = ButtonSystemState.Initial;
}
diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs
index 22151db0dd..24412cd85e 100644
--- a/osu.Game/Screens/Menu/Disclaimer.cs
+++ b/osu.Game/Screens/Menu/Disclaimer.cs
@@ -171,9 +171,9 @@ namespace osu.Game.Screens.Menu
((IBindable)currentUser).BindTo(api.LocalUser);
}
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
icon.RotateTo(10);
icon.FadeOut();
diff --git a/osu.Game/Screens/Menu/IntroCircles.cs b/osu.Game/Screens/Menu/IntroCircles.cs
index 2792d05f75..00e2de62f0 100644
--- a/osu.Game/Screens/Menu/IntroCircles.cs
+++ b/osu.Game/Screens/Menu/IntroCircles.cs
@@ -57,10 +57,10 @@ namespace osu.Game.Screens.Menu
}
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
this.FadeOut(300);
- base.OnSuspending(next);
+ base.OnSuspending(e);
}
}
}
diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs
index 5575d3681f..d4072d6202 100644
--- a/osu.Game/Screens/Menu/IntroScreen.cs
+++ b/osu.Game/Screens/Menu/IntroScreen.cs
@@ -164,9 +164,9 @@ namespace osu.Game.Screens.Menu
}
}
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
ensureEventuallyArrivingAtMenu();
}
@@ -194,7 +194,7 @@ namespace osu.Game.Screens.Menu
}, 5000);
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
this.FadeIn(300);
@@ -237,12 +237,12 @@ namespace osu.Game.Screens.Menu
//don't want to fade out completely else we will stop running updates.
Game.FadeTo(0.01f, fadeOutTime).OnComplete(_ => this.Exit());
- base.OnResuming(last);
+ base.OnResuming(e);
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
- base.OnSuspending(next);
+ base.OnSuspending(e);
initialBeatmap = null;
}
diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs
index b6b6bf2ad7..ba8314f103 100644
--- a/osu.Game/Screens/Menu/IntroTriangles.cs
+++ b/osu.Game/Screens/Menu/IntroTriangles.cs
@@ -89,9 +89,9 @@ namespace osu.Game.Screens.Menu
}
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
- base.OnSuspending(next);
+ base.OnSuspending(e);
// ensure the background is shown, even if the TriangleIntroSequence failed to do so.
background.ApplyToBackground(b => b.Show());
@@ -100,9 +100,9 @@ namespace osu.Game.Screens.Menu
intro.Expire();
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
- base.OnResuming(last);
+ base.OnResuming(e);
background.FadeOut(100);
}
diff --git a/osu.Game/Screens/Menu/IntroWelcome.cs b/osu.Game/Screens/Menu/IntroWelcome.cs
index 27eaa7eb3a..9a6c949cad 100644
--- a/osu.Game/Screens/Menu/IntroWelcome.cs
+++ b/osu.Game/Screens/Menu/IntroWelcome.cs
@@ -106,9 +106,9 @@ namespace osu.Game.Screens.Menu
}
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
- base.OnResuming(last);
+ base.OnResuming(e);
background.FadeOut(100);
}
diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs
index 08df06816b..4401ee93ec 100644
--- a/osu.Game/Screens/Menu/MainMenu.cs
+++ b/osu.Game/Screens/Menu/MainMenu.cs
@@ -35,7 +35,7 @@ namespace osu.Game.Screens.Menu
public const float FADE_OUT_DURATION = 400;
- public override bool HideOverlaysOnEnter => buttons == null || buttons.State == ButtonSystemState.Initial;
+ public override bool HideOverlaysOnEnter => Buttons == null || Buttons.State == ButtonSystemState.Initial;
public override bool AllowBackButton => false;
@@ -45,7 +45,7 @@ namespace osu.Game.Screens.Menu
private MenuSideFlashes sideFlashes;
- private ButtonSystem buttons;
+ protected ButtonSystem Buttons;
[Resolved]
private GameHost host { get; set; }
@@ -101,7 +101,7 @@ namespace osu.Game.Screens.Menu
ParallaxAmount = 0.01f,
Children = new Drawable[]
{
- buttons = new ButtonSystem
+ Buttons = new ButtonSystem
{
OnEdit = delegate
{
@@ -125,7 +125,7 @@ namespace osu.Game.Screens.Menu
exitConfirmOverlay?.CreateProxy() ?? Empty()
});
- buttons.StateChanged += state =>
+ Buttons.StateChanged += state =>
{
switch (state)
{
@@ -140,8 +140,8 @@ namespace osu.Game.Screens.Menu
}
};
- buttons.OnSettings = () => settings?.ToggleVisibility();
- buttons.OnBeatmapListing = () => beatmapListing?.ToggleVisibility();
+ Buttons.OnSettings = () => settings?.ToggleVisibility();
+ Buttons.OnBeatmapListing = () => beatmapListing?.ToggleVisibility();
LoadComponentAsync(background = new BackgroundScreenDefault());
preloadSongSelect();
@@ -176,12 +176,12 @@ namespace osu.Game.Screens.Menu
[Resolved]
private Storage storage { get; set; }
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
- buttons.FadeInFromZero(500);
+ base.OnEntering(e);
+ Buttons.FadeInFromZero(500);
- if (last is IntroScreen && musicController.TrackLoaded)
+ if (e.Last is IntroScreen && musicController.TrackLoaded)
{
var track = musicController.CurrentTrack;
@@ -203,14 +203,14 @@ namespace osu.Game.Screens.Menu
{
base.LogoArriving(logo, resuming);
- buttons.SetOsuLogo(logo);
+ Buttons.SetOsuLogo(logo);
logo.FadeColour(Color4.White, 100, Easing.OutQuint);
logo.FadeIn(100, Easing.OutQuint);
if (resuming)
{
- buttons.State = ButtonSystemState.TopLevel;
+ Buttons.State = ButtonSystemState.TopLevel;
this.FadeIn(FADE_IN_DURATION, Easing.OutQuint);
buttonsContainer.MoveTo(new Vector2(0, 0), FADE_IN_DURATION, Easing.OutQuint);
@@ -245,15 +245,15 @@ namespace osu.Game.Screens.Menu
var seq = logo.FadeOut(300, Easing.InSine)
.ScaleTo(0.2f, 300, Easing.InSine);
- seq.OnComplete(_ => buttons.SetOsuLogo(null));
- seq.OnAbort(_ => buttons.SetOsuLogo(null));
+ seq.OnComplete(_ => Buttons.SetOsuLogo(null));
+ seq.OnAbort(_ => Buttons.SetOsuLogo(null));
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
- base.OnSuspending(next);
+ base.OnSuspending(e);
- buttons.State = ButtonSystemState.EnteringMode;
+ Buttons.State = ButtonSystemState.EnteringMode;
this.FadeOut(FADE_OUT_DURATION, Easing.InSine);
buttonsContainer.MoveTo(new Vector2(-800, 0), FADE_OUT_DURATION, Easing.InSine);
@@ -261,9 +261,9 @@ namespace osu.Game.Screens.Menu
sideFlashes.FadeOut(64, Easing.OutQuint);
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
- base.OnResuming(last);
+ base.OnResuming(e);
ApplyToBackground(b => (b as BackgroundScreenDefault)?.Next());
@@ -273,7 +273,7 @@ namespace osu.Game.Screens.Menu
musicController.EnsurePlayingSomething();
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
if (!exitConfirmed && dialogOverlay != null)
{
@@ -285,13 +285,13 @@ namespace osu.Game.Screens.Menu
return true;
}
- buttons.State = ButtonSystemState.Exit;
+ Buttons.State = ButtonSystemState.Exit;
OverlayActivationMode.Value = OverlayActivation.Disabled;
songTicker.Hide();
this.FadeOut(3000);
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
public void PresentBeatmap(WorkingBeatmap beatmap, RulesetInfo ruleset)
diff --git a/osu.Game/Screens/OnlinePlay/Components/OnlinePlayBackgroundScreen.cs b/osu.Game/Screens/OnlinePlay/Components/OnlinePlayBackgroundScreen.cs
index 8906bebf0e..9e964de31e 100644
--- a/osu.Game/Screens/OnlinePlay/Components/OnlinePlayBackgroundScreen.cs
+++ b/osu.Game/Screens/OnlinePlay/Components/OnlinePlayBackgroundScreen.cs
@@ -91,15 +91,15 @@ namespace osu.Game.Screens.OnlinePlay.Components
AddInternal(background = newBackground);
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
- base.OnSuspending(next);
+ base.OnSuspending(e);
this.MoveToX(0, TRANSITION_LENGTH);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
- bool result = base.OnExiting(next);
+ bool result = base.OnExiting(e);
this.MoveToX(0);
return result;
}
diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeBackgroundScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeBackgroundScreen.cs
index 926c35c5da..52a902f5da 100644
--- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeBackgroundScreen.cs
+++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeBackgroundScreen.cs
@@ -33,7 +33,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
playlist.Clear();
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
// This screen never exits.
return true;
diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs
index a2d3b7f4fc..ec55ae79ce 100644
--- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs
+++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs
@@ -238,15 +238,15 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
#endregion
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
onReturning();
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
- base.OnResuming(last);
+ base.OnResuming(e);
Debug.Assert(selectionLease != null);
@@ -261,16 +261,16 @@ namespace osu.Game.Screens.OnlinePlay.Lounge
onReturning();
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
onLeaving();
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
onLeaving();
- base.OnSuspending(next);
+ base.OnSuspending(e);
}
protected override void OnFocus(FocusEvent e)
diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs
index a382f65d84..cc1f842f8c 100644
--- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs
+++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs
@@ -290,35 +290,35 @@ namespace osu.Game.Screens.OnlinePlay.Match
protected void ShowUserModSelect() => userModsSelectOverlay.Show();
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
beginHandlingTrack();
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
endHandlingTrack();
- base.OnSuspending(next);
+ base.OnSuspending(e);
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
- base.OnResuming(last);
+ base.OnResuming(e);
updateWorkingBeatmap();
beginHandlingTrack();
Scheduler.AddOnce(UpdateMods);
Scheduler.AddOnce(updateRuleset);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
RoomManager?.PartRoom();
Mods.Value = Array.Empty();
endHandlingTrack();
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
protected void StartPlay()
diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs
index c78756771a..53d081a108 100644
--- a/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs
+++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs
@@ -47,16 +47,16 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
}
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
- base.OnResuming(last);
+ base.OnResuming(e);
if (client.Room == null)
return;
Debug.Assert(client.LocalUser != null);
- if (!(last is MultiplayerPlayerLoader playerLoader))
+ if (!(e.Last is MultiplayerPlayerLoader playerLoader))
return;
// Nothing needs to be done if already in the idle state (e.g. via load being aborted by the server).
diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs
index 5cdec52bc2..a05f248d3a 100644
--- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs
+++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs
@@ -25,13 +25,13 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
[Resolved]
private MultiplayerClient client { get; set; }
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
- base.OnResuming(last);
+ base.OnResuming(e);
// Upon having left a room, we don't know whether we were the only participant, and whether the room is now closed as a result of leaving it.
// To work around this, temporarily remove the room and trigger an immediate listing poll.
- if (last is MultiplayerMatchSubScreen match)
+ if (e.Last is MultiplayerMatchSubScreen match)
{
RoomManager.RemoveRoom(match.Room);
ListingPollingComponent.PollImmediately();
diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs
index 0dbf73fc5b..769873f74c 100644
--- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs
+++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs
@@ -242,14 +242,14 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
private bool exitConfirmed;
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
// the room may not be left immediately after a disconnection due to async flow,
// so checking the IsConnected status is also required.
if (client.Room == null || !client.IsConnected.Value)
{
// room has not been created yet; exit immediately.
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
if (!exitConfirmed && dialogOverlay != null)
@@ -268,7 +268,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
return true;
}
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
private ModSettingChangeTracker modSettingChangeTracker;
diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayerLoader.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayerLoader.cs
index 9964452f61..236df7917c 100644
--- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayerLoader.cs
+++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayerLoader.cs
@@ -28,10 +28,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
// The server is forcefully starting gameplay.
|| multiplayerClient.LocalUser?.State == MultiplayerUserState.Playing;
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
- base.OnSuspending(next);
- player = (Player)next;
+ base.OnSuspending(e);
+ player = (Player)e.Next;
}
}
}
diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs
index c56d04d5ac..ff4225e155 100644
--- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs
+++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs
@@ -110,7 +110,7 @@ namespace osu.Game.Screens.OnlinePlay
}
}
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
this.FadeIn();
waves.Show();
@@ -118,35 +118,35 @@ namespace osu.Game.Screens.OnlinePlay
Mods.SetDefault();
if (loungeSubScreen.IsCurrentScreen())
- loungeSubScreen.OnEntering(last);
+ loungeSubScreen.OnEntering(e);
else
loungeSubScreen.MakeCurrent();
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
this.FadeIn(250);
this.ScaleTo(1, 250, Easing.OutSine);
Debug.Assert(screenStack.CurrentScreen != null);
- screenStack.CurrentScreen.OnResuming(last);
+ screenStack.CurrentScreen.OnResuming(e);
- base.OnResuming(last);
+ base.OnResuming(e);
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
this.ScaleTo(1.1f, 250, Easing.InSine);
this.FadeOut(250);
Debug.Assert(screenStack.CurrentScreen != null);
- screenStack.CurrentScreen.OnSuspending(next);
+ screenStack.CurrentScreen.OnSuspending(e);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
var subScreen = screenStack.CurrentScreen as Drawable;
- if (subScreen?.IsLoaded == true && screenStack.CurrentScreen.OnExiting(next))
+ if (subScreen?.IsLoaded == true && screenStack.CurrentScreen.OnExiting(e))
return true;
RoomManager.PartRoom();
@@ -155,7 +155,7 @@ namespace osu.Game.Screens.OnlinePlay
this.Delay(WaveContainer.DISAPPEAR_DURATION).FadeOut();
- base.OnExiting(next);
+ base.OnExiting(e);
return false;
}
diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs b/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs
index 7b64784316..6a559dbb2c 100644
--- a/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs
+++ b/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs
@@ -141,7 +141,7 @@ namespace osu.Game.Screens.OnlinePlay
return base.OnBackButton();
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
if (!itemSelected)
{
@@ -150,7 +150,7 @@ namespace osu.Game.Screens.OnlinePlay
Mods.Value = initialMods;
}
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
protected override ModSelectOverlay CreateModSelectOverlay() => new UserModSelectOverlay
diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreen.cs
index 3411c4afb1..07e0f60011 100644
--- a/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreen.cs
+++ b/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreen.cs
@@ -27,28 +27,28 @@ namespace osu.Game.Screens.OnlinePlay
public const double DISAPPEAR_DURATION = 500;
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
this.FadeInFromZero(APPEAR_DURATION, Easing.OutQuint);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
- base.OnExiting(next);
+ base.OnExiting(e);
this.FadeOut(DISAPPEAR_DURATION, Easing.OutQuint);
return false;
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
- base.OnResuming(last);
+ base.OnResuming(e);
this.FadeIn(APPEAR_DURATION, Easing.OutQuint);
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
- base.OnSuspending(next);
+ base.OnSuspending(e);
this.FadeOut(DISAPPEAR_DURATION, Easing.OutQuint);
}
diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs
index 5a7762a3d8..5cba8676c5 100644
--- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs
+++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs
@@ -45,9 +45,9 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
throw new InvalidOperationException("Current Mods do not match PlaylistItem's RequiredMods");
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
- if (base.OnExiting(next))
+ if (base.OnExiting(e))
return true;
Exited?.Invoke();
diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs
index ed4901e1fa..77db1285bd 100644
--- a/osu.Game/Screens/OsuScreen.cs
+++ b/osu.Game/Screens/OsuScreen.cs
@@ -48,7 +48,7 @@ namespace osu.Game.Screens
///
protected virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All;
- protected readonly Bindable OverlayActivationMode;
+ public readonly Bindable OverlayActivationMode;
IBindable IOsuScreen.OverlayActivationMode => OverlayActivationMode;
@@ -171,7 +171,7 @@ namespace osu.Game.Screens
background.ApplyToBackground(action);
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
if (PlayResumeSound)
sampleExit?.Play();
@@ -183,19 +183,19 @@ namespace osu.Game.Screens
if (trackAdjustmentStateAtSuspend != null)
musicController.AllowTrackAdjustments = trackAdjustmentStateAtSuspend.Value;
- base.OnResuming(last);
+ base.OnResuming(e);
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
- base.OnSuspending(next);
+ base.OnSuspending(e);
trackAdjustmentStateAtSuspend = musicController.AllowTrackAdjustments;
onSuspendingLogo();
}
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
applyArrivingDefaults(false);
@@ -210,15 +210,15 @@ namespace osu.Game.Screens
}
background = backgroundStack?.CurrentScreen as BackgroundScreen;
- base.OnEntering(last);
+ base.OnEntering(e);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
if (ValidForResume && logo != null)
onExitingLogo();
- if (base.OnExiting(next))
+ if (base.OnExiting(e))
return true;
if (ownedBackground != null && backgroundStack?.CurrentScreen == ownedBackground)
diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs
index f99b07c313..2d5a67758a 100644
--- a/osu.Game/Screens/Play/Player.cs
+++ b/osu.Game/Screens/Play/Player.cs
@@ -917,9 +917,9 @@ namespace osu.Game.Screens.Play
#region Screen Logic
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
if (!LoadedBeatmapSuccessfully)
return;
@@ -985,15 +985,15 @@ namespace osu.Game.Screens.Play
GameplayClockContainer.Reset(true);
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
screenSuspension?.RemoveAndDisposeImmediately();
fadeOut();
- base.OnSuspending(next);
+ base.OnSuspending(e);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
screenSuspension?.RemoveAndDisposeImmediately();
failAnimationLayer?.RemoveFilters();
@@ -1024,7 +1024,7 @@ namespace osu.Game.Screens.Play
musicController.ResetTrackAdjustments();
fadeOut();
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
///
diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs
index f7dae6eaa9..bdfa822cb0 100644
--- a/osu.Game/Screens/Play/PlayerLoader.cs
+++ b/osu.Game/Screens/Play/PlayerLoader.cs
@@ -214,9 +214,9 @@ namespace osu.Game.Screens.Play
#region Screen handling
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
ApplyToBackground(b =>
{
@@ -240,9 +240,9 @@ namespace osu.Game.Screens.Play
showBatteryWarningIfNeeded();
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
- base.OnResuming(last);
+ base.OnResuming(e);
Debug.Assert(CurrentPlayer != null);
@@ -258,9 +258,9 @@ namespace osu.Game.Screens.Play
contentIn();
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
- base.OnSuspending(next);
+ base.OnSuspending(e);
BackgroundBrightnessReduction = false;
@@ -272,7 +272,7 @@ namespace osu.Game.Screens.Play
highPassFilter.CutoffTo(0);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
cancelLoad();
ContentOut();
@@ -288,7 +288,7 @@ namespace osu.Game.Screens.Play
BackgroundBrightnessReduction = false;
Beatmap.Value.Track.RemoveAdjustment(AdjustableProperty.Volume, volumeAdjustment);
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
protected override void LogoArriving(OsuLogo logo, bool resuming)
diff --git a/osu.Game/Screens/Play/ReplayPlayerLoader.cs b/osu.Game/Screens/Play/ReplayPlayerLoader.cs
index 9eff4cb8fc..e78f700af2 100644
--- a/osu.Game/Screens/Play/ReplayPlayerLoader.cs
+++ b/osu.Game/Screens/Play/ReplayPlayerLoader.cs
@@ -20,13 +20,13 @@ namespace osu.Game.Screens.Play
Score = score.ScoreInfo;
}
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
// these will be reverted thanks to PlayerLoader's lease.
Mods.Value = Score.Mods;
Ruleset.Value = Score.Ruleset;
- base.OnEntering(last);
+ base.OnEntering(e);
}
}
}
diff --git a/osu.Game/Screens/Play/SoloSpectator.cs b/osu.Game/Screens/Play/SoloSpectator.cs
index a0b07fcbd9..202527f308 100644
--- a/osu.Game/Screens/Play/SoloSpectator.cs
+++ b/osu.Game/Screens/Play/SoloSpectator.cs
@@ -249,10 +249,10 @@ namespace osu.Game.Screens.Play
beatmapDownloader.Download(beatmapSet);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
previewTrackManager.StopAnyPlaying(this);
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
}
}
diff --git a/osu.Game/Screens/Play/SoloSpectatorPlayer.cs b/osu.Game/Screens/Play/SoloSpectatorPlayer.cs
index 969a5bf2b4..5b601083c2 100644
--- a/osu.Game/Screens/Play/SoloSpectatorPlayer.cs
+++ b/osu.Game/Screens/Play/SoloSpectatorPlayer.cs
@@ -24,11 +24,11 @@ namespace osu.Game.Screens.Play
SpectatorClient.OnUserBeganPlaying += userBeganPlaying;
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
SpectatorClient.OnUserBeganPlaying -= userBeganPlaying;
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
private void userBeganPlaying(int userId, SpectatorState state)
diff --git a/osu.Game/Screens/Play/SpectatorPlayer.cs b/osu.Game/Screens/Play/SpectatorPlayer.cs
index c0682952c3..09bec9b89f 100644
--- a/osu.Game/Screens/Play/SpectatorPlayer.cs
+++ b/osu.Game/Screens/Play/SpectatorPlayer.cs
@@ -91,11 +91,11 @@ namespace osu.Game.Screens.Play
DrawableRuleset?.SetReplayScore(score);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
SpectatorClient.OnNewFrames -= userSentFrames;
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
protected override void Dispose(bool isDisposing)
diff --git a/osu.Game/Screens/Play/SpectatorPlayerLoader.cs b/osu.Game/Screens/Play/SpectatorPlayerLoader.cs
index 10cc36c9a9..9ca5475ee4 100644
--- a/osu.Game/Screens/Play/SpectatorPlayerLoader.cs
+++ b/osu.Game/Screens/Play/SpectatorPlayerLoader.cs
@@ -20,13 +20,13 @@ namespace osu.Game.Screens.Play
Score = score.ScoreInfo;
}
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
// these will be reverted thanks to PlayerLoader's lease.
Mods.Value = Score.Mods;
Ruleset.Value = Score.Ruleset;
- base.OnEntering(last);
+ base.OnEntering(e);
}
}
}
diff --git a/osu.Game/Screens/Play/SubmittingPlayer.cs b/osu.Game/Screens/Play/SubmittingPlayer.cs
index b1f2bccddf..b62dc1e5a6 100644
--- a/osu.Game/Screens/Play/SubmittingPlayer.cs
+++ b/osu.Game/Screens/Play/SubmittingPlayer.cs
@@ -115,9 +115,9 @@ namespace osu.Game.Screens.Play
await submitScore(score).ConfigureAwait(false);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
- bool exiting = base.OnExiting(next);
+ bool exiting = base.OnExiting(e);
if (LoadedBeatmapSuccessfully)
submitScore(Score.DeepClone());
diff --git a/osu.Game/Screens/Ranking/ResultsScreen.cs b/osu.Game/Screens/Ranking/ResultsScreen.cs
index cb842ce4a0..98514cd846 100644
--- a/osu.Game/Screens/Ranking/ResultsScreen.cs
+++ b/osu.Game/Screens/Ranking/ResultsScreen.cs
@@ -231,9 +231,9 @@ namespace osu.Game.Screens.Ranking
lastFetchCompleted = true;
});
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
ApplyToBackground(b =>
{
@@ -244,9 +244,9 @@ namespace osu.Game.Screens.Ranking
bottomPanel.FadeTo(1, 250);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
- if (base.OnExiting(next))
+ if (base.OnExiting(e))
return true;
this.FadeOut(100);
diff --git a/osu.Game/Screens/ScreenWhiteBox.cs b/osu.Game/Screens/ScreenWhiteBox.cs
index 8b38b67f5c..3a9e7b8f18 100644
--- a/osu.Game/Screens/ScreenWhiteBox.cs
+++ b/osu.Game/Screens/ScreenWhiteBox.cs
@@ -28,25 +28,25 @@ namespace osu.Game.Screens
protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg2");
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
message.TextContainer.MoveTo(new Vector2(DrawSize.X / 16, 0), transition_time, Easing.OutExpo);
this.FadeOut(transition_time, Easing.OutExpo);
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
- base.OnSuspending(next);
+ base.OnSuspending(e);
message.TextContainer.MoveTo(new Vector2(-(DrawSize.X / 16), 0), transition_time, Easing.OutExpo);
this.FadeOut(transition_time, Easing.OutExpo);
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
- base.OnResuming(last);
+ base.OnResuming(e);
message.TextContainer.MoveTo(Vector2.Zero, transition_time, Easing.OutExpo);
this.FadeIn(transition_time, Easing.OutExpo);
diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs
index 4a991ffc66..ec8b2e029a 100644
--- a/osu.Game/Screens/Select/PlaySongSelect.cs
+++ b/osu.Game/Screens/Select/PlaySongSelect.cs
@@ -109,9 +109,9 @@ namespace osu.Game.Screens.Select
}
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
- base.OnResuming(last);
+ base.OnResuming(e);
if (playerLoader != null)
{
diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs
index dc505063d1..928978cd08 100644
--- a/osu.Game/Screens/Select/SongSelect.cs
+++ b/osu.Game/Screens/Select/SongSelect.cs
@@ -543,9 +543,9 @@ namespace osu.Game.Screens.Select
}
}
- public override void OnEntering(IScreen last)
+ public override void OnEntering(ScreenTransitionEvent e)
{
- base.OnEntering(last);
+ base.OnEntering(e);
this.FadeInFromZero(250);
FilterControl.Activate();
@@ -591,9 +591,9 @@ namespace osu.Game.Screens.Select
logo.FadeOut(logo_transition / 2, Easing.Out);
}
- public override void OnResuming(IScreen last)
+ public override void OnResuming(ScreenTransitionEvent e)
{
- base.OnResuming(last);
+ base.OnResuming(e);
// required due to https://github.com/ppy/osu-framework/issues/3218
ModSelect.SelectedMods.Disabled = false;
@@ -622,7 +622,7 @@ namespace osu.Game.Screens.Select
FilterControl.Activate();
}
- public override void OnSuspending(IScreen next)
+ public override void OnSuspending(ScreenTransitionEvent e)
{
// Handle the case where FinaliseSelection is never called (ie. when a screen is pushed externally).
// Without this, it's possible for a transfer to happen while we are not the current screen.
@@ -640,12 +640,12 @@ namespace osu.Game.Screens.Select
this.FadeOut(250);
FilterControl.Deactivate();
- base.OnSuspending(next);
+ base.OnSuspending(e);
}
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
- if (base.OnExiting(next))
+ if (base.OnExiting(e))
return true;
beatmapInfoWedge.Hide();
diff --git a/osu.Game/Tests/Visual/EditorTestScene.cs b/osu.Game/Tests/Visual/EditorTestScene.cs
index ca12bc73fe..46f31ae53b 100644
--- a/osu.Game/Tests/Visual/EditorTestScene.cs
+++ b/osu.Game/Tests/Visual/EditorTestScene.cs
@@ -118,7 +118,7 @@ namespace osu.Game.Tests.Visual
public new bool HasUnsavedChanges => base.HasUnsavedChanges;
- public override bool OnExiting(IScreen next)
+ public override bool OnExiting(ScreenExitEvent e)
{
// For testing purposes allow the screen to exit without saving on second attempt.
if (!ExitConfirmed && dialogOverlay?.CurrentDialog is PromptForSaveDialog saveDialog)
@@ -127,7 +127,7 @@ namespace osu.Game.Tests.Visual
return true;
}
- return base.OnExiting(next);
+ return base.OnExiting(e);
}
public TestEditor(EditorLoader loader = null)
diff --git a/osu.Game/Tests/Visual/OsuGameTestScene.cs b/osu.Game/Tests/Visual/OsuGameTestScene.cs
index 34d7723fa3..7a6f8c8cfb 100644
--- a/osu.Game/Tests/Visual/OsuGameTestScene.cs
+++ b/osu.Game/Tests/Visual/OsuGameTestScene.cs
@@ -156,6 +156,7 @@ namespace osu.Game.Tests.Visual
base.LoadComplete();
LocalConfig.SetValue(OsuSetting.IntroSequence, IntroSequence.Circles);
+ LocalConfig.SetValue(OsuSetting.ShowFirstRunSetup, false);
API.Login("Rhythm Champion", "osu!");
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 0a102510e7..c6c18f6061 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -35,8 +35,8 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 2f0facea18..64af0d70f3 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -61,8 +61,8 @@
-
-
+
+
@@ -84,7 +84,7 @@
-
+