private void ProcessChanges(RequestIndex index) { // When the UI thread acquires the lock, it should update the front // buffer only if there has been changes. Otherwise, it would block // the UI for too long on each update. _isBackBufferDirty = index.Modifications.Count > 0 || index.Insertions.Count > 0; // apply changes to the data in the back buffer if (index.Modifications.Count > 0) { var groupHead = 0; for (var i = 0; i < _backBuffer.Count; ++i) { Trace.Assert(groupHead <= i, $"{nameof(groupHead)} <= {nameof(i)}"); var group = _backBuffer[i]; // update items in the group var head = 0; for (var j = 0; j < group.Items.Count; ++j) { Trace.Assert(head <= j, $"{nameof(head)} <= {nameof(j)}"); var item = group.Items[j]; if (!index.Modifications.TryGetValue(item.FullPath, out var req)) { // this item has not changed group.Items[head] = item; ++head; } else if (req is RemoveRequest) { _removed.Add(item); } else if (req is MoveRequest moveReq) { item.Data.ChangePath(moveReq.NewPath); var key = Query.GetGroup(item.Data); var list = GetOrAddList(key, index.Insertions); list.Add(item); } else if (req is ModifyRequest modReq) { // replace the item but do not throw away its thumbnail item = new EntityView(modReq.Value, item.Thumbnail); var key = Query.GetGroup(item.Data); var list = GetOrAddList(key, index.Insertions); list.Add(item); } } group.Items.RemoveRange(head, group.Items.Count - head); // remove the group if it is empty if (group.Items.Count > 0) { _backBuffer[groupHead] = group; ++groupHead; } } _backBuffer.RemoveRange(groupHead, _backBuffer.Count - groupHead); } // add new groups if (index.Insertions.Count > 0) { // merge items of existing groups for (var i = 0; i < _backBuffer.Count; ++i) { var group = _backBuffer[i]; if (!index.Insertions.TryGetValue(group.Key, out var list)) { continue; } list.Sort(Comparer); group.Items = group.Items.Merge(list, Comparer); index.Insertions.Remove(group.Key); } // add brand new groups var addedGroups = index.Insertions .Select(pair => new Group(pair.Key) { Items = pair.Value }) .ToList(); addedGroups.Sort(); foreach (var view in addedGroups) { view.Items.Sort(Comparer); } _backBuffer = _backBuffer.Merge(addedGroups, Comparer <Group> .Default); } }
/// <inheritdoc /> /// <summary> /// Create a new drop event arguments. /// </summary> /// <param name="entity">Entity on which the data was dropped. This can be null.</param> /// <param name="allowedEffect">Allowed effect of the drop operation.</param> /// <param name="data">Data dropped on the entity</param> /// <exception cref="ArgumentNullException"><paramref name="data"/> is null</exception> public DropEventArgs(EntityView entity, DragDropEffects allowedEffect, IDataObject data) { Entity = entity; AllowedEffect = allowedEffect; Data = data ?? throw new ArgumentNullException(nameof(data)); }
public AddRequest(EntityView value) { Value = value ?? throw new ArgumentNullException(nameof(value)); }
public EntityEventArgs(EntityView entity) { Entity = entity ?? throw new ArgumentNullException(nameof(entity)); }
public EntityView FindLastItemBelow(EntityView currentItem) { return(_view.FindLastItemBelow(currentItem)); }
public EntityView FindFirstItemAbove(EntityView currentItem) { return(_view.FindFirstItemAbove(currentItem)); }
public EntityView FindItem(EntityView currentItem, Point delta) { return(_view.FindItem(currentItem, delta)); }
public void EnsureItemVisible(EntityView item) { _view.EnsureItemVisible(item); }