1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-18 14:50:54 +08:00
Files
osu-lazer/osu.Game/Overlays/Mods/ModPresetColumn.cs
T
nil 85b8480e46 Fix two mod presets having key binding of 1 (#36563)
Fixes #36562 

Currently there exists a bug where the mod preset hotkeys will wrap
outside of the intended bounds.

Fix is making sure the preset index is < 10

Before:
<img width="486" height="358" alt="image"
src="https://github.com/user-attachments/assets/77f1ca9e-4fd0-4b29-b9f5-f53e652db42d"
/>

After:
<img width="1007" height="1295" alt="image"
src="https://github.com/user-attachments/assets/ca81cc39-2f86-462c-a26b-002aceed77f4"
/>
2026-02-02 00:42:49 +09:00

139 lines
4.3 KiB
C#

// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Input.Events;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Localisation;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osuTK;
using osuTK.Input;
using Realms;
namespace osu.Game.Overlays.Mods
{
public partial class ModPresetColumn : ModSelectColumn
{
[Resolved]
private RealmAccess realm { get; set; } = null!;
[Resolved]
private IBindable<RulesetInfo> ruleset { get; set; } = null!;
private const float contracted_width = WIDTH - 120;
private readonly Key[] toggleKeys = { Key.Number1, Key.Number2, Key.Number3, Key.Number4, Key.Number5, Key.Number6, Key.Number7, Key.Number8, Key.Number9, Key.Number0 };
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
AccentColour = colours.Orange1;
HeaderText = ModSelectOverlayStrings.PersonalPresets;
AddPresetButton addPresetButton;
ItemsFlow.Add(addPresetButton = new AddPresetButton());
ItemsFlow.SetLayoutPosition(addPresetButton, float.PositiveInfinity);
}
protected override void LoadComplete()
{
base.LoadComplete();
ruleset.BindValueChanged(_ => rulesetChanged(), true);
Width = contracted_width;
}
private IDisposable? presetSubscription;
private void rulesetChanged()
{
presetSubscription?.Dispose();
presetSubscription = realm.RegisterForNotifications(r =>
r.All<ModPreset>()
.Filter($"{nameof(ModPreset.Ruleset)}.{nameof(RulesetInfo.ShortName)} == $0"
+ $" && {nameof(ModPreset.DeletePending)} == false", ruleset.Value.ShortName)
.OrderBy(preset => preset.Name), asyncLoadPanels);
}
private CancellationTokenSource? cancellationTokenSource;
private Task? latestLoadTask;
internal bool ItemsLoaded => latestLoadTask?.IsCompleted == true;
private void asyncLoadPanels(IRealmCollection<ModPreset> presets, ChangeSet? changes)
{
cancellationTokenSource?.Cancel();
bool hasPresets = presets.Any();
this.ResizeWidthTo(hasPresets ? WIDTH : contracted_width, 200, Easing.OutQuint);
if (!hasPresets)
{
removeAndDisposePresetPanels();
return;
}
var panels = new List<ModPresetPanel>();
for (int i = 0; i < presets.Count; i++)
{
var preset = presets[i];
panels.Add(new ModPresetPanel(preset.ToLive(realm))
{
Index = i < 10 ? (i + 1) % 10 : null,
Shear = Vector2.Zero
});
}
latestLoadTask = LoadComponentsAsync(panels, loaded =>
{
removeAndDisposePresetPanels();
ItemsFlow.AddRange(loaded);
}, (cancellationTokenSource = new CancellationTokenSource()).Token);
void removeAndDisposePresetPanels()
{
foreach (var panel in ItemsFlow.OfType<ModPresetPanel>().ToArray())
panel.RemoveAndDisposeImmediately();
}
}
protected override bool OnKeyDown(KeyDownEvent e)
{
if (e.ControlPressed || e.AltPressed || e.SuperPressed || e.Repeat)
return false;
int index = Array.IndexOf(toggleKeys, e.Key);
if (index < 0)
return false;
var panel = ItemsFlow.OfType<ModPresetPanel>().ElementAtOrDefault(index);
if (panel == null)
return false;
panel.Toggle();
return true;
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
presetSubscription?.Dispose();
}
}
}