private IEnumerable <int> IndexOfOverlap(SelectionRangeWithItems rangeWithItems) { if (rangeWithItems.IsEmpty) { yield break; } var targetRange = rangeWithItems.Range; var comparer = new RangeComparer(targetRange); var index = this.FindIndex(comparer); if (index < 0) { yield break; } while (index > 0) { if (comparer.Compare(m_sortedRanges[index - 1]) != 0) { break; } index--; } for (int i = index; i < m_sortedRanges.Count; i++) { var wrapper = m_sortedRanges[i]; if (comparer.Compare(wrapper) != 0) { break; } var currentRangeWithItems = wrapper.Value; var overlap = targetRange.Intersect(currentRangeWithItems.Range); if (!overlap.IsEmpty && (rangeWithItems.IsItemsEqual(overlap, currentRangeWithItems))) { yield return(wrapper.Index); } } }
public int Compare(SelectionRangeWithItemsWrapper item) { if (item == m_target) { return(0); } var xr = m_target.Value.Range; var yr = item.Value.Range; int xs, xe, ys, ye; ItemComparer.GetBounds(xr, out xs, out xe); ItemComparer.GetBounds(yr, out ys, out ye); if (xs < ys) { Debug.Assert(RangeComparer.Compare(xr, item) <= 0); return(-1); } else if (xs > ys) { Debug.Assert(RangeComparer.Compare(xr, item) >= 0); return(1); } Debug.Assert(RangeComparer.Compare(xr, item) == 0); if (xe < ye) { return(-1); } else if (xe > ye) { return(1); } Debug.Assert(xr == yr); return(m_target.Index - item.Index); }
public int Compare(SelectionRangeWithItemsWrapper item) { return(RangeComparer.Compare(m_target, item)); }
public void OffsetIndex(int startIndex, int offset) { if (m_sortedRanges.Count == 0) { return; } // Used to offset index after an add or remove from the data source of the grid. var offsetRange = new SelectionRange(startIndex, startIndex + System.Math.Abs(offset) - 1); var comparer = new RangeComparer(offsetRange); // Find the first range that is greater or that overlaps the target range. var index = this.FindIndex(comparer); if (index < 0) { index = ~index; } else { while (index > 0) { if (comparer.Compare(m_sortedRanges[index - 1]) != 0) { break; } index--; } } var matches = m_sortedRanges.Skip(index).OrderByDescending(item => item.Index).ToList(); // Adjust the range of all ranges greater or that overlaps the target range. foreach (var currentRangeWithItemsWrapper in matches) { Debug.Assert(comparer.Compare(currentRangeWithItemsWrapper) <= 0); var currentRangeIndex = currentRangeWithItemsWrapper.Index; var currentRangeWithItems = currentRangeWithItemsWrapper.Value; var currentRange = currentRangeWithItems.Range; var currentRangeItems = currentRangeWithItems.Items; Debug.Assert(!(offsetRange > currentRange)); var currentRangeIntersection = currentRange.Intersect(offsetRange); // The range overlaps. if (!currentRangeIntersection.IsEmpty) { // Should only happen when adding since when we remove data from the source, we remove the // the range from the list. Debug.Assert(offset > 0); SelectionRange topRange; SelectionRange bottomRange; if (currentRange.StartIndex > currentRange.EndIndex) { if (currentRangeIntersection.EndIndex == currentRange.EndIndex) { this[currentRangeIndex] = new SelectionRangeWithItems( new SelectionRange(currentRange.StartIndex + offset, currentRange.EndIndex + offset), currentRangeItems); continue; } else { topRange = new SelectionRange(currentRange.StartIndex + offset, startIndex + offset); bottomRange = new SelectionRange(startIndex - 1, currentRange.EndIndex); } } else { if (currentRangeIntersection.StartIndex == currentRange.StartIndex) { this[currentRangeIndex] = new SelectionRangeWithItems( new SelectionRange(currentRange.StartIndex + offset, currentRange.EndIndex + offset), currentRangeItems); continue; } else { topRange = new SelectionRange(currentRange.StartIndex, startIndex - 1); bottomRange = new SelectionRange(startIndex + offset, currentRange.EndIndex + offset); } } object[] topItems = null; object[] bottomItems = null; if (currentRangeItems != null) { topItems = new object[topRange.Length]; Array.Copy(currentRangeItems, 0, topItems, 0, topItems.Length); bottomItems = new object[bottomRange.Length]; Array.Copy(currentRangeItems, topItems.Length, bottomItems, 0, bottomItems.Length); } this[currentRangeIndex] = new SelectionRangeWithItems(topRange, topItems); this.Insert(currentRangeIndex + 1, new SelectionRangeWithItems(bottomRange, bottomItems), true); } // The range is greater. else { this[currentRangeIndex] = new SelectionRangeWithItems( new SelectionRange(currentRange.StartIndex + offset, currentRange.EndIndex + offset), currentRangeItems); } } }