diff --git a/osu.Game/Overlays/DialogOverlay.cs b/osu.Game/Overlays/DialogOverlay.cs index a07cf1608d..493cd66258 100644 --- a/osu.Game/Overlays/DialogOverlay.cs +++ b/osu.Game/Overlays/DialogOverlay.cs @@ -49,43 +49,54 @@ namespace osu.Game.Overlays public void Push(PopupDialog dialog) { - if (dialog == CurrentDialog || dialog.State.Value != Visibility.Visible) return; - - var lastDialog = CurrentDialog; + if (dialog == CurrentDialog || dialog.State.Value == Visibility.Hidden) return; // Immediately update the externally accessible property as this may be used for checks even before // a DialogOverlay instance has finished loading. + var lastDialog = CurrentDialog; CurrentDialog = dialog; - Scheduler.Add(() => + Schedule(() => { // if any existing dialog is being displayed, dismiss it before showing a new one. lastDialog?.Hide(); - dialog.State.ValueChanged += state => onDialogOnStateChanged(dialog, state.NewValue); - dialogContainer.Add(dialog); + // if the new dialog is hidden before added to the dialogContainer, bypass any further operations. + if (dialog.State.Value == Visibility.Hidden) + { + dismiss(); + return; + } + + dialogContainer.Add(dialog); Show(); - }, false); + + dialog.State.BindValueChanged(state => + { + if (state.NewValue != Visibility.Hidden) return; + + // Trigger the demise of the dialog as soon as it hides. + dialog.Delay(PopupDialog.EXIT_DURATION).Expire(); + + dismiss(); + }); + }); + + void dismiss() + { + if (dialog != CurrentDialog) return; + + // Handle the case where the dialog is the currently displayed dialog. + // In this scenario, the overlay itself should also be hidden. + Hide(); + CurrentDialog = null; + } } public override bool IsPresent => Scheduler.HasPendingTasks || dialogContainer.Children.Count > 0; protected override bool BlockNonPositionalInput => true; - private void onDialogOnStateChanged(VisibilityContainer dialog, Visibility v) - { - if (v != Visibility.Hidden) return; - - // handle the dialog being dismissed. - dialog.Delay(PopupDialog.EXIT_DURATION).Expire(); - - if (dialog == CurrentDialog) - { - Hide(); - CurrentDialog = null; - } - } - protected override void PopIn() { base.PopIn(); @@ -97,7 +108,8 @@ namespace osu.Game.Overlays base.PopOut(); lowPassFilter.CutoffTo(AudioFilter.MAX_LOWPASS_CUTOFF, 100, Easing.InCubic); - if (CurrentDialog?.State.Value == Visibility.Visible) + // PopOut gets called initially, but we only want to hide dialog when we have been loaded and are present. + if (IsLoaded && CurrentDialog?.State.Value == Visibility.Visible) CurrentDialog.Hide(); }