Improve mod cycling logic further

This commit is contained in:
Dean Herbert
2018-01-02 16:55:03 +09:00
parent f72239ef7a
commit 0e1b033008
2 changed files with 38 additions and 22 deletions

View File

@ -48,32 +48,27 @@ namespace osu.Game.Overlays.Mods
/// <summary> /// <summary>
/// Change the selected mod index of this button. /// Change the selected mod index of this button.
/// </summary> /// </summary>
/// <param name="value">The new index</param> /// <param name="newIndexhe new index</param>
/// <returns>Whether the selection changed.</returns> /// <returns>Whether the selection changed.</returns>
private bool changeSelectedIndex(int value) private bool changeSelectedIndex(int newIndex)
{ {
if (value == selectedIndex) return false; if (newIndex == selectedIndex) return false;
int direction = value < selectedIndex ? -1 : 1; int direction = newIndex < selectedIndex ? -1 : 1;
bool beforeSelected = Selected; bool beforeSelected = Selected;
Mod modBefore = SelectedMod ?? Mods[0]; Mod modBefore = SelectedMod ?? Mods[0];
if (value >= Mods.Length) if (newIndex >= Mods.Length)
selectedIndex = -1; newIndex = -1;
else if (value < -1) else if (newIndex < -1)
selectedIndex = Mods.Length - 1; newIndex = Mods.Length - 1;
else
selectedIndex = value;
Mod modAfter = SelectedMod ?? Mods[0]; if (newIndex >= 0 && !Mods[newIndex].HasImplementation)
if (!modAfter.HasImplementation)
{
if (modAfter != modBefore)
return changeSelectedIndex(selectedIndex + direction);
return false; return false;
}
selectedIndex = newIndex;
Mod modAfter = SelectedMod ?? Mods[0];
if (beforeSelected != Selected) if (beforeSelected != Selected)
{ {
@ -169,19 +164,40 @@ namespace osu.Game.Overlays.Mods
switch (args.Button) switch (args.Button)
{ {
case MouseButton.Left: case MouseButton.Left:
SelectNext(); SelectNext(1);
break; break;
case MouseButton.Right: case MouseButton.Right:
SelectPrevious(); SelectNext(-1);
break; break;
} }
return true; return true;
} }
public void SelectNext() => changeSelectedIndex(selectedIndex + 1); /// <summary>
/// Select the next available mod in a specified direction.
/// </summary>
/// <param name="direction">1 for forwards, -1 for backwards.</param>
public void SelectNext(int direction)
{
int start = selectedIndex + direction;
// wrap around if we are at an extremity.
if (start >= Mods.Length)
start = -1;
else if (start < -1)
start = Mods.Length - 1;
public void SelectPrevious() => changeSelectedIndex(selectedIndex - 1); for (int i = start; i < Mods.Length && i >= 0; i += direction)
{
if (Mods[i].HasImplementation)
{
changeSelectedIndex(i);
return;
}
}
Deselect();
}
public void Deselect() => changeSelectedIndex(-1); public void Deselect() => changeSelectedIndex(-1);

View File

@ -83,7 +83,7 @@ namespace osu.Game.Overlays.Mods
{ {
var index = Array.IndexOf(ToggleKeys, args.Key); var index = Array.IndexOf(ToggleKeys, args.Key);
if (index > -1 && index < buttons.Length) if (index > -1 && index < buttons.Length)
buttons[index].SelectNext(); buttons[index].SelectNext(state.Keyboard.ShiftPressed ? -1 : 1);
return base.OnKeyDown(state, args); return base.OnKeyDown(state, args);
} }