Refactor gameplay menu overlay to fix regression

This commit is contained in:
Bartłomiej Dach 2020-08-15 13:36:00 +02:00
parent c1a9bf507a
commit a426ff1d5b

View File

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