1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 17:27:24 +08:00

Allow screens to change the ability to interact with the global track

This commit is contained in:
Dean Herbert 2023-07-25 20:00:18 +09:00
parent 157b1f301b
commit 6146f30541
5 changed files with 53 additions and 21 deletions

View File

@ -30,20 +30,14 @@ namespace osu.Game.Overlays.Music
[Resolved]
private OnScreenDisplay? onScreenDisplay { get; set; }
[Resolved]
private OsuGame game { get; set; } = null!;
public bool OnPressed(KeyBindingPressEvent<GlobalAction> e)
{
if (e.Repeat)
if (e.Repeat || !musicController.AllowTrackControl.Value)
return false;
switch (e.Action)
{
case GlobalAction.MusicPlay:
if (game.LocalUserPlaying.Value)
return false;
// use previous state as TogglePause may not update the track's state immediately (state update is run on the audio thread see https://github.com/ppy/osu/issues/9880#issuecomment-674668842)
bool wasPlaying = musicController.IsPlaying;

View File

@ -40,6 +40,11 @@ namespace osu.Game.Overlays
/// </summary>
public bool UserPauseRequested { get; private set; }
/// <summary>
/// Whether control of the global track should be allowed.
/// </summary>
public readonly BindableBool AllowTrackControl = new BindableBool(true);
/// <summary>
/// Fired when the global <see cref="WorkingBeatmap"/> has changed.
/// Includes direction information for display purposes.
@ -92,8 +97,10 @@ namespace osu.Game.Overlays
seekDelegate?.Cancel();
seekDelegate = Schedule(() =>
{
if (!beatmap.Disabled)
CurrentTrack.Seek(position);
if (beatmap.Disabled || !AllowTrackControl.Value)
return;
CurrentTrack.Seek(position);
});
}
@ -107,7 +114,7 @@ namespace osu.Game.Overlays
if (CurrentTrack.IsDummyDevice || beatmap.Value.BeatmapSetInfo.DeletePending)
{
if (beatmap.Disabled)
if (beatmap.Disabled || !AllowTrackControl.Value)
return;
Logger.Log($"{nameof(MusicController)} skipping next track to {nameof(EnsurePlayingSomething)}");
@ -132,6 +139,9 @@ namespace osu.Game.Overlays
/// <returns>Whether the operation was successful.</returns>
public bool Play(bool restart = false, bool requestedByUser = false)
{
if (requestedByUser && !AllowTrackControl.Value)
return false;
if (requestedByUser)
UserPauseRequested = false;
@ -153,6 +163,9 @@ namespace osu.Game.Overlays
/// </param>
public void Stop(bool requestedByUser = false)
{
if (requestedByUser && !AllowTrackControl.Value)
return;
UserPauseRequested |= requestedByUser;
if (CurrentTrack.IsRunning)
CurrentTrack.StopAsync();
@ -164,6 +177,9 @@ namespace osu.Game.Overlays
/// <returns>Whether the operation was successful.</returns>
public bool TogglePause()
{
if (!AllowTrackControl.Value)
return false;
if (CurrentTrack.IsRunning)
Stop(true);
else
@ -189,7 +205,7 @@ namespace osu.Game.Overlays
/// <returns>The <see cref="PreviousTrackResult"/> that indicate the decided action.</returns>
private PreviousTrackResult prev()
{
if (beatmap.Disabled)
if (beatmap.Disabled || !AllowTrackControl.Value)
return PreviousTrackResult.None;
double currentTrackPosition = CurrentTrack.CurrentTime;
@ -229,7 +245,7 @@ namespace osu.Game.Overlays
private bool next()
{
if (beatmap.Disabled)
if (beatmap.Disabled || !AllowTrackControl.Value)
return false;
queuedDirection = TrackChangeDirection.Next;
@ -352,7 +368,7 @@ namespace osu.Game.Overlays
private void onTrackCompleted()
{
if (!CurrentTrack.Looping && !beatmap.Disabled)
if (!CurrentTrack.Looping && !beatmap.Disabled && AllowTrackControl.Value)
NextTrack();
}

View File

@ -68,6 +68,8 @@ namespace osu.Game.Overlays
[Resolved]
private OsuColour colours { get; set; }
private Bindable<bool> allowTrackControl;
public NowPlayingOverlay()
{
Width = 400;
@ -220,8 +222,10 @@ namespace osu.Game.Overlays
{
base.LoadComplete();
beatmap.BindDisabledChanged(_ => Scheduler.AddOnce(beatmapDisabledChanged));
beatmapDisabledChanged();
beatmap.BindDisabledChanged(_ => Scheduler.AddOnce(updateEnabledStates));
allowTrackControl = musicController.AllowTrackControl.GetBoundCopy();
allowTrackControl.BindValueChanged(_ => Scheduler.AddOnce(updateEnabledStates), true);
musicController.TrackChanged += trackChanged;
trackChanged(beatmap.Value);
@ -334,16 +338,18 @@ namespace osu.Game.Overlays
};
}
private void beatmapDisabledChanged()
private void updateEnabledStates()
{
bool disabled = beatmap.Disabled;
bool beatmapDisabled = beatmap.Disabled;
bool trackControlDisabled = !musicController.AllowTrackControl.Value;
if (disabled)
if (beatmapDisabled || trackControlDisabled)
playlist?.Hide();
prevButton.Enabled.Value = !disabled;
nextButton.Enabled.Value = !disabled;
playlistButton.Enabled.Value = !disabled;
prevButton.Enabled.Value = !beatmapDisabled && !trackControlDisabled;
nextButton.Enabled.Value = !beatmapDisabled && !trackControlDisabled;
playlistButton.Enabled.Value = !beatmapDisabled && !trackControlDisabled;
playButton.Enabled.Value = !trackControlDisabled;
}
protected override void Dispose(bool isDisposing)

View File

@ -69,6 +69,12 @@ namespace osu.Game.Screens
/// </summary>
bool? ApplyModTrackAdjustments { get; }
/// <summary>
/// Whether control of the global track should be allowed via the music controller / now playing overlay.
/// A <see langword="null"/> value means that the parent screen's value of this setting will be used.
/// </summary>
bool? AllowGlobalTrackControl { get; }
/// <summary>
/// Invoked when the back button has been pressed to close any overlays before exiting this <see cref="IOsuScreen"/>.
/// </summary>

View File

@ -87,6 +87,8 @@ namespace osu.Game.Screens
public virtual bool? ApplyModTrackAdjustments => null;
public virtual bool? AllowGlobalTrackControl => null;
public Bindable<WorkingBeatmap> Beatmap { get; private set; }
public Bindable<RulesetInfo> Ruleset { get; private set; }
@ -95,6 +97,8 @@ namespace osu.Game.Screens
private OsuScreenDependencies screenDependencies;
private bool? globalMusicControlStateAtSuspend;
private bool? modTrackAdjustmentStateAtSuspend;
internal void CreateLeasedDependencies(IReadOnlyDependencyContainer dependencies) => createDependencies(dependencies);
@ -180,6 +184,8 @@ namespace osu.Game.Screens
// in such a case there's no need to restore this value.
if (modTrackAdjustmentStateAtSuspend != null)
musicController.ApplyModTrackAdjustments = modTrackAdjustmentStateAtSuspend.Value;
if (globalMusicControlStateAtSuspend != null)
musicController.AllowTrackControl.Value = globalMusicControlStateAtSuspend.Value;
base.OnResuming(e);
}
@ -189,6 +195,7 @@ namespace osu.Game.Screens
base.OnSuspending(e);
modTrackAdjustmentStateAtSuspend = musicController.ApplyModTrackAdjustments;
globalMusicControlStateAtSuspend = musicController.AllowTrackControl.Value;
onSuspendingLogo();
}
@ -200,6 +207,9 @@ namespace osu.Game.Screens
if (ApplyModTrackAdjustments != null)
musicController.ApplyModTrackAdjustments = ApplyModTrackAdjustments.Value;
if (AllowGlobalTrackControl != null)
musicController.AllowTrackControl.Value = AllowGlobalTrackControl.Value;
if (backgroundStack?.Push(ownedBackground = CreateBackground()) != true)
{
// If the constructed instance was not actually pushed to the background stack, we don't want to track it unnecessarily.