int _IndexOfCumulatedDistance(double cumulatedDistance) { if (InternalCount == 0) { return((int)Math.Floor(cumulatedDistance / DefaultDistance)); } int delta = 0; double internalTotalDistance = InternalTotalDistance - this.paddingDistance; if (cumulatedDistance >= internalTotalDistance) { delta = (int)Math.Floor((cumulatedDistance - internalTotalDistance) / DefaultDistance); cumulatedDistance = internalTotalDistance; return(InternalCount + delta); } var searchPosition = new DistanceLineCounter(cumulatedDistance, 0); DistanceLineCounterEntry rbEntry = rbTree.GetEntryAtCounterPosition(searchPosition, DistanceLineCounterKind.Distance, false); DistanceLineCounterSource rbValue = rbEntry.Value; DistanceLineCounter rbEntryPosition = rbEntry.GetCounterPosition(); if (rbValue.SingleLineDistance > 0) { delta = (int)Math.Floor((cumulatedDistance - rbEntryPosition.Distance) / rbValue.SingleLineDistance); } return(rbEntryPosition.LineCount + delta); }
/// <summary> /// Assigns a collection with nested entities to an item. /// </summary> /// <param name="index">The index.</param> /// <param name="nestedCollection">The nested collection.</param> public void SetNestedDistances(int index, IDistanceCounterCollection nestedCollection) { CheckRange("index", 0, Count - 1, index); if (GetNestedDistances(index) != nestedCollection) { if (index >= InternalCount) { EnsureTreeCount(index + 1); } DistanceLineCounterEntry entry = Split(index); Split(index + 1); if (nestedCollection != null) { var vcs = new NestedDistanceCounterCollectionSource(this, nestedCollection, entry); entry.Value = vcs; } else { entry.Value = new DistanceLineCounterSource(0, 1); } entry.InvalidateCounterBottomUp(true); } }
/// <summary> /// Insert entities in the collection. /// </summary> /// <param name="insertAt">Insert position.</param> /// <param name="count">The number of entities to be inserted.</param> /// <param name="distance">The distance to be set.</param> public void Insert(int insertAt, int count, double distance) { Count += count; if (insertAt >= InternalCount && distance == defaultDistance) { return; } EnsureTreeCount(insertAt); LineIndexEntryAt e = InitDistanceLine(insertAt, false); if (e.rbValue.SingleLineDistance == distance) { e.rbValue.LineCount += count; e.rbEntry.InvalidateCounterBottomUp(true); } else { DistanceLineCounterEntry rbEntry0 = Split(insertAt); DistanceLineCounterEntry entry = CreateTreeTableEntry(distance, count); if (rbEntry0 == null) { rbTree.Add(entry); } else { rbTree.Insert(rbTree.IndexOf(rbEntry0), entry); } //entry.InvalidateCounterBottomUp(true); Merge(entry, true); } }
int RemoveHelper(int removeAt, int count) { if (removeAt >= InternalCount) { return(rbTree.GetCount()); } DistanceLineCounterEntry entry = Split(removeAt); Split(removeAt + count); int n = rbTree.IndexOf(entry); var toDelete = new List <DistanceLineCounterEntry>(); int total = 0; while (total < count && entry != null) { total += entry.Value.LineCount; toDelete.Add(entry); entry = rbTree.GetNextEntry(entry); } for (int l = 0; l < toDelete.Count; l++) { //toDelete[l].InvalidateCounterBottomUp(true); rbTree.Remove(toDelete[l]); } return(n); }
DistanceLineCounterEntry Split(int index) { if (index >= InternalCount) { return(null); } LineIndexEntryAt e = InitDistanceLine(index, true); if (e.rbEntryPosition.LineCount != index) { int count1 = index - e.rbEntryPosition.LineCount; int count2 = e.rbValue.LineCount - count1; e.rbValue.LineCount = count1; DistanceLineCounterEntry rbEntry2 = CreateTreeTableEntry(e.rbValue.SingleLineDistance, count2); rbTree.Insert(rbTree.IndexOf(e.rbEntry) + 1, rbEntry2); //rbEntry2.InvalidateCounterBottomUp(true); e.rbEntry.InvalidateCounterBottomUp(true); return(rbEntry2); } return(e.rbEntry); }
void Merge(DistanceLineCounterEntry entry, bool checkPrevious) { DistanceLineCounterSource value = entry.Value; DistanceLineCounterEntry previousEntry = null; if (checkPrevious) { previousEntry = rbTree.GetPreviousEntry(entry); } DistanceLineCounterEntry nextEntry = rbTree.GetNextEntry(entry); bool dirty = false; if (previousEntry != null && (previousEntry.Value).SingleLineDistance == value.SingleLineDistance) { value.LineCount += (previousEntry.Value).LineCount; //previousEntry.InvalidateCounterBottomUp(true); rbTree.Remove(previousEntry); dirty = true; } if (nextEntry != null && (nextEntry.Value).SingleLineDistance == value.SingleLineDistance) { value.LineCount += (nextEntry.Value).LineCount; //nextEntry.InvalidateCounterBottomUp(true); rbTree.Remove(nextEntry); dirty = true; } if (dirty) { entry.InvalidateCounterBottomUp(true); } }
/// <summary> /// Hides a specified range of entities (lines, rows or colums) /// </summary> /// <param name="from">The index for the first entity></param> /// <param name="to">The raw index for the last entity</param> /// <param name="distance">The distance.</param> public void SetRange(int from, int to, double distance) { CheckRange("from", 0, Count - 1, from); CheckRange("to", 0, Count - 1, to); if (from == to) { this[from] = distance; return; } if (from >= InternalCount && distance.Equals(defaultDistance)) { return; } int count = to - from + 1; EnsureTreeCount(from); int n = RemoveHelper(from, count); DistanceLineCounterEntry rb = CreateTreeTableEntry(distance, count); rbTree.Insert(n, rb); Merge(rb, true); }
DistanceLineCounterEntry CreateTreeTableEntry(double distance, int count) { var entry = new DistanceLineCounterEntry { Value = new DistanceLineCounterSource(distance, count), Tree = rbTree }; return(entry); }
void EnsureTreeCount(int count) { int treeCount = InternalCount; int insert = count - treeCount; if (insert > 0) { DistanceLineCounterEntry entry = CreateTreeTableEntry(DefaultDistance, insert); rbTree.Add(entry); //entry.InvalidateCounterBottomUp(true); } }
/// <summary> /// Initializes a new instance of the <see cref="NestedDistanceCounterCollectionSource"/> class. /// </summary> /// <param name="parentDistances">The parent distances.</param> /// <param name="nestedDistances">The nested distances.</param> /// <param name="entry">The entry.</param> public NestedDistanceCounterCollectionSource(IDistanceCounterCollection parentDistances, IDistanceCounterCollection nestedDistances, DistanceLineCounterEntry entry) : base(0, 1) { this.parentDistances = parentDistances; this.nestedDistances = nestedDistances; this.entry = entry; if (nestedDistances != null) { nestedDistances.ConnectWithParent(this); } }
/// <summary> /// Gets or sets the distance for an entity. /// </summary> /// <param name="index">The index for the entity</param> /// <returns></returns> public double this[int index] { get { CheckRange("index", 0, Count - 1, index); if (index >= InternalCount) { return(DefaultDistance); } LineIndexEntryAt e = InitDistanceLine(index, false); return(e.rbValue.SingleLineDistance); } set { CheckRange("index", 0, Count - 1, index); if (value < 0) { throw new ArgumentOutOfRangeException("value must not be negative."); } if (!value.Equals(this[index])) { if (index >= InternalCount) { EnsureTreeCount(Count); } DistanceLineCounterEntry entry = Split(index); Split(index + 1); entry.Value.SingleLineDistance = value; entry.InvalidateCounterBottomUp(true); } } }
public DistanceLineCounterEntry GetPreviousNotEmptyCounterEntry(DistanceLineCounterEntry current, int cookie) { return((DistanceLineCounterEntry)base.GetPreviousNotEmptyCounterEntry(current, cookie)); }
public void Remove(DistanceLineCounterEntry value) { base.Remove(value); }
public void Insert(int index, DistanceLineCounterEntry value) { base.Insert(index, value); }
public bool Contains(DistanceLineCounterEntry value) { return(base.Contains(value)); }
public int IndexOf(DistanceLineCounterEntry value) { return(base.IndexOf(value)); }
public int Add(DistanceLineCounterEntry value) { return(base.Add(value)); }
public DistanceLineCounterEntry GetNextEntry(DistanceLineCounterEntry current) { return((DistanceLineCounterEntry)base.GetNextEntry(current)); }
public DistanceLineCounterEntry GetPreviousVisibleEntry(DistanceLineCounterEntry current) { return((DistanceLineCounterEntry)base.GetPreviousVisibleEntry(current)); }