diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingLayer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingLayer.cs index 1be191fc29..d426723f0b 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingLayer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingLayer.cs @@ -5,6 +5,7 @@ using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Utils; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osuTK; @@ -14,8 +15,7 @@ namespace osu.Game.Tests.Visual.UserInterface { public class TestSceneLoadingLayer : OsuTestScene { - private Drawable dimContent; - private LoadingLayer overlay; + private TestLoadingLayer overlay; private Container content; @@ -29,14 +29,14 @@ namespace osu.Game.Tests.Visual.UserInterface Size = new Vector2(300), Anchor = Anchor.Centre, Origin = Anchor.Centre, - Children = new[] + Children = new Drawable[] { new Box { Colour = Color4.SlateGray, RelativeSizeAxes = Axes.Both, }, - dimContent = new FillFlowContainer + new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -51,7 +51,7 @@ namespace osu.Game.Tests.Visual.UserInterface new TriangleButton { Text = "puush me", Width = 200, Action = () => { } }, } }, - overlay = new LoadingLayer(dimContent), + overlay = new TestLoadingLayer(true), } }, }; @@ -64,25 +64,11 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("show", () => overlay.Show()); - AddUntilStep("wait for content dim", () => dimContent.Colour != Color4.White); + AddUntilStep("wait for content dim", () => overlay.BackgroundDimLayer.Alpha > 0); AddStep("hide", () => overlay.Hide()); - AddUntilStep("wait for content restore", () => dimContent.Colour == Color4.White); - } - - [Test] - public void TestContentRestoreOnDispose() - { - AddAssert("not visible", () => !overlay.IsPresent); - - AddStep("show", () => overlay.Show()); - - AddUntilStep("wait for content dim", () => dimContent.Colour != Color4.White); - - AddStep("expire", () => overlay.Expire()); - - AddUntilStep("wait for content restore", () => dimContent.Colour == Color4.White); + AddUntilStep("wait for content restore", () => Precision.AlmostEquals(overlay.BackgroundDimLayer.Alpha, 0)); } [Test] @@ -98,5 +84,15 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("hide", () => overlay.Hide()); } + + private class TestLoadingLayer : LoadingLayer + { + public new Box BackgroundDimLayer => base.BackgroundDimLayer; + + public TestLoadingLayer(bool dimBackground = false, bool withBox = true) + : base(dimBackground, withBox) + { + } + } } } diff --git a/osu.Game/Graphics/UserInterface/LoadingLayer.cs b/osu.Game/Graphics/UserInterface/LoadingLayer.cs index c8c4424bee..47ba5fce4d 100644 --- a/osu.Game/Graphics/UserInterface/LoadingLayer.cs +++ b/osu.Game/Graphics/UserInterface/LoadingLayer.cs @@ -2,8 +2,9 @@ // See the LICENCE file in the repository root for full licence text. using System; +using JetBrains.Annotations; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osuTK; using osuTK.Graphics; @@ -17,22 +18,32 @@ namespace osu.Game.Graphics.UserInterface /// public class LoadingLayer : LoadingSpinner { - private readonly Drawable dimTarget; + [CanBeNull] + protected Box BackgroundDimLayer { get; } /// - /// Constuct a new loading spinner. + /// Construct a new loading spinner. /// - /// An optional target to dim when displayed. + /// Whether the full background area should be dimmed while loading. /// Whether the spinner should have a surrounding black box for visibility. - public LoadingLayer(Drawable dimTarget = null, bool withBox = true) + public LoadingLayer(bool dimBackground = false, bool withBox = true) : base(withBox) { RelativeSizeAxes = Axes.Both; Size = new Vector2(1); - this.dimTarget = dimTarget; - MainContents.RelativeSizeAxes = Axes.None; + + if (dimBackground) + { + AddInternal(BackgroundDimLayer = new Box + { + Depth = float.MaxValue, + Colour = Color4.Black, + Alpha = 0, + RelativeSizeAxes = Axes.Both, + }); + } } public override bool HandleNonPositionalInput => false; @@ -56,31 +67,21 @@ namespace osu.Game.Graphics.UserInterface protected override void PopIn() { - dimTarget?.FadeColour(OsuColour.Gray(0.5f), TRANSITION_DURATION, Easing.OutQuint); + BackgroundDimLayer?.FadeTo(0.5f, TRANSITION_DURATION * 2, Easing.OutQuint); base.PopIn(); } protected override void PopOut() { - dimTarget?.FadeColour(Color4.White, TRANSITION_DURATION, Easing.OutQuint); + BackgroundDimLayer?.FadeOut(TRANSITION_DURATION, Easing.OutQuint); base.PopOut(); } protected override void Update() { base.Update(); + MainContents.Size = new Vector2(Math.Clamp(Math.Min(DrawWidth, DrawHeight) * 0.25f, 30, 100)); } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - if (State.Value == Visibility.Visible) - { - // ensure we don't leave the target in a bad state. - dimTarget?.FadeColour(Color4.White, TRANSITION_DURATION, Easing.OutQuint); - } - } } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 17831ed26b..36e3078653 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -151,11 +151,11 @@ namespace osu.Game updateBlockingOverlayFade(); } - public void RemoveBlockingOverlay(OverlayContainer overlay) + public void RemoveBlockingOverlay(OverlayContainer overlay) => Schedule(() => { visibleBlockingOverlays.Remove(overlay); updateBlockingOverlayFade(); - } + }); /// /// Close all game-wide overlays. diff --git a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs index a0b1b27ebf..bcb3d4b635 100644 --- a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs +++ b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs @@ -48,11 +48,9 @@ namespace osu.Game.Overlays.AccountCreation [BackgroundDependencyLoader] private void load(OsuColour colours) { - FillFlowContainer mainContent; - InternalChildren = new Drawable[] { - mainContent = new FillFlowContainer + new FillFlowContainer { RelativeSizeAxes = Axes.Both, Direction = FillDirection.Vertical, @@ -124,7 +122,7 @@ namespace osu.Game.Overlays.AccountCreation }, }, }, - loadingLayer = new LoadingLayer(mainContent) + loadingLayer = new LoadingLayer(true) }; textboxes = new[] { usernameTextBox, emailTextBox, passwordTextBox }; diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 1e29e713af..0c9c995dd6 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -92,14 +92,14 @@ namespace osu.Game.Overlays { foundContent = new FillFlowContainer(), notFoundContent = new NotFoundDrawable(), - loadingLayer = new LoadingLayer(panelTarget) } } - } + }, }, } - } - } + }, + }, + loadingLayer = new LoadingLayer(true) }; } diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs index c983b337b5..7ad6906cea 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs @@ -53,7 +53,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons Size = new Vector2(18), Shadow = false, }, - loading = new LoadingLayer(icon, false), + loading = new LoadingLayer(true, false), }); Action = () => diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 9a2dcd014a..b598b7d97f 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -157,11 +157,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } }, - loading = new LoadingLayer() } } - } - } + }, + }, + loading = new LoadingLayer() }); } @@ -228,7 +228,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { Scores = null; notSupporterPlaceholder.Show(); + loading.Hide(); + loading.FinishTransforms(); return; } @@ -241,6 +243,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores getScoresRequest.Success += scores => { loading.Hide(); + loading.FinishTransforms(); + Scores = scores; if (!scores.Scores.Any()) diff --git a/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs b/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs index cc26a11da1..e6fe6ac749 100644 --- a/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs +++ b/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs @@ -128,7 +128,7 @@ namespace osu.Game.Overlays.Dashboard.Friends AutoSizeAxes = Axes.Y, Padding = new MarginPadding { Horizontal = 50 } }, - loading = new LoadingLayer(itemsPlaceholder) + loading = new LoadingLayer(true) } } } diff --git a/osu.Game/Overlays/DashboardOverlay.cs b/osu.Game/Overlays/DashboardOverlay.cs index 04defce636..03c320debe 100644 --- a/osu.Game/Overlays/DashboardOverlay.cs +++ b/osu.Game/Overlays/DashboardOverlay.cs @@ -68,7 +68,7 @@ namespace osu.Game.Overlays } } }, - loading = new LoadingLayer(content), + loading = new LoadingLayer(true), }; } diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index c8c1db012f..5820d405d4 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -59,7 +59,7 @@ namespace osu.Game.Overlays }, }, }, - loading = new LoadingLayer(content), + loading = new LoadingLayer(true), }; } diff --git a/osu.Game/Overlays/Rankings/SpotlightsLayout.cs b/osu.Game/Overlays/Rankings/SpotlightsLayout.cs index 61339df76f..b16e0a4908 100644 --- a/osu.Game/Overlays/Rankings/SpotlightsLayout.cs +++ b/osu.Game/Overlays/Rankings/SpotlightsLayout.cs @@ -45,6 +45,7 @@ namespace osu.Game.Overlays.Rankings { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; + InternalChild = new ReverseChildIDFillFlowContainer { RelativeSizeAxes = Axes.X, @@ -68,7 +69,7 @@ namespace osu.Game.Overlays.Rankings AutoSizeAxes = Axes.Y, Margin = new MarginPadding { Vertical = 10 } }, - loading = new LoadingLayer(content) + loading = new LoadingLayer(true) } } } diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index ae6d49960a..25350e310a 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -42,6 +42,8 @@ namespace osu.Game.Overlays Depth = -float.MaxValue }) { + loading = new LoadingLayer(true); + Children = new Drawable[] { background = new Box @@ -74,12 +76,12 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.X, Margin = new MarginPadding { Bottom = 10 } }, - loading = new LoadingLayer(contentContainer), } } } } - } + }, + loading }; } diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 79f5dfdee1..0f06188dc2 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -65,7 +65,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge Padding = new MarginPadding(10), Child = roomsContainer = new RoomsContainer { JoinRequested = joinRequested } }, - loadingLayer = new LoadingLayer(roomsContainer), + loadingLayer = new LoadingLayer(true), } }, new RoomInspector diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs index ae03d384f6..67c6aa7add 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs @@ -71,201 +71,192 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match [BackgroundDependencyLoader] private void load(OsuColour colours) { - Container dimContent; - InternalChildren = new Drawable[] { - dimContent = new Container + new Box { RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + Colour = Color4Extensions.FromHex(@"28242d"), + }, + new GridContainer + { + RelativeSizeAxes = Axes.Both, + RowDimensions = new[] { - new Box + new Dimension(GridSizeMode.Distributed), + new Dimension(GridSizeMode.AutoSize), + }, + Content = new[] + { + new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = Color4Extensions.FromHex(@"28242d"), - }, - new GridContainer - { - RelativeSizeAxes = Axes.Both, - RowDimensions = new[] + new OsuScrollContainer { - new Dimension(GridSizeMode.Distributed), - new Dimension(GridSizeMode.AutoSize), - }, - Content = new[] - { - new Drawable[] + Padding = new MarginPadding { - new OsuScrollContainer + Horizontal = OsuScreen.HORIZONTAL_OVERFLOW_PADDING, + Vertical = 10 + }, + RelativeSizeAxes = Axes.Both, + Children = new[] + { + new FillFlowContainer { - Padding = new MarginPadding + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new Drawable[] { - Horizontal = OsuScreen.HORIZONTAL_OVERFLOW_PADDING, - Vertical = 10 - }, - RelativeSizeAxes = Axes.Both, - Children = new[] - { - new FillFlowContainer + new Container { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.WIDTH_PADDING }, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 10), Children = new Drawable[] { - new Container + new SectionContainer { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Padding = new MarginPadding { Horizontal = WaveOverlayContainer.WIDTH_PADDING }, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] + Padding = new MarginPadding { Right = FIELD_PADDING / 2 }, + Children = new[] { - new SectionContainer + new Section("Room name") { - Padding = new MarginPadding { Right = FIELD_PADDING / 2 }, - Children = new[] + Child = NameField = new SettingsTextBox { - new Section("Room name") + RelativeSizeAxes = Axes.X, + TabbableContentContainer = this, + }, + }, + new Section("Room visibility") + { + Alpha = disabled_alpha, + Child = AvailabilityPicker = new RoomAvailabilityPicker + { + Enabled = { Value = false } + }, + }, + new Section("Game type") + { + Alpha = disabled_alpha, + Child = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Spacing = new Vector2(7), + Children = new Drawable[] { - Child = NameField = new SettingsTextBox + TypePicker = new GameTypePicker { RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - }, - }, - new Section("Room visibility") - { - Alpha = disabled_alpha, - Child = AvailabilityPicker = new RoomAvailabilityPicker - { Enabled = { Value = false } }, - }, - new Section("Game type") - { - Alpha = disabled_alpha, - Child = new FillFlowContainer + typeLabel = new OsuSpriteText { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Spacing = new Vector2(7), - Children = new Drawable[] - { - TypePicker = new GameTypePicker - { - RelativeSizeAxes = Axes.X, - Enabled = { Value = false } - }, - typeLabel = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 14), - Colour = colours.Yellow - }, - }, + Font = OsuFont.GetFont(size: 14), + Colour = colours.Yellow }, }, }, }, - new SectionContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Padding = new MarginPadding { Left = FIELD_PADDING / 2 }, - Children = new[] - { - new Section("Max participants") - { - Alpha = disabled_alpha, - Child = MaxParticipantsField = new SettingsNumberTextBox - { - RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - ReadOnly = true, - }, - }, - new Section("Password (optional)") - { - Alpha = disabled_alpha, - Child = new SettingsPasswordTextBox - { - RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - ReadOnly = true, - }, - }, - } - } }, }, - initialBeatmapControl = new BeatmapSelectionControl + new SectionContainer { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, - Width = 0.5f + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Padding = new MarginPadding { Left = FIELD_PADDING / 2 }, + Children = new[] + { + new Section("Max participants") + { + Alpha = disabled_alpha, + Child = MaxParticipantsField = new SettingsNumberTextBox + { + RelativeSizeAxes = Axes.X, + TabbableContentContainer = this, + ReadOnly = true, + }, + }, + new Section("Password (optional)") + { + Alpha = disabled_alpha, + Child = new SettingsPasswordTextBox + { + RelativeSizeAxes = Axes.X, + TabbableContentContainer = this, + ReadOnly = true, + }, + }, + } } - } + }, + }, + initialBeatmapControl = new BeatmapSelectionControl + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + Width = 0.5f } - }, - }, + } + } }, - new Drawable[] + }, + }, + new Drawable[] + { + new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Y = 2, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] { - new Container + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4Extensions.FromHex(@"28242d").Darken(0.5f).Opacity(1f), + }, + new FillFlowContainer { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Y = 2, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Margin = new MarginPadding { Vertical = 20 }, + Padding = new MarginPadding { Horizontal = OsuScreen.HORIZONTAL_OVERFLOW_PADDING }, Children = new Drawable[] { - new Box + ApplyButton = new CreateOrUpdateButton { - RelativeSizeAxes = Axes.Both, - Colour = Color4Extensions.FromHex(@"28242d").Darken(0.5f).Opacity(1f), + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Size = new Vector2(230, 55), + Enabled = { Value = false }, + Action = apply, }, - new FillFlowContainer + ErrorText = new OsuSpriteText { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Margin = new MarginPadding { Vertical = 20 }, - Padding = new MarginPadding { Horizontal = OsuScreen.HORIZONTAL_OVERFLOW_PADDING }, - Children = new Drawable[] - { - ApplyButton = new CreateOrUpdateButton - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Size = new Vector2(230, 55), - Enabled = { Value = false }, - Action = apply, - }, - ErrorText = new OsuSpriteText - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Alpha = 0, - Depth = 1, - Colour = colours.RedDark - } - } + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Alpha = 0, + Depth = 1, + Colour = colours.RedDark } } } } } - }, + } } }, - loadingLayer = new LoadingLayer(dimContent) + loadingLayer = new LoadingLayer(true) }; TypePicker.Current.BindValueChanged(type => typeLabel.Text = type.NewValue?.Name ?? string.Empty, true); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs index 72539a2e3a..36dbb9e792 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs @@ -47,7 +47,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer [BackgroundDependencyLoader] private void load() { - AddInternal(loadingLayer = new LoadingLayer(Carousel)); + AddInternal(loadingLayer = new LoadingLayer(true)); initialBeatmap = Beatmap.Value; initialRuleset = Ruleset.Value; initialMods = Mods.Value.ToList(); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayer.cs index 4247e954bd..4bee502e2e 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayer.cs @@ -62,7 +62,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer // todo: this should be implemented via a custom HUD implementation, and correctly masked to the main content area. LoadComponentAsync(leaderboard = new MultiplayerGameplayLeaderboard(ScoreProcessor, userIds), HUDOverlay.Add); - HUDOverlay.Add(loadingDisplay = new LoadingLayer(DrawableRuleset) { Depth = float.MaxValue }); + HUDOverlay.Add(loadingDisplay = new LoadingLayer(true) { Depth = float.MaxValue }); if (Token == null) return; // Todo: Somehow handle token retrieval failure. diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsMatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsMatchSettingsOverlay.cs index 6b92526f35..01f9920609 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsMatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsMatchSettingsOverlay.cs @@ -64,243 +64,234 @@ namespace osu.Game.Screens.OnlinePlay.Playlists [BackgroundDependencyLoader] private void load(OsuColour colours) { - Container dimContent; - InternalChildren = new Drawable[] { - dimContent = new Container + new Box { RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + Colour = Color4Extensions.FromHex(@"28242d"), + }, + new GridContainer + { + RelativeSizeAxes = Axes.Both, + RowDimensions = new[] { - new Box + new Dimension(GridSizeMode.Distributed), + new Dimension(GridSizeMode.AutoSize), + }, + Content = new[] + { + new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = Color4Extensions.FromHex(@"28242d"), - }, - new GridContainer - { - RelativeSizeAxes = Axes.Both, - RowDimensions = new[] + new OsuScrollContainer { - new Dimension(GridSizeMode.Distributed), - new Dimension(GridSizeMode.AutoSize), - }, - Content = new[] - { - new Drawable[] + Padding = new MarginPadding { - new OsuScrollContainer - { - Padding = new MarginPadding - { - Horizontal = OsuScreen.HORIZONTAL_OVERFLOW_PADDING, - Vertical = 10 - }, - RelativeSizeAxes = Axes.Both, - Children = new[] - { - new Container - { - Padding = new MarginPadding { Horizontal = WaveOverlayContainer.WIDTH_PADDING }, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - new SectionContainer - { - Padding = new MarginPadding { Right = FIELD_PADDING / 2 }, - Children = new[] - { - new Section("Room name") - { - Child = NameField = new SettingsTextBox - { - RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - LengthLimit = 100 - }, - }, - new Section("Duration") - { - Child = DurationField = new DurationDropdown - { - RelativeSizeAxes = Axes.X, - Items = new[] - { - TimeSpan.FromMinutes(30), - TimeSpan.FromHours(1), - TimeSpan.FromHours(2), - TimeSpan.FromHours(4), - TimeSpan.FromHours(8), - TimeSpan.FromHours(12), - //TimeSpan.FromHours(16), - TimeSpan.FromHours(24), - TimeSpan.FromDays(3), - TimeSpan.FromDays(7) - } - } - }, - new Section("Room visibility") - { - Alpha = disabled_alpha, - Child = AvailabilityPicker = new RoomAvailabilityPicker - { - Enabled = { Value = false } - }, - }, - new Section("Game type") - { - Alpha = disabled_alpha, - Child = new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Spacing = new Vector2(7), - Children = new Drawable[] - { - TypePicker = new GameTypePicker - { - RelativeSizeAxes = Axes.X, - Enabled = { Value = false } - }, - typeLabel = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 14), - Colour = colours.Yellow - }, - }, - }, - }, - new Section("Max participants") - { - Alpha = disabled_alpha, - Child = MaxParticipantsField = new SettingsNumberTextBox - { - RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - ReadOnly = true, - }, - }, - new Section("Password (optional)") - { - Alpha = disabled_alpha, - Child = new SettingsPasswordTextBox - { - RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - ReadOnly = true, - }, - }, - }, - }, - new SectionContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Padding = new MarginPadding { Left = FIELD_PADDING / 2 }, - Children = new[] - { - new Section("Playlist") - { - Child = new GridContainer - { - RelativeSizeAxes = Axes.X, - Height = 300, - Content = new[] - { - new Drawable[] - { - playlist = new DrawableRoomPlaylist(true, true) { RelativeSizeAxes = Axes.Both } - }, - new Drawable[] - { - playlistLength = new OsuSpriteText - { - Margin = new MarginPadding { Vertical = 5 }, - Colour = colours.Yellow, - Font = OsuFont.GetFont(size: 12), - } - }, - new Drawable[] - { - new PurpleTriangleButton - { - RelativeSizeAxes = Axes.X, - Height = 40, - Text = "Edit playlist", - Action = () => EditPlaylist?.Invoke() - } - } - }, - RowDimensions = new[] - { - new Dimension(), - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize), - } - } - }, - }, - }, - }, - } - }, - }, + Horizontal = OsuScreen.HORIZONTAL_OVERFLOW_PADDING, + Vertical = 10 }, - new Drawable[] + RelativeSizeAxes = Axes.Both, + Children = new[] { new Container { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Y = 2, + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.WIDTH_PADDING }, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Children = new Drawable[] { - new Box + new SectionContainer { - RelativeSizeAxes = Axes.Both, - Colour = Color4Extensions.FromHex(@"28242d").Darken(0.5f).Opacity(1f), - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Margin = new MarginPadding { Vertical = 20 }, - Padding = new MarginPadding { Horizontal = OsuScreen.HORIZONTAL_OVERFLOW_PADDING }, - Children = new Drawable[] + Padding = new MarginPadding { Right = FIELD_PADDING / 2 }, + Children = new[] { - ApplyButton = new CreateRoomButton + new Section("Room name") { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Size = new Vector2(230, 55), - Enabled = { Value = false }, - Action = apply, + Child = NameField = new SettingsTextBox + { + RelativeSizeAxes = Axes.X, + TabbableContentContainer = this, + LengthLimit = 100 + }, }, - ErrorText = new OsuSpriteText + new Section("Duration") { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Alpha = 0, - Depth = 1, - Colour = colours.RedDark - } - } + Child = DurationField = new DurationDropdown + { + RelativeSizeAxes = Axes.X, + Items = new[] + { + TimeSpan.FromMinutes(30), + TimeSpan.FromHours(1), + TimeSpan.FromHours(2), + TimeSpan.FromHours(4), + TimeSpan.FromHours(8), + TimeSpan.FromHours(12), + //TimeSpan.FromHours(16), + TimeSpan.FromHours(24), + TimeSpan.FromDays(3), + TimeSpan.FromDays(7) + } + } + }, + new Section("Room visibility") + { + Alpha = disabled_alpha, + Child = AvailabilityPicker = new RoomAvailabilityPicker + { + Enabled = { Value = false } + }, + }, + new Section("Game type") + { + Alpha = disabled_alpha, + Child = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Spacing = new Vector2(7), + Children = new Drawable[] + { + TypePicker = new GameTypePicker + { + RelativeSizeAxes = Axes.X, + Enabled = { Value = false } + }, + typeLabel = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 14), + Colour = colours.Yellow + }, + }, + }, + }, + new Section("Max participants") + { + Alpha = disabled_alpha, + Child = MaxParticipantsField = new SettingsNumberTextBox + { + RelativeSizeAxes = Axes.X, + TabbableContentContainer = this, + ReadOnly = true, + }, + }, + new Section("Password (optional)") + { + Alpha = disabled_alpha, + Child = new SettingsPasswordTextBox + { + RelativeSizeAxes = Axes.X, + TabbableContentContainer = this, + ReadOnly = true, + }, + }, + }, + }, + new SectionContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Padding = new MarginPadding { Left = FIELD_PADDING / 2 }, + Children = new[] + { + new Section("Playlist") + { + Child = new GridContainer + { + RelativeSizeAxes = Axes.X, + Height = 300, + Content = new[] + { + new Drawable[] + { + playlist = new DrawableRoomPlaylist(true, true) { RelativeSizeAxes = Axes.Both } + }, + new Drawable[] + { + playlistLength = new OsuSpriteText + { + Margin = new MarginPadding { Vertical = 5 }, + Colour = colours.Yellow, + Font = OsuFont.GetFont(size: 12), + } + }, + new Drawable[] + { + new PurpleTriangleButton + { + RelativeSizeAxes = Axes.X, + Height = 40, + Text = "Edit playlist", + Action = () => EditPlaylist?.Invoke() + } + } + }, + RowDimensions = new[] + { + new Dimension(), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + } + } + }, + }, + }, + }, + } + }, + }, + }, + new Drawable[] + { + new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Y = 2, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4Extensions.FromHex(@"28242d").Darken(0.5f).Opacity(1f), + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Margin = new MarginPadding { Vertical = 20 }, + Padding = new MarginPadding { Horizontal = OsuScreen.HORIZONTAL_OVERFLOW_PADDING }, + Children = new Drawable[] + { + ApplyButton = new CreateRoomButton + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Size = new Vector2(230, 55), + Enabled = { Value = false }, + Action = apply, + }, + ErrorText = new OsuSpriteText + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Alpha = 0, + Depth = 1, + Colour = colours.RedDark } } } } } - }, + } } }, - loadingLayer = new LoadingLayer(dimContent) + loadingLayer = new LoadingLayer(true) }; TypePicker.Current.BindValueChanged(type => typeLabel.Text = type.NewValue?.Name ?? string.Empty, true); diff --git a/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs b/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs index 5530b4beac..b53141e8fb 100644 --- a/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs +++ b/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs @@ -53,7 +53,6 @@ namespace osu.Game.Screens.Play private readonly Bindable> mods; private readonly Drawable facade; private LoadingSpinner loading; - private Sprite backgroundSprite; public IBindable> Mods => mods; @@ -123,7 +122,7 @@ namespace osu.Game.Screens.Play Masking = true, Children = new Drawable[] { - backgroundSprite = new Sprite + new Sprite { RelativeSizeAxes = Axes.Both, Texture = beatmap?.Background, @@ -131,7 +130,7 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, FillMode = FillMode.Fill, }, - loading = new LoadingLayer(backgroundSprite) + loading = new LoadingLayer(true) } }, new OsuSpriteText diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index d76f0abb9e..36f8fbedb3 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -13,6 +13,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Pooling; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; +using osu.Framework.Layout; using osu.Framework.Threading; using osu.Framework.Utils; using osu.Game.Beatmaps; @@ -124,6 +125,8 @@ namespace osu.Game.Screens.Select { BeatmapSetsChanged?.Invoke(); BeatmapSetsLoaded = true; + + itemsCache.Invalidate(); }); } @@ -567,6 +570,15 @@ namespace osu.Game.Screens.Select #endregion + protected override bool OnInvalidate(Invalidation invalidation, InvalidationSource source) + { + // handles the vertical size of the carousel changing (ie. on window resize when aspect ratio has changed). + if ((invalidation & Invalidation.Layout) > 0) + itemsCache.Invalidate(); + + return base.OnInvalidate(invalidation, source); + } + protected override void Update() { base.Update(); @@ -777,13 +789,19 @@ namespace osu.Game.Screens.Select Scroll.ScrollContent.Height = currentY; - if (BeatmapSetsLoaded && (selectedBeatmapSet == null || selectedBeatmap == null || selectedBeatmapSet.State.Value != CarouselItemState.Selected)) - { - selectedBeatmapSet = null; - SelectionChanged?.Invoke(null); - } - itemsCache.Validate(); + + // update and let external consumers know about selection loss. + if (BeatmapSetsLoaded) + { + bool selectionLost = selectedBeatmapSet != null && selectedBeatmapSet.State.Value != CarouselItemState.Selected; + + if (selectionLost) + { + selectedBeatmapSet = null; + SelectionChanged?.Invoke(null); + } + } } private bool firstScroll = true; @@ -806,14 +824,13 @@ namespace osu.Game.Screens.Select break; case PendingScrollOperation.Immediate: + // in order to simplify animation logic, rather than using the animated version of ScrollTo, // we take the difference in scroll height and apply to all visible panels. // this avoids edge cases like when the visible panels is reduced suddenly, causing ScrollContainer // to enter clamp-special-case mode where it animates completely differently to normal. float scrollChange = scrollTarget.Value - Scroll.Current; - Scroll.ScrollTo(scrollTarget.Value, false); - foreach (var i in Scroll.Children) i.Y += scrollChange; break; diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 71f78c5c95..8a1c291fca 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -63,8 +63,6 @@ namespace osu.Game.Screens.Select public BeatmapDetails() { - Container content; - Children = new Drawable[] { new Box @@ -72,7 +70,7 @@ namespace osu.Game.Screens.Select RelativeSizeAxes = Axes.Both, Colour = Color4.Black.Opacity(0.5f), }, - content = new Container + new Container { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Horizontal = spacing }, @@ -159,7 +157,7 @@ namespace osu.Game.Screens.Select }, }, }, - loading = new LoadingLayer(content), + loading = new LoadingLayer(true), }; } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index a5252fdc96..7e217ca7a4 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -428,16 +428,21 @@ namespace osu.Game.Screens.Select private void updateSelectedBeatmap(BeatmapInfo beatmap) { + if (beatmap == null && beatmapNoDebounce == null) + return; + if (beatmap?.Equals(beatmapNoDebounce) == true) return; beatmapNoDebounce = beatmap; - performUpdateSelected(); } private void updateSelectedRuleset(RulesetInfo ruleset) { + if (ruleset == null && rulesetNoDebounce == null) + return; + if (ruleset?.Equals(rulesetNoDebounce) == true) return;