Merge pull request #9867 from bdach/fix-pause-menu-selection

Fix pause menu selection not resetting on visibility change
This commit is contained in:
Dean Herbert 2020-08-15 22:33:03 +09:00 committed by GitHub
commit bffdb73624
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 31 deletions

View File

@ -272,7 +272,21 @@ namespace osu.Game.Tests.Visual.Gameplay
AddAssert("Overlay is closed", () => pauseOverlay.State.Value == Visibility.Hidden);
}
[Test]
public void TestSelectionResetOnVisibilityChange()
{
showOverlay();
AddStep("Select last button", () => InputManager.Key(Key.Up));
hideOverlay();
showOverlay();
AddAssert("No button selected",
() => pauseOverlay.Buttons.All(button => !button.Selected.Value));
}
private void showOverlay() => AddStep("Show overlay", () => pauseOverlay.Show());
private void hideOverlay() => AddStep("Hide overlay", () => pauseOverlay.Hide());
private DialogButton getButton(int index) => pauseOverlay.Buttons.Skip(index).First();

View File

@ -50,7 +50,7 @@ namespace osu.Game.Screens.Play
public abstract string Description { get; }
protected internal FillFlowContainer<DialogButton> InternalButtons;
protected ButtonContainer InternalButtons;
public IReadOnlyList<DialogButton> Buttons => InternalButtons;
private FillFlowContainer retryCounterContainer;
@ -59,7 +59,7 @@ namespace osu.Game.Screens.Play
{
RelativeSizeAxes = Axes.Both;
State.ValueChanged += s => selectionIndex = -1;
State.ValueChanged += s => InternalButtons.Deselect();
}
[BackgroundDependencyLoader]
@ -114,7 +114,7 @@ namespace osu.Game.Screens.Play
}
}
},
InternalButtons = new FillFlowContainer<DialogButton>
InternalButtons = new ButtonContainer
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
@ -186,40 +186,16 @@ namespace osu.Game.Screens.Play
InternalButtons.Add(button);
}
private int selectionIndex = -1;
private void setSelected(int value)
{
if (selectionIndex == value)
return;
// Deselect the previously-selected button
if (selectionIndex != -1)
InternalButtons[selectionIndex].Selected.Value = false;
selectionIndex = value;
// Select the newly-selected button
if (selectionIndex != -1)
InternalButtons[selectionIndex].Selected.Value = true;
}
public bool OnPressed(GlobalAction action)
{
switch (action)
{
case GlobalAction.SelectPrevious:
if (selectionIndex == -1 || selectionIndex == 0)
setSelected(InternalButtons.Count - 1);
else
setSelected(selectionIndex - 1);
InternalButtons.SelectPrevious();
return true;
case GlobalAction.SelectNext:
if (selectionIndex == -1 || selectionIndex == InternalButtons.Count - 1)
setSelected(0);
else
setSelected(selectionIndex + 1);
InternalButtons.SelectNext();
return true;
case GlobalAction.Back:
@ -241,9 +217,9 @@ namespace osu.Game.Screens.Play
private void buttonSelectionChanged(DialogButton button, bool isSelected)
{
if (!isSelected)
setSelected(-1);
InternalButtons.Deselect();
else
setSelected(InternalButtons.IndexOf(button));
InternalButtons.Select(button);
}
private void updateRetryCount()
@ -277,6 +253,46 @@ namespace osu.Game.Screens.Play
};
}
protected class ButtonContainer : FillFlowContainer<DialogButton>
{
private int selectedIndex = -1;
private void setSelected(int value)
{
if (selectedIndex == value)
return;
// Deselect the previously-selected button
if (selectedIndex != -1)
this[selectedIndex].Selected.Value = false;
selectedIndex = value;
// Select the newly-selected button
if (selectedIndex != -1)
this[selectedIndex].Selected.Value = true;
}
public void SelectNext()
{
if (selectedIndex == -1 || selectedIndex == Count - 1)
setSelected(0);
else
setSelected(selectedIndex + 1);
}
public void SelectPrevious()
{
if (selectedIndex == -1 || selectedIndex == 0)
setSelected(Count - 1);
else
setSelected(selectedIndex - 1);
}
public void Deselect() => setSelected(-1);
public void Select(DialogButton button) => setSelected(IndexOf(button));
}
private class Button : DialogButton
{
// required to ensure keyboard navigation always starts from an extremity (unless the cursor is moved)