diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/NodeSamplePointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/NodeSamplePointPiece.cs new file mode 100644 index 0000000000..dc91401c13 --- /dev/null +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/NodeSamplePointPiece.cs @@ -0,0 +1,54 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Audio; +using osu.Game.Graphics; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using osuTK.Graphics; + +namespace osu.Game.Screens.Edit.Compose.Components.Timeline +{ + public partial class NodeSamplePointPiece : SamplePointPiece + { + public readonly int NodeIndex; + + public NodeSamplePointPiece(HitObject hitObject, int nodeIndex) + : base(hitObject) + { + if (hitObject is not IHasRepeats) + throw new System.ArgumentException($"HitObject must implement {nameof(IHasRepeats)}", nameof(hitObject)); + + NodeIndex = nodeIndex; + } + + protected override Color4 GetRepresentingColour(OsuColour colours) => colours.Purple; + + protected override IList GetSamples() + { + var hasRepeats = (IHasRepeats)HitObject; + return NodeIndex < hasRepeats.NodeSamples.Count ? hasRepeats.NodeSamples[NodeIndex] : HitObject.Samples; + } + + public override Popover GetPopover() => new NodeSampleEditPopover(HitObject); + + public partial class NodeSampleEditPopover : SampleEditPopover + { + private readonly int nodeIndex; + + protected override IList GetSamples(HitObject ho) + { + var hasRepeats = (IHasRepeats)ho; + return nodeIndex < hasRepeats.NodeSamples.Count ? hasRepeats.NodeSamples[nodeIndex] : ho.Samples; + } + + public NodeSampleEditPopover(HitObject hitObject, int nodeIndex = 0) + : base(hitObject) + { + this.nodeIndex = nodeIndex; + } + } + } +} diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs index 4f3526b531..064e96c255 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs @@ -48,7 +48,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void updateText() { - Label.Text = $"{GetBankValue(HitObject.Samples)} {GetVolumeValue(HitObject.Samples)}"; + Label.Text = $"{GetBankValue(GetSamples())} {GetVolumeValue(GetSamples())}"; } public static string? GetBankValue(IEnumerable samples) @@ -61,7 +61,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline return samples.Count == 0 ? 0 : samples.Max(o => o.Volume); } - public Popover GetPopover() => new SampleEditPopover(HitObject); + protected virtual IList GetSamples() => HitObject.Samples; + + public virtual Popover GetPopover() => new SampleEditPopover(HitObject); public partial class SampleEditPopover : OsuPopover { @@ -70,6 +72,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private LabelledTextBox bank = null!; private IndeterminateSliderWithTextBoxInput volume = null!; + protected virtual IList GetSamples(HitObject ho) => ho.Samples; + [Resolved(canBeNull: true)] private EditorBeatmap beatmap { get; set; } = null!; @@ -112,7 +116,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline // if the piece belongs to a currently selected object, assume that the user wants to change all selected objects. // if the piece belongs to an unselected object, operate on that object alone, independently of the selection. var relevantObjects = (beatmap.SelectedHitObjects.Contains(hitObject) ? beatmap.SelectedHitObjects : hitObject.Yield()).ToArray(); - var relevantSamples = relevantObjects.Select(h => h.Samples).ToArray(); + var relevantSamples = relevantObjects.Select(GetSamples).ToArray(); // even if there are multiple objects selected, we can still display sample volume or bank if they all have the same value. string? commonBank = getCommonBank(relevantSamples);