src/Misc/EFTools/DesignXmlCore/VirtualTreeGrid/UI/VirtualTreeSelection.cs
/// <summary>
///     Selects/deselects the given range.
/// </summary>
Selects/deselects the given range.
Selects / deselects the given range .
private void SetSelectionRange(int startIndex, int endIndex, bool select)
        {
            if (mySelectedRanges == null)
            {
                mySelectedRanges = new List<SelectionRange>();
            }
            if (select)
            {
                var newRange = new SelectionRange(startIndex, endIndex);
                int startPos;
                int endPos;
                for (startPos = 0; startPos < mySelectedRanges.Count; startPos++)
                {
                    var range = mySelectedRanges[startPos];
                    if (newRange.StartIndex - 1 <= range.EndIndex)
                    {
                        newRange.StartIndex = Math.Min(range.StartIndex, newRange.StartIndex);
                        break;
                    }
                }
                for (endPos = mySelectedRanges.Count; --endPos >= startPos;)
                {
                    var range = mySelectedRanges[endPos];
                    if (newRange.EndIndex + 1 >= range.StartIndex)
                    {
                        newRange.EndIndex = Math.Max(range.EndIndex, newRange.EndIndex);
                        break;
                    }
                }
                if (endPos < mySelectedRanges.Count)
                {
                    for (var pos = endPos; pos >= startPos; pos--)
                    {
                        var range = mySelectedRanges[pos];
                        if ((newRange.StartIndex <= range.StartIndex)
                            && (newRange.EndIndex >= range.EndIndex))
                        {
                            mySelectedRanges.RemoveAt(pos);
                        }
                    }
                }
                mySelectedRanges.Insert(startPos, newRange);
                InvalidateItem(
                    startIndex, -1, NativeMethods.RedrawWindowFlags.Invalidate | NativeMethods.RedrawWindowFlags.Erase,
                    (endIndex - startIndex) + 1);
            }
            else
            {
                for (var i = 0; i < mySelectedRanges.Count; i++)
                {
                    var currentRange = mySelectedRanges[i];
                    if (currentRange.StartIndex > endIndex)
                    {
                        break;
                    }
                    if (startIndex > currentRange.StartIndex
                        && endIndex < currentRange.EndIndex)
                    {
                        mySelectedRanges[i] = new SelectionRange(currentRange.StartIndex, startIndex - 1);
                        mySelectedRanges.Insert(i + 1, new SelectionRange(endIndex + 1, currentRange.EndIndex));
                        InvalidateItem(
                            startIndex, -1, NativeMethods.RedrawWindowFlags.Invalidate | NativeMethods.RedrawWindowFlags.Erase,
                            (endIndex - startIndex) + 1);
                        break; 
                    }
                    if (startIndex <= currentRange.StartIndex
                        && endIndex >= currentRange.EndIndex)
                    {
                        mySelectedRanges.RemoveAt(i--);
                        InvalidateItem(
                            currentRange.StartIndex, -1, NativeMethods.RedrawWindowFlags.Invalidate | NativeMethods.RedrawWindowFlags.Erase,
                            (currentRange.EndIndex - currentRange.StartIndex) + 1);
                        continue; 
                    }
                    if (startIndex <= currentRange.StartIndex
                        && endIndex >= currentRange.StartIndex)
                    {
                        InvalidateItem(
                            currentRange.StartIndex, -1, NativeMethods.RedrawWindowFlags.Invalidate | NativeMethods.RedrawWindowFlags.Erase,
                            (endIndex - currentRange.StartIndex) + 1);
                        currentRange.StartIndex = endIndex + 1;
                        mySelectedRanges[i] = currentRange;
                    }
                    else if (startIndex <= currentRange.EndIndex
                             && endIndex >= currentRange.EndIndex)
                    {
                        InvalidateItem(
                            startIndex, -1, NativeMethods.RedrawWindowFlags.Invalidate | NativeMethods.RedrawWindowFlags.Erase,
                            (currentRange.EndIndex - startIndex) + 1);
                        currentRange.EndIndex = startIndex - 1;
                        mySelectedRanges[i] = currentRange;
                    }
                }
            }
        }
private void SetSelectionRange ( int startIndex , int endIndex , bool select ) { if ( mySelectedRanges == null ) { mySelectedRanges = new List < SelectionRange > ( ) ; } if ( select ) { var newRange = new SelectionRange ( startIndex , endIndex ) ; int startPos ; int endPos ; for ( startPos = 0 ; startPos < mySelectedRanges . Count ; startPos ++ ) { var range = mySelectedRanges [ startPos ] ; if ( newRange . StartIndex - 1 <= range . EndIndex ) { newRange . StartIndex = Math . Min ( range . StartIndex , newRange . StartIndex ) ; break ; } } for ( endPos = mySelectedRanges . Count ; -- endPos >= startPos ; ) { var range = mySelectedRanges [ endPos ] ; if ( newRange . EndIndex + 1 >= range . StartIndex ) { newRange . EndIndex = Math . Max ( range . EndIndex , newRange . EndIndex ) ; break ; } } if ( endPos < mySelectedRanges . Count ) { for ( var pos = endPos ; pos >= startPos ; pos -- ) { var range = mySelectedRanges [ pos ] ; if ( ( newRange . StartIndex <= range . StartIndex ) && ( newRange . EndIndex >= range . EndIndex ) ) { mySelectedRanges . RemoveAt ( pos ) ; } } } mySelectedRanges . Insert ( startPos , newRange ) ; InvalidateItem ( startIndex , - 1 , NativeMethods . RedrawWindowFlags . Invalidate | NativeMethods . RedrawWindowFlags . Erase , ( endIndex - startIndex ) + 1 ) ; } else { for ( var i = 0 ; i < mySelectedRanges . Count ; i ++ ) { var currentRange = mySelectedRanges [ i ] ; if ( currentRange . StartIndex > endIndex ) { break ; } if ( startIndex > currentRange . StartIndex && endIndex < currentRange . EndIndex ) { mySelectedRanges [ i ] = new SelectionRange ( currentRange . StartIndex , startIndex - 1 ) ; mySelectedRanges . Insert ( i + 1 , new SelectionRange ( endIndex + 1 , currentRange . EndIndex ) ) ; InvalidateItem ( startIndex , - 1 , NativeMethods . RedrawWindowFlags . Invalidate | NativeMethods . RedrawWindowFlags . Erase , ( endIndex - startIndex ) + 1 ) ; break ; } if ( startIndex <= currentRange . StartIndex && endIndex >= currentRange . EndIndex ) { mySelectedRanges . RemoveAt ( i -- ) ; InvalidateItem ( currentRange . StartIndex , - 1 , NativeMethods . RedrawWindowFlags . Invalidate | NativeMethods . RedrawWindowFlags . Erase , ( currentRange . EndIndex - currentRange . StartIndex ) + 1 ) ; continue ; } if ( startIndex <= currentRange . StartIndex && endIndex >= currentRange . StartIndex ) { InvalidateItem ( currentRange . StartIndex , - 1 , NativeMethods . RedrawWindowFlags . Invalidate | NativeMethods . RedrawWindowFlags . Erase , ( endIndex - currentRange . StartIndex ) + 1 ) ; currentRange . StartIndex = endIndex + 1 ; mySelectedRanges [ i ] = currentRange ; } else if ( startIndex <= currentRange . EndIndex && endIndex >= currentRange . EndIndex ) { InvalidateItem ( startIndex , - 1 , NativeMethods . RedrawWindowFlags . Invalidate | NativeMethods . RedrawWindowFlags . Erase , ( currentRange . EndIndex - startIndex ) + 1 ) ; currentRange . EndIndex = startIndex - 1 ; mySelectedRanges [ i ] = currentRange ; } } } }
Selects/deselects the given range.
Selects / deselects the given range .
// algorithm for selection case: // 1. expand newRange to first overlapping or contiguous range // 2. expand newRange to last overlapping or contiguous range // 3. collapse overlapping ranges // expand newRange to first overlapping or contiguous range // expand newRange to last overlapping or contiguous range // collapse overlapping ranges // store new range // invalidate entire selected area. // algorithm for deselection case.  For each range: // 1.  If contains new range (exclusive), split existing range into two. // 2.  If contained by new range (inclusive), discard. // 3.  If start index or end index fall within new range, adjust accordingly. // Note: we're a bit more careful about invalidating only the necessary regions here, because SetCurrentExtendedMultiSelectIndex // deselects large item ranges. // finished, we've accounted for entire range. // keep going, there may be additional ranges to modify
startIndex
int
endIndex
int
select
bool