Example #1
0
        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);
                }
            }
        }
Example #2
0
            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);
            }
Example #3
0
 public int Compare(SelectionRangeWithItemsWrapper item)
 {
     return(RangeComparer.Compare(m_target, item));
 }
Example #4
0
        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);
                }
            }
        }