mirror of
https://github.com/ppy/osu.git
synced 2025-03-21 17:17:20 +08:00
Centralise selection animation logic
This commit is contained in:
parent
4bfe3aabdc
commit
f23ca7c7cf
@ -33,6 +33,8 @@ namespace osu.Game.Overlays.Mods
|
||||
|
||||
private CancellationTokenSource modsLoadCts;
|
||||
|
||||
protected bool SelectionAnimationRunning => pendingSelectionOperations.Count > 0;
|
||||
|
||||
/// <summary>
|
||||
/// True when all mod icons have completed loading.
|
||||
/// </summary>
|
||||
@ -49,7 +51,11 @@ namespace osu.Game.Overlays.Mods
|
||||
|
||||
return new ModButton(m)
|
||||
{
|
||||
SelectionChanged = Action,
|
||||
SelectionChanged = mod =>
|
||||
{
|
||||
ModButtonStateChanged(mod);
|
||||
Action?.Invoke(mod);
|
||||
},
|
||||
};
|
||||
}).ToArray();
|
||||
|
||||
@ -78,6 +84,10 @@ namespace osu.Game.Overlays.Mods
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void ModButtonStateChanged(Mod mod)
|
||||
{
|
||||
}
|
||||
|
||||
private ModButton[] buttons = Array.Empty<ModButton>();
|
||||
|
||||
protected override bool OnKeyDown(KeyDownEvent e)
|
||||
@ -94,44 +104,53 @@ namespace osu.Game.Overlays.Mods
|
||||
return base.OnKeyDown(e);
|
||||
}
|
||||
|
||||
private const double initial_multiple_selection_delay = 100;
|
||||
|
||||
private readonly Queue<Action> pendingSelectionOperations = new Queue<Action>();
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
Scheduler.AddDelayed(() =>
|
||||
{
|
||||
if (pendingSelectionOperations.TryDequeue(out var dequeuedAction))
|
||||
dequeuedAction();
|
||||
}, initial_multiple_selection_delay, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects all mods.
|
||||
/// </summary>
|
||||
public void SelectAll()
|
||||
{
|
||||
pendingSelectionOperations.Clear();
|
||||
|
||||
foreach (var button in buttons.Where(b => !b.Selected))
|
||||
button.SelectAt(0);
|
||||
pendingSelectionOperations.Enqueue(() => button.SelectAt(0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deselects all mods.
|
||||
/// </summary>
|
||||
/// <param name="immediate">Set to true to bypass animations and update selections immediately.</param>
|
||||
public void DeselectAll(bool immediate = false) => DeselectTypes(buttons.Select(b => b.SelectedMod?.GetType()).Where(t => t != null), immediate);
|
||||
public void DeselectAll() => DeselectTypes(buttons.Select(b => b.SelectedMod?.GetType()).Where(t => t != null));
|
||||
|
||||
/// <summary>
|
||||
/// Deselect one or more mods in this section.
|
||||
/// </summary>
|
||||
/// <param name="modTypes">The types of <see cref="Mod"/>s which should be deselected.</param>
|
||||
/// <param name="immediate">Set to true to bypass animations and update selections immediately.</param>
|
||||
public void DeselectTypes(IEnumerable<Type> modTypes, bool immediate = false)
|
||||
public void DeselectTypes(IEnumerable<Type> modTypes)
|
||||
{
|
||||
int delay = 0;
|
||||
pendingSelectionOperations.Clear();
|
||||
|
||||
foreach (var button in buttons)
|
||||
{
|
||||
Mod selected = button.SelectedMod;
|
||||
if (selected == null) continue;
|
||||
if (button.SelectedMod == null) continue;
|
||||
|
||||
foreach (var type in modTypes)
|
||||
{
|
||||
if (type.IsInstanceOfType(selected))
|
||||
{
|
||||
if (immediate)
|
||||
button.Deselect();
|
||||
else
|
||||
Scheduler.AddDelayed(button.Deselect, delay += 50);
|
||||
}
|
||||
if (type.IsInstanceOfType(button.SelectedMod))
|
||||
pendingSelectionOperations.Enqueue(button.Deselect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Backgrounds;
|
||||
using osu.Game.Graphics.Containers;
|
||||
|
@ -12,7 +12,7 @@ namespace osu.Game.Overlays.Mods
|
||||
base.OnModSelected(mod);
|
||||
|
||||
foreach (var section in ModSectionsContainer.Children)
|
||||
section.DeselectTypes(mod.IncompatibleMods, true);
|
||||
section.DeselectTypes(mod.IncompatibleMods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection.Emit;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
@ -72,7 +71,7 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
private void deselectAll()
|
||||
{
|
||||
foreach (var section in ModSectionsContainer.Children)
|
||||
section.DeselectAll(true);
|
||||
section.DeselectAll();
|
||||
}
|
||||
|
||||
protected override ModSection CreateModSection(ModType type) => new FreeModSection(type);
|
||||
@ -99,21 +98,21 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
|
||||
private void onCheckboxChanged(bool value)
|
||||
{
|
||||
foreach (var button in ButtonsContainer.OfType<ModButton>())
|
||||
{
|
||||
if (value)
|
||||
button.SelectAt(0);
|
||||
else
|
||||
button.Deselect();
|
||||
}
|
||||
if (value)
|
||||
SelectAll();
|
||||
else
|
||||
DeselectAll();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
protected override void ModButtonStateChanged(Mod mod)
|
||||
{
|
||||
base.Update();
|
||||
base.ModButtonStateChanged(mod);
|
||||
|
||||
var validButtons = ButtonsContainer.OfType<ModButton>().Where(b => b.Mod.HasImplementation);
|
||||
checkbox.Current.Value = validButtons.All(b => b.Selected);
|
||||
if (!SelectionAnimationRunning)
|
||||
{
|
||||
var validButtons = ButtonsContainer.OfType<ModButton>().Where(b => b.Mod.HasImplementation);
|
||||
checkbox.Current.Value = validButtons.All(b => b.Selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user