// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. #nullable disable using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Screens.Edit.Compose.Components { /// /// A container for ordered by their start times. /// public sealed class HitObjectOrderedSelectionContainer : Container> { [Resolved] private EditorBeatmap editorBeatmap { get; set; } protected override void LoadComplete() { base.LoadComplete(); editorBeatmap.HitObjectUpdated += hitObjectUpdated; } private void hitObjectUpdated(HitObject _) => SortInternal(); public override void Add(SelectionBlueprint drawable) { SortInternal(); base.Add(drawable); } public override bool Remove(SelectionBlueprint drawable, bool disposeImmediately) { SortInternal(); return base.Remove(drawable, disposeImmediately); } protected override int Compare(Drawable x, Drawable y) { var xObj = ((SelectionBlueprint)x).Item; var yObj = ((SelectionBlueprint)y).Item; // Put earlier blueprints towards the end of the list, so they handle input first int result = yObj.StartTime.CompareTo(xObj.StartTime); if (result != 0) return result; // Fall back to end time if the start time is equal. result = yObj.GetEndTime().CompareTo(xObj.GetEndTime()); if (result != 0) return result; // As a final fallback, use combo information if available. if (xObj is IHasComboInformation xHasCombo && yObj is IHasComboInformation yHasCombo) { result = yHasCombo.ComboIndex.CompareTo(xHasCombo.ComboIndex); if (result != 0) return result; result = yHasCombo.IndexInCurrentCombo.CompareTo(xHasCombo.IndexInCurrentCombo); if (result != 0) return result; } return CompareReverseChildID(x, y); } protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); if (editorBeatmap != null) editorBeatmap.HitObjectUpdated -= hitObjectUpdated; } } }