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 @@ - +