mirror of
https://github.com/osukey/osukey.git
synced 2025-07-01 08:20:00 +09:00
Port multiselection from previous design
This commit is contained in:
@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Padding = new MarginPadding(30),
|
Padding = new MarginPadding(30),
|
||||||
Child = new ModColumn(modType)
|
Child = new ModColumn(modType, false)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre
|
Origin = Anchor.Centre
|
||||||
@ -44,5 +44,20 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddStep("change ruleset to catch", () => Ruleset.Value = new CatchRuleset().RulesetInfo);
|
AddStep("change ruleset to catch", () => Ruleset.Value = new CatchRuleset().RulesetInfo);
|
||||||
AddStep("change ruleset to mania", () => Ruleset.Value = new ManiaRuleset().RulesetInfo);
|
AddStep("change ruleset to mania", () => Ruleset.Value = new ManiaRuleset().RulesetInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMultiSelection()
|
||||||
|
{
|
||||||
|
AddStep("create content", () => Child = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding(30),
|
||||||
|
Child = new ModColumn(ModType.DifficultyIncrease, true)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,8 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
if (allowBulkSelection)
|
if (allowBulkSelection)
|
||||||
{
|
{
|
||||||
controlContainer.Add(toggleAllCheckbox = new ToggleAllCheckbox
|
controlContainer.Height = 50;
|
||||||
|
controlContainer.Add(toggleAllCheckbox = new ToggleAllCheckbox(this)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
@ -218,9 +219,72 @@ namespace osu.Game.Overlays.Mods
|
|||||||
LoadComponentsAsync(panels, loaded =>
|
LoadComponentsAsync(panels, loaded =>
|
||||||
{
|
{
|
||||||
panelFlow.ChildrenEnumerable = loaded;
|
panelFlow.ChildrenEnumerable = loaded;
|
||||||
|
foreach (var panel in panelFlow)
|
||||||
|
panel.Active.BindValueChanged(_ => updateToggleState());
|
||||||
|
updateToggleState();
|
||||||
}, (cancellationTokenSource = new CancellationTokenSource()).Token);
|
}, (cancellationTokenSource = new CancellationTokenSource()).Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Bulk select / deselect
|
||||||
|
|
||||||
|
private const double initial_multiple_selection_delay = 120;
|
||||||
|
|
||||||
|
private double selectionDelay = initial_multiple_selection_delay;
|
||||||
|
private double lastSelection;
|
||||||
|
|
||||||
|
private readonly Queue<Action> pendingSelectionOperations = new Queue<Action>();
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
if (selectionDelay == initial_multiple_selection_delay || Time.Current - lastSelection >= selectionDelay)
|
||||||
|
{
|
||||||
|
if (pendingSelectionOperations.TryDequeue(out var dequeuedAction))
|
||||||
|
{
|
||||||
|
dequeuedAction();
|
||||||
|
|
||||||
|
// each time we play an animation, we decrease the time until the next animation (to ramp the visual and audible elements).
|
||||||
|
selectionDelay = Math.Max(30, selectionDelay * 0.8f);
|
||||||
|
lastSelection = Time.Current;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// reset the selection delay after all animations have been completed.
|
||||||
|
// this will cause the next action to be immediately performed.
|
||||||
|
selectionDelay = initial_multiple_selection_delay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateToggleState()
|
||||||
|
{
|
||||||
|
if (toggleAllCheckbox != null && pendingSelectionOperations.Count == 0)
|
||||||
|
toggleAllCheckbox.Current.Value = panelFlow.All(panel => panel.Active.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Selects all mods.
|
||||||
|
/// </summary>
|
||||||
|
public void SelectAll()
|
||||||
|
{
|
||||||
|
pendingSelectionOperations.Clear();
|
||||||
|
|
||||||
|
foreach (var button in panelFlow.Where(b => !b.Active.Value))
|
||||||
|
pendingSelectionOperations.Enqueue(() => button.Active.Value = true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deselects all mods.
|
||||||
|
/// </summary>
|
||||||
|
public void DeselectAll()
|
||||||
|
{
|
||||||
|
pendingSelectionOperations.Clear();
|
||||||
|
|
||||||
|
foreach (var button in panelFlow.Where(b => b.Active.Value))
|
||||||
|
pendingSelectionOperations.Enqueue(() => button.Active.Value = false);
|
||||||
|
}
|
||||||
|
|
||||||
private class ToggleAllCheckbox : OsuCheckbox
|
private class ToggleAllCheckbox : OsuCheckbox
|
||||||
{
|
{
|
||||||
private Color4 accentColour;
|
private Color4 accentColour;
|
||||||
@ -247,9 +311,12 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ToggleAllCheckbox()
|
private readonly ModColumn column;
|
||||||
|
|
||||||
|
public ToggleAllCheckbox(ModColumn column)
|
||||||
: base(false)
|
: base(false)
|
||||||
{
|
{
|
||||||
|
this.column = column;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ApplyLabelParameters(SpriteText text)
|
protected override void ApplyLabelParameters(SpriteText text)
|
||||||
@ -270,6 +337,16 @@ namespace osu.Game.Overlays.Mods
|
|||||||
Nub.GlowingAccentColour = AccentHoverColour;
|
Nub.GlowingAccentColour = AccentHoverColour;
|
||||||
Nub.GlowColour = AccentHoverColour.Opacity(0.2f);
|
Nub.GlowColour = AccentHoverColour.Opacity(0.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnUserChange(bool value)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
column.SelectAll();
|
||||||
|
else
|
||||||
|
column.DeselectAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user