diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs
index 0e8e481e9d..512602d120 100644
--- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs
+++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs
@@ -34,7 +34,7 @@ namespace osu.Game.Graphics.Containers
protected virtual bool DimMainContent => true;
[Resolved(CanBeNull = true)]
- private OsuGame game { get; set; }
+ private IOverlayManager overlayManager { get; set; }
[Resolved]
private PreviewTrackManager previewTrackManager { get; set; }
@@ -50,8 +50,8 @@ namespace osu.Game.Graphics.Containers
protected override void LoadComplete()
{
- if (game != null)
- OverlayActivationMode.BindTo(game.OverlayActivationMode);
+ if (overlayManager != null)
+ OverlayActivationMode.BindTo(overlayManager.OverlayActivationMode);
OverlayActivationMode.BindValueChanged(mode =>
{
@@ -127,14 +127,14 @@ namespace osu.Game.Graphics.Containers
if (didChange)
samplePopIn?.Play();
- if (BlockScreenWideMouse && DimMainContent) game?.ShowBlockingOverlay(this);
+ if (BlockScreenWideMouse && DimMainContent) overlayManager?.ShowBlockingOverlay(this);
break;
case Visibility.Hidden:
if (didChange)
samplePopOut?.Play();
- if (BlockScreenWideMouse) game?.HideBlockingOverlay(this);
+ if (BlockScreenWideMouse) overlayManager?.HideBlockingOverlay(this);
break;
}
@@ -150,7 +150,7 @@ namespace osu.Game.Graphics.Containers
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
- game?.HideBlockingOverlay(this);
+ overlayManager?.HideBlockingOverlay(this);
}
}
}
diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs
index da8cdde944..fcf5889a7e 100644
--- a/osu.Game/OsuGame.cs
+++ b/osu.Game/OsuGame.cs
@@ -63,7 +63,7 @@ namespace osu.Game
/// The full osu! experience. Builds on top of to add menus and binding logic
/// for initial components that are generally retrieved via DI.
///
- public class OsuGame : OsuGameBase, IKeyBindingHandler, ILocalUserPlayInfo, IPerformFromScreenRunner
+ public class OsuGame : OsuGameBase, IKeyBindingHandler, ILocalUserPlayInfo, IPerformFromScreenRunner, IOverlayManager
{
///
/// The amount of global offset to apply when a left/right anchored overlay is displayed (ie. settings or notifications).
@@ -184,48 +184,34 @@ namespace osu.Game
SentryLogger = new SentryLogger(this);
}
+ #region IOverlayManager
+
+ IBindable IOverlayManager.OverlayActivationMode => OverlayActivationMode;
+
private void updateBlockingOverlayFade() =>
ScreenContainer.FadeColour(visibleBlockingOverlays.Any() ? OsuColour.Gray(0.5f) : Color4.White, 500, Easing.OutQuint);
- ///
- /// Registers a blocking that was not created by itself for later use.
- ///
- ///
- /// The goal of this method is to allow child screens, like to register their own full-screen blocking overlays
- /// with background dim.
- /// In those cases, for the dim to work correctly, the overlays need to be added at the `OsuGame` level directly, rather as children of the screens.
- ///
- ///
- /// An that should be disposed of when the should be unregistered.
- /// Disposing of this will automatically expire the .
- ///
- internal IDisposable RegisterBlockingOverlay(OverlayContainer overlayContainer)
+ IDisposable IOverlayManager.RegisterBlockingOverlay(OverlayContainer overlayContainer)
{
if (overlayContainer.Parent != null)
- throw new ArgumentException($@"Overlays registered via {nameof(RegisterBlockingOverlay)} should not be added to the scene graph.");
+ throw new ArgumentException($@"Overlays registered via {nameof(IOverlayManager.RegisterBlockingOverlay)} should not be added to the scene graph.");
if (externalOverlays.Contains(overlayContainer))
- throw new ArgumentException($@"{overlayContainer} has already been registered via {nameof(RegisterBlockingOverlay)} once.");
+ throw new ArgumentException($@"{overlayContainer} has already been registered via {nameof(IOverlayManager.RegisterBlockingOverlay)} once.");
externalOverlays.Add(overlayContainer);
overlayContent.Add(overlayContainer);
return new InvokeOnDisposal(() => unregisterBlockingOverlay(overlayContainer));
}
- ///
- /// Should be called when has been shown and should begin blocking background input.
- ///
- internal void ShowBlockingOverlay(OverlayContainer overlay)
+ void IOverlayManager.ShowBlockingOverlay(OverlayContainer overlay)
{
if (!visibleBlockingOverlays.Contains(overlay))
visibleBlockingOverlays.Add(overlay);
updateBlockingOverlayFade();
}
- ///
- /// Should be called when a blocking has been hidden and should stop blocking background input.
- ///
- internal void HideBlockingOverlay(OverlayContainer overlay) => Schedule(() =>
+ void IOverlayManager.HideBlockingOverlay(OverlayContainer overlay) => Schedule(() =>
{
visibleBlockingOverlays.Remove(overlay);
updateBlockingOverlayFade();
@@ -240,6 +226,8 @@ namespace osu.Game
overlayContainer.Expire();
}
+ #endregion
+
///
/// Close all game-wide overlays.
///
diff --git a/osu.Game/Overlays/IOverlayManager.cs b/osu.Game/Overlays/IOverlayManager.cs
new file mode 100644
index 0000000000..940ee2d8db
--- /dev/null
+++ b/osu.Game/Overlays/IOverlayManager.cs
@@ -0,0 +1,44 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using osu.Framework.Allocation;
+using osu.Framework.Bindables;
+using osu.Framework.Graphics.Containers;
+using osu.Game.Screens.Select;
+
+namespace osu.Game.Overlays
+{
+ [Cached]
+ internal interface IOverlayManager
+ {
+ ///
+ /// Whether overlays should be able to be opened game-wide. Value is sourced from the current active screen.
+ ///
+ IBindable OverlayActivationMode { get; }
+
+ ///
+ /// Registers a blocking that was not created by itself for later use.
+ ///
+ ///
+ /// The goal of this method is to allow child screens, like to register their own full-screen blocking overlays
+ /// with background dim.
+ /// In those cases, for the dim to work correctly, the overlays need to be added at a game level directly, rather as children of the screens.
+ ///
+ ///
+ /// An that should be disposed of when the should be unregistered.
+ /// Disposing of this will automatically expire the .
+ ///
+ IDisposable RegisterBlockingOverlay(OverlayContainer overlayContainer);
+
+ ///
+ /// Should be called when has been shown and should begin blocking background input.
+ ///
+ void ShowBlockingOverlay(OverlayContainer overlay);
+
+ ///
+ /// Should be called when a blocking has been hidden and should stop blocking background input.
+ ///
+ void HideBlockingOverlay(OverlayContainer overlay);
+ }
+}
diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs
index 5b892e1925..b7a9b45bb8 100644
--- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs
+++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs
@@ -58,8 +58,8 @@ namespace osu.Game.Screens.OnlinePlay.Match
protected readonly IBindable RoomId = new Bindable();
- [Resolved]
- private OsuGame game { get; set; }
+ [Resolved(CanBeNull = true)]
+ private IOverlayManager overlayManager { get; set; }
[Resolved]
private MusicController music { get; set; }
@@ -264,7 +264,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
beatmapAvailabilityTracker.SelectedItem.BindTo(SelectedItem);
beatmapAvailabilityTracker.Availability.BindValueChanged(_ => updateWorkingBeatmap());
- userModsSelectOverlayRegistration = game?.RegisterBlockingOverlay(userModsSelectOverlay);
+ userModsSelectOverlayRegistration = overlayManager?.RegisterBlockingOverlay(userModsSelectOverlay);
}
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs b/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs
index 659084addf..c262544d6c 100644
--- a/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs
+++ b/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs
@@ -53,7 +53,7 @@ namespace osu.Game.Screens.OnlinePlay
private IReadOnlyList initialMods;
private bool itemSelected;
- private FreeModSelectScreen freeModSelectOverlay;
+ private readonly FreeModSelectScreen freeModSelectOverlay;
private IDisposable freeModSelectOverlayRegistration;
protected OnlinePlaySongSelect(Room room)
@@ -98,7 +98,7 @@ namespace osu.Game.Screens.OnlinePlay
Mods.BindValueChanged(onModsChanged);
Ruleset.BindValueChanged(onRulesetChanged);
- freeModSelectOverlayRegistration = Game?.RegisterBlockingOverlay(freeModSelectOverlay);
+ freeModSelectOverlayRegistration = OverlayManager?.RegisterBlockingOverlay(freeModSelectOverlay);
}
private void onModsChanged(ValueChangedEvent> mods)
diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs
index 55d28ec8a4..bb2746ee95 100644
--- a/osu.Game/Screens/Select/SongSelect.cs
+++ b/osu.Game/Screens/Select/SongSelect.cs
@@ -124,7 +124,7 @@ namespace osu.Game.Screens.Select
private MusicController music { get; set; }
[Resolved(CanBeNull = true)]
- protected new OsuGame Game { get; private set; }
+ internal IOverlayManager OverlayManager { get; private set; }
[BackgroundDependencyLoader(true)]
private void load(AudioManager audio, IDialogOverlay dialog, OsuColour colours, ManageCollectionsDialog manageCollectionsDialog, DifficultyRecommender recommender)
@@ -315,7 +315,7 @@ namespace osu.Game.Screens.Select
{
base.LoadComplete();
- modSelectOverlayRegistration = Game?.RegisterBlockingOverlay(ModSelect);
+ modSelectOverlayRegistration = OverlayManager?.RegisterBlockingOverlay(ModSelect);
}
///