using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; #nullable enable namespace Avalonia.Controls.Selection { internal class SelectedItems : IReadOnlyList { private readonly SelectionModel? _owner; private readonly ItemsSourceView? _items; private readonly IReadOnlyList? _ranges; public SelectedItems(SelectionModel owner) => _owner = owner; public SelectedItems(IReadOnlyList ranges, ItemsSourceView? items) { _ranges = ranges ?? throw new ArgumentNullException(nameof(ranges)); _items = items; } [MaybeNull] public T this[int index] { #pragma warning disable CS8766 get #pragma warning restore CS8766 { if (index >= Count) { throw new IndexOutOfRangeException("The index was out of range."); } if (_owner?.SingleSelect == true) { return _owner.SelectedItem; } else if (Items is object) { return Items[index]; } else { return default; } } } public int Count { get { if (_owner?.SingleSelect == true) { return _owner.SelectedIndex == -1 ? 0 : 1; } else { return Ranges is object ? IndexRange.GetCount(Ranges) : 0; } } } private ItemsSourceView? Items => _items ?? _owner?.ItemsView; private IReadOnlyList? Ranges => _ranges ?? _owner!.Ranges; public IEnumerator GetEnumerator() { if (_owner?.SingleSelect == true) { if (_owner.SelectedIndex >= 0) { #pragma warning disable CS8603 yield return _owner.SelectedItem; #pragma warning restore CS8603 } } else { var items = Items; foreach (var range in Ranges!) { for (var i = range.Begin; i <= range.End; ++i) { #pragma warning disable CS8603 yield return items is object ? items[i] : default; #pragma warning restore CS8603 } } } } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); public static SelectedItems? Create( IReadOnlyList? ranges, ItemsSourceView? items) { return ranges is object ? new SelectedItems(ranges, items) : null; } public class Untyped : IReadOnlyList { private readonly IReadOnlyList _source; public Untyped(IReadOnlyList source) => _source = source; public object? this[int index] => _source[index]; public int Count => _source.Count; IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); public IEnumerator GetEnumerator() { foreach (var i in _source) { yield return i; } } } } }