1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-19 10:00:42 +08:00
Files
osu-lazer/osu.Game/Screens/Edit/Setup/FormSampleSetChooser.cs
T

149 lines
4.8 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.Globalization;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Localisation;
namespace osu.Game.Screens.Edit.Setup
{
public partial class FormSampleSetChooser : FormDropdown<EditorBeatmapSkin.SampleSet?>, IHasPopover
{
private EditorBeatmapSkin? beatmapSkin;
public FormSampleSetChooser()
{
Caption = EditorSetupStrings.CustomSampleSets;
}
[BackgroundDependencyLoader]
private void load(EditorBeatmap editorBeatmap)
{
beatmapSkin = editorBeatmap.BeatmapSkin;
}
protected override void LoadComplete()
{
base.LoadComplete();
populateItems();
if (beatmapSkin != null)
beatmapSkin.BeatmapSkinChanged += scheduleItemPopulation;
Current.Value = Items.First(i => i?.SampleSetIndex > 0);
Current.BindValueChanged(val =>
{
if (val.NewValue?.SampleSetIndex == -1)
this.ShowPopover();
});
}
private void populateItems()
{
var items = beatmapSkin?.GetAvailableSampleSets().ToList() ?? [new EditorBeatmapSkin.SampleSet(1)];
items.Add(new EditorBeatmapSkin.SampleSet(-1, "Add new..."));
Items = items;
}
private void scheduleItemPopulation() => Schedule(populateItems);
protected override LocalisableString GenerateItemText(EditorBeatmapSkin.SampleSet? item)
{
if (item == null)
return string.Empty;
return base.GenerateItemText(item);
}
public Popover GetPopover() => new NewSampleSetPopover(
Items.Any(i => i?.SampleSetIndex > 0) ? Items.Max(i => i!.SampleSetIndex) : 0,
idx =>
{
if (idx == null)
{
Current.Value = Items.FirstOrDefault(i => i?.SampleSetIndex > 0);
return;
}
if (Items.SingleOrDefault(i => i?.SampleSetIndex == idx) is EditorBeatmapSkin.SampleSet existing)
{
Current.Value = existing;
return;
}
var sampleSet = new EditorBeatmapSkin.SampleSet(idx.Value, $@"Custom #{idx}");
var newItems = Items.ToList();
newItems.Insert(newItems.Count - 1, sampleSet);
Items = newItems;
Current.Value = sampleSet;
});
protected override void Dispose(bool isDisposing)
{
if (beatmapSkin != null)
beatmapSkin.BeatmapSkinChanged -= scheduleItemPopulation;
base.Dispose(isDisposing);
}
private partial class NewSampleSetPopover : OsuPopover
{
private readonly int currentLargestIndex;
private readonly Action<int?> onCommit;
private int? committedIndex;
private LabelledNumberBox numberBox = null!;
public NewSampleSetPopover(int currentLargestIndex, Action<int?> onCommit)
{
this.currentLargestIndex = currentLargestIndex;
this.onCommit = onCommit;
}
[BackgroundDependencyLoader]
private void load()
{
Child = numberBox = new LabelledNumberBox
{
RelativeSizeAxes = Axes.None,
Width = 250,
Label = "Sample set index",
Current = { Value = (currentLargestIndex + 1).ToString(CultureInfo.InvariantCulture) }
};
numberBox.OnCommit += (_, _) =>
{
if (int.TryParse(numberBox.Current.Value, out int parsed))
committedIndex = parsed;
Hide();
};
}
protected override void OnFocus(FocusEvent e)
{
base.OnFocus(e);
// avoids infinite refocus loop
if (committedIndex == null)
GetContainingFocusManager()?.ChangeFocus(numberBox);
}
public override void Hide()
{
if (State.Value == Visibility.Visible)
onCommit.Invoke(committedIndex > 0 ? committedIndex : null);
base.Hide();
}
}
}
}