diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index dfe9dc9dd8..370eb37d16 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; +using System.Text.RegularExpressions; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -219,5 +220,40 @@ namespace osu.Game.Rulesets.Catch.Edit distanceSnapGrid.StartTime = sourceHitObject.GetEndTime(); distanceSnapGrid.StartX = sourceHitObject.EffectiveX; } + + #region Clipboard handling + + public override string ConvertSelectionToString() + => string.Join(',', EditorBeatmap.SelectedHitObjects.Cast().OrderBy(h => h.StartTime).Select(h => (h.IndexInCurrentCombo + 1).ToString())); + + // 1,2,3,4 ... + private static readonly Regex selection_regex = new Regex(@"^\d+(,\d+)*$", RegexOptions.Compiled); + + public override void SelectFromTimestamp(double timestamp, string objectDescription) + { + if (!selection_regex.IsMatch(objectDescription)) + return; + + List remainingHitObjects = EditorBeatmap.HitObjects.Cast().Where(h => h.StartTime >= timestamp).ToList(); + string[] splitDescription = objectDescription.Split(','); + + for (int i = 0; i < splitDescription.Length; i++) + { + if (!int.TryParse(splitDescription[i], out int combo) || combo < 1) + continue; + + CatchHitObject? current = remainingHitObjects.FirstOrDefault(h => h.IndexInCurrentCombo + 1 == combo); + + if (current == null) + continue; + + EditorBeatmap.SelectedHitObjects.Add(current); + + if (i < splitDescription.Length - 1) + remainingHitObjects = remainingHitObjects.Where(h => h != current && h.StartTime >= current.StartTime).ToList(); + } + } + + #endregion } }